Skip to content

Commit 0d37587

Browse files
Add a note and one more fast path
1 parent 904458f commit 0d37587

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,22 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
534534
return Err(TypeError::Mismatch);
535535
}
536536

537+
// This is an optimization because coercion is one of the most common
538+
// operations that we do in typeck, since it happens at every assignment
539+
// and call arg (among other positions).
540+
//
537541
// These targets are known to never be RHS in `LHS: CoerceUnsized<RHS>`.
538542
// That's because these are built-in types for which a core-provided impl
539543
// doesn't exist, and for which a user-written impl is invalid.
544+
//
545+
// This is technically incomplete when users write impossible bounds like
546+
// `where T: CoerceUnsized<usize>`, for example, but that trait is unstable
547+
// and coercion is allowed to be incomplete. The only case where this matters
548+
// is impossible bounds.
549+
//
550+
// Note that some of these types implement `LHS: Unsize<RHS>`, but they
551+
// do not implement *`CoerceUnsized`* which is the root obligation of the
552+
// check below.
540553
match target.kind() {
541554
ty::Bool
542555
| ty::Char
@@ -558,6 +571,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
558571
| ty::Tuple(_) => return Err(TypeError::Mismatch),
559572
_ => {}
560573
}
574+
// Additionally, we ignore `&str -> &str` coercions, which happen very
575+
// commonly since strings are one of the most used argument types in Rust,
576+
// we do coercions when type checking call expressions.
577+
if let ty::Ref(_, source_pointee, ty::Mutability::Not) = *source.kind()
578+
&& source_pointee.is_str()
579+
&& let ty::Ref(_, target_pointee, ty::Mutability::Not) = *target.kind()
580+
&& target_pointee.is_str()
581+
{
582+
return Err(TypeError::Mismatch);
583+
}
561584

562585
let traits =
563586
(self.tcx.lang_items().unsize_trait(), self.tcx.lang_items().coerce_unsized_trait());

0 commit comments

Comments
 (0)