File tree Expand file tree Collapse file tree 5 files changed +67
-0
lines changed
rustc_trait_selection/src/solve Expand file tree Collapse file tree 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>> {
8383 | TypeFlags :: HAS_CT_PLACEHOLDER ,
8484 )
8585 }
86+ fn has_non_region_placeholders ( & self ) -> bool {
87+ self . has_type_flags ( TypeFlags :: HAS_TY_PLACEHOLDER | TypeFlags :: HAS_CT_PLACEHOLDER )
88+ }
8689 fn needs_subst ( & self ) -> bool {
8790 self . has_type_flags ( TypeFlags :: NEEDS_SUBST )
8891 }
Original file line number Diff line number Diff line change @@ -225,6 +225,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
225225 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
226226 goal : Goal < ' tcx , Self > ,
227227 ) -> QueryResult < ' tcx > ;
228+
229+ fn consider_builtin_transmute_candidate (
230+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
231+ goal : Goal < ' tcx , Self > ,
232+ ) -> QueryResult < ' tcx > ;
228233}
229234
230235impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
@@ -373,6 +378,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
373378 G :: consider_builtin_discriminant_kind_candidate ( self , goal)
374379 } else if lang_items. destruct_trait ( ) == Some ( trait_def_id) {
375380 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)
376383 } else {
377384 Err ( NoSolution )
378385 } ;
Original file line number Diff line number Diff line change @@ -639,4 +639,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
639639 crate :: traits:: wf:: unnormalized_obligations ( self . infcx , param_env, arg)
640640 . map ( |obligations| obligations. into_iter ( ) . map ( |obligation| obligation. into ( ) ) )
641641 }
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+ }
642663}
Original file line number Diff line number Diff line change @@ -524,6 +524,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
524524 ) -> QueryResult < ' tcx > {
525525 bug ! ( "`Destruct` does not have an associated type: {:?}" , goal) ;
526526 }
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+ }
527534}
528535
529536/// 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> {
556556 Err ( NoSolution )
557557 }
558558 }
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+ }
559588}
560589
561590impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
You can’t perform that action at this time.
0 commit comments