File tree 5 files changed +67
-0
lines changed
rustc_trait_selection/src/solve
5 files changed +67
-0
lines changed Original file line number Diff line number Diff line change @@ -83,6 +83,9 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
83
83
| TypeFlags :: HAS_CT_PLACEHOLDER ,
84
84
)
85
85
}
86
+ fn has_non_region_placeholders ( & self ) -> bool {
87
+ self . has_type_flags ( TypeFlags :: HAS_TY_PLACEHOLDER | TypeFlags :: HAS_CT_PLACEHOLDER )
88
+ }
86
89
fn needs_subst ( & self ) -> bool {
87
90
self . has_type_flags ( TypeFlags :: NEEDS_SUBST )
88
91
}
Original file line number Diff line number Diff line change @@ -225,6 +225,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
225
225
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
226
226
goal : Goal < ' tcx , Self > ,
227
227
) -> QueryResult < ' tcx > ;
228
+
229
+ fn consider_builtin_transmute_candidate (
230
+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
231
+ goal : Goal < ' tcx , Self > ,
232
+ ) -> QueryResult < ' tcx > ;
228
233
}
229
234
230
235
impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
@@ -373,6 +378,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
373
378
G :: consider_builtin_discriminant_kind_candidate ( self , goal)
374
379
} else if lang_items. destruct_trait ( ) == Some ( trait_def_id) {
375
380
G :: consider_builtin_destruct_candidate ( self , goal)
381
+ } else if lang_items. transmute_trait ( ) == Some ( trait_def_id) {
382
+ G :: consider_builtin_transmute_candidate ( self , goal)
376
383
} else {
377
384
Err ( NoSolution )
378
385
} ;
Original file line number Diff line number Diff line change @@ -639,4 +639,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
639
639
crate :: traits:: wf:: unnormalized_obligations ( self . infcx , param_env, arg)
640
640
. map ( |obligations| obligations. into_iter ( ) . map ( |obligation| obligation. into ( ) ) )
641
641
}
642
+
643
+ pub ( super ) fn is_transmutable (
644
+ & self ,
645
+ src_and_dst : rustc_transmute:: Types < ' tcx > ,
646
+ scope : Ty < ' tcx > ,
647
+ assume : rustc_transmute:: Assume ,
648
+ ) -> Result < Certainty , NoSolution > {
649
+ // FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
650
+ match rustc_transmute:: TransmuteTypeEnv :: new ( self . infcx ) . is_transmutable (
651
+ ObligationCause :: dummy ( ) ,
652
+ ty:: Binder :: dummy ( src_and_dst) ,
653
+ scope,
654
+ assume,
655
+ ) {
656
+ rustc_transmute:: Answer :: Yes => Ok ( Certainty :: Yes ) ,
657
+ rustc_transmute:: Answer :: No ( _)
658
+ | rustc_transmute:: Answer :: IfTransmutable { .. }
659
+ | rustc_transmute:: Answer :: IfAll ( _)
660
+ | rustc_transmute:: Answer :: IfAny ( _) => Err ( NoSolution ) ,
661
+ }
662
+ }
642
663
}
Original file line number Diff line number Diff line change @@ -524,6 +524,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
524
524
) -> QueryResult < ' tcx > {
525
525
bug ! ( "`Destruct` does not have an associated type: {:?}" , goal) ;
526
526
}
527
+
528
+ fn consider_builtin_transmute_candidate (
529
+ _ecx : & mut EvalCtxt < ' _ , ' tcx > ,
530
+ goal : Goal < ' tcx , Self > ,
531
+ ) -> QueryResult < ' tcx > {
532
+ bug ! ( "`BikeshedIntrinsicFrom` does not have an associated type: {:?}" , goal)
533
+ }
527
534
}
528
535
529
536
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
Original file line number Diff line number Diff line change @@ -556,6 +556,35 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
556
556
Err ( NoSolution )
557
557
}
558
558
}
559
+
560
+ fn consider_builtin_transmute_candidate (
561
+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
562
+ goal : Goal < ' tcx , Self > ,
563
+ ) -> QueryResult < ' tcx > {
564
+ // `rustc_transmute` does not have support for type or const params
565
+ if goal. has_non_region_placeholders ( ) {
566
+ return Err ( NoSolution ) ;
567
+ }
568
+
569
+ // Erase regions because we compute layouts in `rustc_transmute`,
570
+ // which will ICE for region vars.
571
+ let substs = ecx. tcx ( ) . erase_regions ( goal. predicate . trait_ref . substs ) ;
572
+
573
+ let Some ( assume) = rustc_transmute:: Assume :: from_const (
574
+ ecx. tcx ( ) ,
575
+ goal. param_env ,
576
+ substs. const_at ( 3 ) ,
577
+ ) else {
578
+ return Err ( NoSolution ) ;
579
+ } ;
580
+
581
+ let certainty = ecx. is_transmutable (
582
+ rustc_transmute:: Types { dst : substs. type_at ( 0 ) , src : substs. type_at ( 1 ) } ,
583
+ substs. type_at ( 2 ) ,
584
+ assume,
585
+ ) ?;
586
+ ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
587
+ }
559
588
}
560
589
561
590
impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
You can’t perform that action at this time.
0 commit comments