@@ -515,11 +515,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
515
515
///
516
516
/// [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions)
517
517
#[ instrument( skip( self ) , level = "debug" ) ]
518
- fn coerce_unsized ( & self , mut source : Ty < ' tcx > , mut target : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
519
- source = self . shallow_resolve ( source) ;
520
- target = self . shallow_resolve ( target) ;
521
- debug ! ( ?source, ?target) ;
522
-
518
+ fn coerce_unsized ( & self , source : Ty < ' tcx > , target : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
523
519
// We don't apply any coercions incase either the source or target
524
520
// aren't sufficiently well known but tend to instead just equate
525
521
// them both.
@@ -532,6 +528,31 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
532
528
return Err ( TypeError :: Mismatch ) ;
533
529
}
534
530
531
+ // These targets are known to never be RHS in `LHS: CoerceUnsized<RHS>`.
532
+ // That's because these are built-in types for which a core-provided impl
533
+ // doesn't exist, and for which a user-written impl is invalid.
534
+ match target. kind ( ) {
535
+ ty:: Bool
536
+ | ty:: Char
537
+ | ty:: Int ( _)
538
+ | ty:: Uint ( _)
539
+ | ty:: Float ( _)
540
+ | ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
541
+ | ty:: Str
542
+ | ty:: Array ( _, _)
543
+ | ty:: Slice ( _)
544
+ | ty:: FnDef ( _, _)
545
+ | ty:: FnPtr ( _, _)
546
+ | ty:: Dynamic ( _, _, _)
547
+ | ty:: Closure ( _, _)
548
+ | ty:: CoroutineClosure ( _, _)
549
+ | ty:: Coroutine ( _, _)
550
+ | ty:: CoroutineWitness ( _, _)
551
+ | ty:: Never
552
+ | ty:: Tuple ( _) => return Err ( TypeError :: Mismatch ) ,
553
+ _ => { }
554
+ }
555
+
535
556
let traits =
536
557
( self . tcx . lang_items ( ) . unsize_trait ( ) , self . tcx . lang_items ( ) . coerce_unsized_trait ( ) ) ;
537
558
let ( Some ( unsize_did) , Some ( coerce_unsized_did) ) = traits else {
0 commit comments