@@ -531,6 +531,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
531
531
// These targets are known to never be RHS in `LHS: CoerceUnsized<RHS>`.
532
532
// That's because these are built-in types for which a core-provided impl
533
533
// 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.
534
539
match target. kind ( ) {
535
540
ty:: Bool
536
541
| ty:: Char
@@ -552,6 +557,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
552
557
| ty:: Tuple ( _) => return Err ( TypeError :: Mismatch ) ,
553
558
_ => { }
554
559
}
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
+ }
555
570
556
571
let traits =
557
572
( self . tcx . lang_items ( ) . unsize_trait ( ) , self . tcx . lang_items ( ) . coerce_unsized_trait ( ) ) ;
0 commit comments