@@ -490,53 +490,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
490490 ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
491491 }
492492
493- fn consider_unsize_to_dyn_candidate (
494- ecx : & mut EvalCtxt < ' _ , ' tcx > ,
495- goal : Goal < ' tcx , Self > ,
496- ) -> QueryResult < ' tcx > {
497- ecx. probe ( |_| ProbeKind :: UnsizeAssembly ) . enter ( |ecx| {
498- let a_ty = goal. predicate . self_ty ( ) ;
499- // We need to normalize the b_ty since it's destructured as a `dyn Trait`.
500- let Some ( b_ty) =
501- ecx. try_normalize_ty ( goal. param_env , goal. predicate . trait_ref . args . type_at ( 1 ) )
502- else {
503- return ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: OVERFLOW ) ;
504- } ;
505-
506- let ty:: Dynamic ( b_data, b_region, ty:: Dyn ) = * b_ty. kind ( ) else {
507- return Err ( NoSolution ) ;
508- } ;
509-
510- let tcx = ecx. tcx ( ) ;
511-
512- // Can only unsize to an object-safe trait.
513- if b_data. principal_def_id ( ) . is_some_and ( |def_id| !tcx. check_is_object_safe ( def_id) ) {
514- return Err ( NoSolution ) ;
515- }
516-
517- // Check that the type implements all of the predicates of the trait object.
518- // (i.e. the principal, all of the associated types match, and any auto traits)
519- ecx. add_goals (
520- GoalSource :: ImplWhereBound ,
521- b_data. iter ( ) . map ( |pred| goal. with ( tcx, pred. with_self_ty ( tcx, a_ty) ) ) ,
522- ) ;
523-
524- // The type must be `Sized` to be unsized.
525- if let Some ( sized_def_id) = tcx. lang_items ( ) . sized_trait ( ) {
526- ecx. add_goal (
527- GoalSource :: ImplWhereBound ,
528- goal. with ( tcx, ty:: TraitRef :: new ( tcx, sized_def_id, [ a_ty] ) ) ,
529- ) ;
530- } else {
531- return Err ( NoSolution ) ;
532- }
533-
534- // The type must outlive the lifetime of the `dyn` we're unsizing into.
535- ecx. add_goal ( GoalSource :: Misc , goal. with ( tcx, ty:: OutlivesPredicate ( a_ty, b_region) ) ) ;
536- ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
537- } )
538- }
539-
540493 /// ```ignore (builtin impl example)
541494 /// trait Trait {
542495 /// fn foo(&self);
@@ -588,8 +541,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
588541 goal, a_data, a_region, b_data, b_region,
589542 ) ,
590543
591- // `T` -> `dyn Trait` unsizing is handled separately in `consider_unsize_to_dyn_candidate`
592- ( _, & ty:: Dynamic ( ..) ) => vec ! [ ] ,
544+ // `T` -> `dyn Trait` unsizing.
545+ ( _, & ty:: Dynamic ( b_region, b_data, ty:: Dyn ) ) => result_to_single (
546+ ecx. consider_builtin_unsize_to_dyn_candidate ( goal, b_region, b_data) ,
547+ BuiltinImplSource :: Misc ,
548+ ) ,
593549
594550 // `[T; N]` -> `[T]` unsizing
595551 ( & ty:: Array ( a_elem_ty, ..) , & ty:: Slice ( b_elem_ty) ) => result_to_single (
@@ -691,6 +647,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
691647 responses
692648 }
693649
650+ fn consider_builtin_unsize_to_dyn_candidate (
651+ & mut self ,
652+ goal : Goal < ' tcx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
653+ b_data : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
654+ b_region : ty:: Region < ' tcx > ,
655+ ) -> QueryResult < ' tcx > {
656+ let tcx = self . tcx ( ) ;
657+ let Goal { predicate : ( a_ty, _) , .. } = goal;
658+
659+ // Can only unsize to an object-safe trait.
660+ if b_data. principal_def_id ( ) . is_some_and ( |def_id| !tcx. check_is_object_safe ( def_id) ) {
661+ return Err ( NoSolution ) ;
662+ }
663+
664+ // Check that the type implements all of the predicates of the trait object.
665+ // (i.e. the principal, all of the associated types match, and any auto traits)
666+ self . add_goals (
667+ GoalSource :: ImplWhereBound ,
668+ b_data. iter ( ) . map ( |pred| goal. with ( tcx, pred. with_self_ty ( tcx, a_ty) ) ) ,
669+ ) ;
670+
671+ // The type must be `Sized` to be unsized.
672+ if let Some ( sized_def_id) = tcx. lang_items ( ) . sized_trait ( ) {
673+ self . add_goal (
674+ GoalSource :: ImplWhereBound ,
675+ goal. with ( tcx, ty:: TraitRef :: new ( tcx, sized_def_id, [ a_ty] ) ) ,
676+ ) ;
677+ } else {
678+ return Err ( NoSolution ) ;
679+ }
680+
681+ // The type must outlive the lifetime of the `dyn` we're unsizing into.
682+ self . add_goal ( GoalSource :: Misc , goal. with ( tcx, ty:: OutlivesPredicate ( a_ty, b_region) ) ) ;
683+ self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
684+ }
685+
694686 fn consider_builtin_upcast_to_principal (
695687 & mut self ,
696688 goal : Goal < ' tcx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
0 commit comments