@@ -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