@@ -490,53 +490,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
490
490
ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
491
491
}
492
492
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
-
540
493
/// ```ignore (builtin impl example)
541
494
/// trait Trait {
542
495
/// fn foo(&self);
@@ -588,8 +541,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
588
541
goal, a_data, a_region, b_data, b_region,
589
542
) ,
590
543
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
+ ) ,
593
549
594
550
// `[T; N]` -> `[T]` unsizing
595
551
( & ty:: Array ( a_elem_ty, ..) , & ty:: Slice ( b_elem_ty) ) => result_to_single (
@@ -691,6 +647,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
691
647
responses
692
648
}
693
649
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
+
694
686
fn consider_builtin_upcast_to_principal (
695
687
& mut self ,
696
688
goal : Goal < ' tcx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
0 commit comments