@@ -802,6 +802,128 @@ impl<'tcx> ctxt<'tcx> {
802
802
pub fn free_region_map ( & self , id : NodeId ) -> FreeRegionMap {
803
803
self . free_region_maps . borrow ( ) [ & id] . clone ( )
804
804
}
805
+
806
+ pub fn lift < T : Lift < ' tcx > > ( & self , value : & T ) -> Option < T :: Lifted > {
807
+ value. lift_to_tcx ( self )
808
+ }
809
+ }
810
+
811
+ /// A trait implemented for all X<'a> types which can be safely and
812
+ /// efficiently converted to X<'tcx> as long as they are part of the
813
+ /// provided ty::ctxt<'tcx>.
814
+ /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
815
+ /// by looking them up in their respective interners.
816
+ pub trait Lift < ' tcx > {
817
+ type Lifted ;
818
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Self :: Lifted > ;
819
+ }
820
+
821
+ impl < ' tcx , A : Lift < ' tcx > , B : Lift < ' tcx > > Lift < ' tcx > for ( A , B ) {
822
+ type Lifted = ( A :: Lifted , B :: Lifted ) ;
823
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Self :: Lifted > {
824
+ tcx. lift ( & self . 0 ) . and_then ( |a| tcx. lift ( & self . 1 ) . map ( |b| ( a, b) ) )
825
+ }
826
+ }
827
+
828
+ impl < ' tcx , T : Lift < ' tcx > > Lift < ' tcx > for Vec < T > {
829
+ type Lifted = Vec < T :: Lifted > ;
830
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Self :: Lifted > {
831
+ let mut result = Vec :: with_capacity ( self . len ( ) ) ;
832
+ for x in self {
833
+ if let Some ( value) = tcx. lift ( x) {
834
+ result. push ( value) ;
835
+ } else {
836
+ return None ;
837
+ }
838
+ }
839
+ Some ( result)
840
+ }
841
+ }
842
+
843
+ impl < ' tcx > Lift < ' tcx > for Region {
844
+ type Lifted = Self ;
845
+ fn lift_to_tcx ( & self , _: & ctxt < ' tcx > ) -> Option < Region > {
846
+ Some ( * self )
847
+ }
848
+ }
849
+
850
+ impl < ' a , ' tcx > Lift < ' tcx > for Ty < ' a > {
851
+ type Lifted = Ty < ' tcx > ;
852
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Ty < ' tcx > > {
853
+ if let Some ( & ty) = tcx. interner . borrow ( ) . get ( & self . sty ) {
854
+ if * self as * const _ == ty as * const _ {
855
+ return Some ( ty) ;
856
+ }
857
+ }
858
+ None
859
+ }
860
+ }
861
+
862
+ impl < ' a , ' tcx > Lift < ' tcx > for & ' a Substs < ' a > {
863
+ type Lifted = & ' tcx Substs < ' tcx > ;
864
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < & ' tcx Substs < ' tcx > > {
865
+ if let Some ( & substs) = tcx. substs_interner . borrow ( ) . get ( * self ) {
866
+ if * self as * const _ == substs as * const _ {
867
+ return Some ( substs) ;
868
+ }
869
+ }
870
+ None
871
+ }
872
+ }
873
+
874
+ impl < ' a , ' tcx > Lift < ' tcx > for TraitRef < ' a > {
875
+ type Lifted = TraitRef < ' tcx > ;
876
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < TraitRef < ' tcx > > {
877
+ tcx. lift ( & self . substs ) . map ( |substs| TraitRef {
878
+ def_id : self . def_id ,
879
+ substs : substs
880
+ } )
881
+ }
882
+ }
883
+
884
+ impl < ' a , ' tcx > Lift < ' tcx > for TraitPredicate < ' a > {
885
+ type Lifted = TraitPredicate < ' tcx > ;
886
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < TraitPredicate < ' tcx > > {
887
+ tcx. lift ( & self . trait_ref ) . map ( |trait_ref| TraitPredicate {
888
+ trait_ref : trait_ref
889
+ } )
890
+ }
891
+ }
892
+
893
+ impl < ' a , ' tcx > Lift < ' tcx > for EquatePredicate < ' a > {
894
+ type Lifted = EquatePredicate < ' tcx > ;
895
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < EquatePredicate < ' tcx > > {
896
+ tcx. lift ( & ( self . 0 , self . 1 ) ) . map ( |( a, b) | EquatePredicate ( a, b) )
897
+ }
898
+ }
899
+
900
+ impl < ' tcx , A : Copy +Lift < ' tcx > , B : Copy +Lift < ' tcx > > Lift < ' tcx > for OutlivesPredicate < A , B > {
901
+ type Lifted = OutlivesPredicate < A :: Lifted , B :: Lifted > ;
902
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Self :: Lifted > {
903
+ tcx. lift ( & ( self . 0 , self . 1 ) ) . map ( |( a, b) | OutlivesPredicate ( a, b) )
904
+ }
905
+ }
906
+
907
+ impl < ' a , ' tcx > Lift < ' tcx > for ProjectionPredicate < ' a > {
908
+ type Lifted = ProjectionPredicate < ' tcx > ;
909
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < ProjectionPredicate < ' tcx > > {
910
+ tcx. lift ( & ( self . projection_ty . trait_ref , self . ty ) ) . map ( |( trait_ref, ty) | {
911
+ ProjectionPredicate {
912
+ projection_ty : ProjectionTy {
913
+ trait_ref : trait_ref,
914
+ item_name : self . projection_ty . item_name
915
+ } ,
916
+ ty : ty
917
+ }
918
+ } )
919
+ }
920
+ }
921
+
922
+ impl < ' tcx , T : Lift < ' tcx > > Lift < ' tcx > for Binder < T > {
923
+ type Lifted = Binder < T :: Lifted > ;
924
+ fn lift_to_tcx ( & self , tcx : & ctxt < ' tcx > ) -> Option < Self :: Lifted > {
925
+ tcx. lift ( & self . 0 ) . map ( |x| Binder ( x) )
926
+ }
805
927
}
806
928
807
929
pub mod tls {
0 commit comments