22
33use rustc_data_structures:: fx:: FxHashSet ;
44use rustc_index:: bit_set:: BitSet ;
5- use rustc_infer:: infer:: TyCtxtInferExt ;
65use rustc_middle:: mir:: interpret:: Scalar ;
76use rustc_middle:: mir:: visit:: NonUseContext :: VarDebugInfo ;
87use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
@@ -12,8 +11,7 @@ use rustc_middle::mir::{
1211 ProjectionElem , RuntimePhase , Rvalue , SourceScope , Statement , StatementKind , Terminator ,
1312 TerminatorKind , UnOp , START_BLOCK ,
1413} ;
15- use rustc_middle:: ty:: fold:: BottomUpFolder ;
16- use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeFoldable , TypeVisitable } ;
14+ use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitable } ;
1715use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
1816use rustc_mir_dataflow:: storage:: always_storage_live_locals;
1917use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
@@ -70,44 +68,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
7068 }
7169}
7270
73- /// Returns whether the two types are equal up to lifetimes.
74- /// All lifetimes, including higher-ranked ones, get ignored for this comparison.
75- /// (This is unlike the `erasing_regions` methods, which keep higher-ranked lifetimes for soundness reasons.)
76- ///
77- /// The point of this function is to approximate "equal up to subtyping". However,
78- /// the approximation is incorrect as variance is ignored.
79- pub fn equal_up_to_regions < ' tcx > (
80- tcx : TyCtxt < ' tcx > ,
81- param_env : ParamEnv < ' tcx > ,
82- src : Ty < ' tcx > ,
83- dest : Ty < ' tcx > ,
84- ) -> bool {
85- // Fast path.
86- if src == dest {
87- return true ;
88- }
89-
90- // Normalize lifetimes away on both sides, then compare.
91- let normalize = |ty : Ty < ' tcx > | {
92- tcx. try_normalize_erasing_regions ( param_env, ty) . unwrap_or ( ty) . fold_with (
93- & mut BottomUpFolder {
94- tcx,
95- // FIXME: We erase all late-bound lifetimes, but this is not fully correct.
96- // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
97- // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`,
98- // since one may have an `impl SomeTrait for fn(&32)` and
99- // `impl SomeTrait for fn(&'static u32)` at the same time which
100- // specify distinct values for Assoc. (See also #56105)
101- lt_op : |_| tcx. lifetimes . re_erased ,
102- // Leave consts and types unchanged.
103- ct_op : |ct| ct,
104- ty_op : |ty| ty,
105- } ,
106- )
107- } ;
108- tcx. infer_ctxt ( ) . build ( ) . can_eq ( param_env, normalize ( src) , normalize ( dest) ) . is_ok ( )
109- }
110-
11171struct TypeChecker < ' a , ' tcx > {
11272 when : & ' a str ,
11373 body : & ' a Body < ' tcx > ,
@@ -183,22 +143,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
183143 return true ;
184144 }
185145
186- // Normalize projections and things like that.
187- // Type-changing assignments can happen when subtyping is used. While
188- // all normal lifetimes are erased, higher-ranked types with their
189- // late-bound lifetimes are still around and can lead to type
190- // differences. So we compare ignoring lifetimes.
191-
192- // First, try with reveal_all. This might not work in some cases, as the predicates
193- // can be cleared in reveal_all mode. We try the reveal first anyways as it is used
194- // by some other passes like inlining as well.
195- let param_env = self . param_env . with_reveal_all_normalized ( self . tcx ) ;
196- if equal_up_to_regions ( self . tcx , param_env, src, dest) {
197- return true ;
198- }
199-
200- // If this fails, we can try it without the reveal.
201- equal_up_to_regions ( self . tcx , self . param_env , src, dest)
146+ crate :: util:: is_subtype ( self . tcx , self . param_env , src, dest)
202147 }
203148}
204149
0 commit comments