Skip to content

Commit 3d115ac

Browse files
Add a note and one more fast path
1 parent 3dc5b4a commit 3d115ac

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
531531
// These targets are known to never be RHS in `LHS: CoerceUnsized<RHS>`.
532532
// That's because these are built-in types for which a core-provided impl
533533
// doesn't exist, and for which a user-written impl is invalid.
534+
//
535+
// This is technically incomplete when users write impossible bounds like
536+
// `where T: CoerceUnsized<usize>`, for example, but that trait is unstable
537+
// and coercion is allowed to be incomplete. The only case where this matters
538+
// is impossible bounds.
534539
match target.kind() {
535540
ty::Bool
536541
| ty::Char
@@ -552,6 +557,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
552557
| ty::Tuple(_) => return Err(TypeError::Mismatch),
553558
_ => {}
554559
}
560+
// Additionally, we ignore `&str -> &str` coercions, which happen very
561+
// commonly since strings are one of the most used argument types in Rust,
562+
// we do coercions when type checking call expressions.
563+
if let ty::Ref(_, source_pointee, ty::Mutability::Not) = *source.kind()
564+
&& source_pointee.is_str()
565+
&& let ty::Ref(_, target_pointee, ty::Mutability::Not) = *target.kind()
566+
&& target_pointee.is_str()
567+
{
568+
return Err(TypeError::Mismatch);
569+
}
555570

556571
let traits =
557572
(self.tcx.lang_items().unsize_trait(), self.tcx.lang_items().coerce_unsized_trait());

0 commit comments

Comments
 (0)