@@ -423,7 +423,55 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
423
423
ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
424
424
}
425
425
426
- fn consider_builtin_unsize_candidates (
426
+ fn consider_unsize_to_dyn_candidate (
427
+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
428
+ goal : Goal < ' tcx , Self > ,
429
+ ) -> QueryResult < ' tcx > {
430
+ ecx. probe ( |_| CandidateKind :: UnsizeAssembly ) . enter ( |ecx| {
431
+ let a_ty = goal. predicate . self_ty ( ) ;
432
+ // We need to normalize the b_ty since it's destructured as a `dyn Trait`.
433
+ let Some ( b_ty) =
434
+ ecx. try_normalize_ty ( goal. param_env , goal. predicate . trait_ref . args . type_at ( 1 ) ) ?
435
+ else {
436
+ return ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: OVERFLOW ) ;
437
+ } ;
438
+
439
+ let ty:: Dynamic ( b_data, b_region, ty:: Dyn ) = * b_ty. kind ( ) else {
440
+ return Err ( NoSolution ) ;
441
+ } ;
442
+
443
+ let tcx = ecx. tcx ( ) ;
444
+
445
+ // Can only unsize to an object-safe trait.
446
+ if b_data. principal_def_id ( ) . is_some_and ( |def_id| !tcx. check_is_object_safe ( def_id) ) {
447
+ return Err ( NoSolution ) ;
448
+ }
449
+
450
+ // Check that the type implements all of the predicates of the trait object.
451
+ // (i.e. the principal, all of the associated types match, and any auto traits)
452
+ ecx. add_goals ( b_data. iter ( ) . map ( |pred| goal. with ( tcx, pred. with_self_ty ( tcx, a_ty) ) ) ) ;
453
+
454
+ // The type must be `Sized` to be unsized.
455
+ if let Some ( sized_def_id) = tcx. lang_items ( ) . sized_trait ( ) {
456
+ ecx. add_goal ( goal. with ( tcx, ty:: TraitRef :: new ( tcx, sized_def_id, [ a_ty] ) ) ) ;
457
+ } else {
458
+ return Err ( NoSolution ) ;
459
+ }
460
+
461
+ // The type must outlive the lifetime of the `dyn` we're unsizing into.
462
+ ecx. add_goal ( goal. with ( tcx, ty:: OutlivesPredicate ( a_ty, b_region) ) ) ;
463
+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
464
+ } )
465
+ }
466
+
467
+ /// ```ignore (builtin impl example)
468
+ /// trait Trait {
469
+ /// fn foo(&self);
470
+ /// }
471
+ /// // results in the following builtin impl
472
+ /// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
473
+ /// ```
474
+ fn consider_structural_builtin_unsize_candidates (
427
475
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
428
476
goal : Goal < ' tcx , Self > ,
429
477
) -> Vec < ( CanonicalResponse < ' tcx > , BuiltinImplSource ) > {
@@ -468,11 +516,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
468
516
goal, a_data, a_region, b_data, b_region,
469
517
) ,
470
518
471
- // `T` -> `dyn Trait` unsizing
472
- ( _, & ty:: Dynamic ( b_data, b_region, ty:: Dyn ) ) => result_to_single (
473
- ecx. consider_builtin_unsize_to_dyn ( goal, b_data, b_region) ,
474
- BuiltinImplSource :: Misc ,
475
- ) ,
519
+ // `T` -> `dyn Trait` unsizing is handled separately in `consider_unsize_to_dyn_candidate`
520
+ ( _, & ty:: Dynamic ( ..) ) => vec ! [ ] ,
476
521
477
522
// `[T; N]` -> `[T]` unsizing
478
523
( & ty:: Array ( a_elem_ty, ..) , & ty:: Slice ( b_elem_ty) ) => result_to_single (
@@ -574,43 +619,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
574
619
responses
575
620
}
576
621
577
- /// ```ignore (builtin impl example)
578
- /// trait Trait {
579
- /// fn foo(&self);
580
- /// }
581
- /// // results in the following builtin impl
582
- /// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
583
- /// ```
584
- fn consider_builtin_unsize_to_dyn (
585
- & mut self ,
586
- goal : Goal < ' tcx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
587
- b_data : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
588
- b_region : ty:: Region < ' tcx > ,
589
- ) -> QueryResult < ' tcx > {
590
- let tcx = self . tcx ( ) ;
591
- let Goal { predicate : ( a_ty, _b_ty) , .. } = goal;
592
-
593
- // Can only unsize to an object-safe trait
594
- if b_data. principal_def_id ( ) . is_some_and ( |def_id| !tcx. check_is_object_safe ( def_id) ) {
595
- return Err ( NoSolution ) ;
596
- }
597
-
598
- // Check that the type implements all of the predicates of the trait object.
599
- // (i.e. the principal, all of the associated types match, and any auto traits)
600
- self . add_goals ( b_data. iter ( ) . map ( |pred| goal. with ( tcx, pred. with_self_ty ( tcx, a_ty) ) ) ) ;
601
-
602
- // The type must be `Sized` to be unsized.
603
- if let Some ( sized_def_id) = tcx. lang_items ( ) . sized_trait ( ) {
604
- self . add_goal ( goal. with ( tcx, ty:: TraitRef :: new ( tcx, sized_def_id, [ a_ty] ) ) ) ;
605
- } else {
606
- return Err ( NoSolution ) ;
607
- }
608
-
609
- // The type must outlive the lifetime of the `dyn` we're unsizing into.
610
- self . add_goal ( goal. with ( tcx, ty:: OutlivesPredicate ( a_ty, b_region) ) ) ;
611
- self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
612
- }
613
-
614
622
fn consider_builtin_upcast_to_principal (
615
623
& mut self ,
616
624
goal : Goal < ' tcx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
0 commit comments