@@ -515,11 +515,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
515515 ///
516516 /// [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions)
517517 #[ 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 > {
523519 // We don't apply any coercions incase either the source or target
524520 // aren't sufficiently well known but tend to instead just equate
525521 // them both.
@@ -532,6 +528,31 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
532528 return Err ( TypeError :: Mismatch ) ;
533529 }
534530
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+
535556 let traits =
536557 ( self . tcx . lang_items ( ) . unsize_trait ( ) , self . tcx . lang_items ( ) . coerce_unsized_trait ( ) ) ;
537558 let ( Some ( unsize_did) , Some ( coerce_unsized_did) ) = traits else {
0 commit comments