3333
3434use infer:: { InferCtxt , RegionVariableOrigin , TypeVariableOrigin } ;
3535use rustc_data_structures:: indexed_vec:: IndexVec ;
36- use smallvec:: SmallVec ;
3736use rustc_data_structures:: sync:: Lrc ;
3837use serialize:: UseSpecializedDecodable ;
38+ use smallvec:: SmallVec ;
3939use std:: ops:: Index ;
4040use syntax:: source_map:: Span ;
4141use ty:: fold:: TypeFoldable ;
4242use ty:: subst:: Kind ;
43- use ty:: { self , BoundTyIndex , Lift , Region , List , TyCtxt } ;
43+ use ty:: { self , BoundTyIndex , Lift , List , Region , TyCtxt } ;
4444
4545mod canonicalizer;
4646
@@ -80,13 +80,31 @@ pub struct CanonicalVarValues<'tcx> {
8080/// various parts of it with canonical variables. This struct stores
8181/// those replaced bits to remember for when we process the query
8282/// result.
83- #[ derive( Clone , Debug , Default , PartialEq , Eq , Hash , RustcDecodable , RustcEncodable ) ]
83+ #[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcDecodable , RustcEncodable ) ]
8484pub struct OriginalQueryValues < ' tcx > {
85+ /// Map from the universes that appear in the query to the
86+ /// universes in the caller context. For the time being, we only
87+ /// ever put ROOT values into the query, so this map is very
88+ /// simple.
89+ pub universe_map : SmallVec < [ ty:: UniverseIndex ; 4 ] > ,
90+
8591 /// This is equivalent to `CanonicalVarValues`, but using a
8692 /// `SmallVec` yields a significant performance win.
8793 pub var_values : SmallVec < [ Kind < ' tcx > ; 8 ] > ,
8894}
8995
96+ impl Default for OriginalQueryValues < ' tcx > {
97+ fn default ( ) -> Self {
98+ let mut universe_map = SmallVec :: default ( ) ;
99+ universe_map. push ( ty:: UniverseIndex :: ROOT ) ;
100+
101+ Self {
102+ universe_map,
103+ var_values : SmallVec :: default ( ) ,
104+ }
105+ }
106+ }
107+
90108/// Information about a canonical variable that is included with the
91109/// canonical value. This is sufficient information for code to create
92110/// a copy of the canonical value in some other inference context,
@@ -97,9 +115,17 @@ pub struct CanonicalVarInfo {
97115}
98116
99117impl CanonicalVarInfo {
100- pub fn universe ( self ) -> ty:: UniverseIndex {
118+ pub fn universe ( & self ) -> ty:: UniverseIndex {
101119 self . kind . universe ( )
102120 }
121+
122+ pub fn is_existential ( & self ) -> bool {
123+ match self . kind {
124+ CanonicalVarKind :: Ty ( _) => true ,
125+ CanonicalVarKind :: Region ( _) => true ,
126+ CanonicalVarKind :: PlaceholderRegion ( ..) => false ,
127+ }
128+ }
103129}
104130
105131/// Describes the "kind" of the canonical variable. This is a "kind"
@@ -112,8 +138,12 @@ pub enum CanonicalVarKind {
112138
113139 /// Region variable `'?R`.
114140 Region ( ty:: UniverseIndex ) ,
115- }
116141
142+ /// A "placeholder" that represents "any region". Created when you
143+ /// are solving a goal like `for<'a> T: Foo<'a>` to represent the
144+ /// bound region `'a`.
145+ PlaceholderRegion ( ty:: Placeholder ) ,
146+ }
117147
118148impl CanonicalVarKind {
119149 pub fn universe ( self ) -> ty:: UniverseIndex {
@@ -125,6 +155,7 @@ impl CanonicalVarKind {
125155
126156 // Region variables can be created in sub-universes.
127157 CanonicalVarKind :: Region ( ui) => ui,
158+ CanonicalVarKind :: PlaceholderRegion ( placeholder) => placeholder. universe ,
128159 }
129160 }
130161}
@@ -242,8 +273,16 @@ impl<'gcx, V> Canonical<'gcx, V> {
242273 /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty));
243274 /// ```
244275 pub fn unchecked_map < W > ( self , map_op : impl FnOnce ( V ) -> W ) -> Canonical < ' gcx , W > {
245- let Canonical { max_universe, variables, value } = self ;
246- Canonical { max_universe, variables, value : map_op ( value) }
276+ let Canonical {
277+ max_universe,
278+ variables,
279+ value,
280+ } = self ;
281+ Canonical {
282+ max_universe,
283+ variables,
284+ value : map_op ( value) ,
285+ }
247286 }
248287}
249288
@@ -271,35 +310,50 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
271310 where
272311 T : TypeFoldable < ' tcx > ,
273312 {
313+ // For each universe that is referred to in the incoming
314+ // query, create a universe in our local inference context. In
315+ // practice, as of this writing, all queries have no universes
316+ // in them, so this code has no effect, but it is looking
317+ // forward to the day when we *do* want to carry universes
318+ // through into queries.
319+ let universes: IndexVec < ty:: UniverseIndex , _ > = std:: iter:: once ( ty:: UniverseIndex :: ROOT )
320+ . chain ( ( 0 ..canonical. max_universe . as_u32 ( ) ) . map ( |_| self . create_next_universe ( ) ) )
321+ . collect ( ) ;
322+
274323 let canonical_inference_vars =
275- self . fresh_inference_vars_for_canonical_vars ( span, canonical. variables ) ;
324+ self . instantiate_canonical_vars ( span, canonical. variables , |ui| universes [ ui ] ) ;
276325 let result = canonical. substitute ( self . tcx , & canonical_inference_vars) ;
277326 ( result, canonical_inference_vars)
278327 }
279328
280329 /// Given the "infos" about the canonical variables from some
281- /// canonical, creates fresh inference variables with the same
282- /// characteristics. You can then use `substitute` to instantiate
283- /// the canonical variable with these inference variables.
284- fn fresh_inference_vars_for_canonical_vars (
330+ /// canonical, creates fresh variables with the same
331+ /// characteristics (see `instantiate_canonical_var` for
332+ /// details). You can then use `substitute` to instantiate the
333+ /// canonical variable with these inference variables.
334+ fn instantiate_canonical_vars (
285335 & self ,
286336 span : Span ,
287337 variables : & List < CanonicalVarInfo > ,
338+ universe_map : impl Fn ( ty:: UniverseIndex ) -> ty:: UniverseIndex ,
288339 ) -> CanonicalVarValues < ' tcx > {
289340 let var_values: IndexVec < BoundTyIndex , Kind < ' tcx > > = variables
290341 . iter ( )
291- . map ( |info| self . fresh_inference_var_for_canonical_var ( span, * info) )
342+ . map ( |info| self . instantiate_canonical_var ( span, * info, & universe_map ) )
292343 . collect ( ) ;
293344
294345 CanonicalVarValues { var_values }
295346 }
296347
297348 /// Given the "info" about a canonical variable, creates a fresh
298- /// inference variable with the same characteristics.
299- fn fresh_inference_var_for_canonical_var (
349+ /// variable for it. If this is an existentially quantified
350+ /// variable, then you'll get a new inference variable; if it is a
351+ /// universally quantified variable, you get a placeholder.
352+ fn instantiate_canonical_var (
300353 & self ,
301354 span : Span ,
302355 cv_info : CanonicalVarInfo ,
356+ universe_map : impl Fn ( ty:: UniverseIndex ) -> ty:: UniverseIndex ,
303357 ) -> Kind < ' tcx > {
304358 match cv_info. kind {
305359 CanonicalVarKind :: Ty ( ty_kind) => {
@@ -315,9 +369,21 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
315369 ty. into ( )
316370 }
317371
318- CanonicalVarKind :: Region ( ui) => self
319- . next_region_var_in_universe ( RegionVariableOrigin :: MiscVariable ( span) , ui)
320- . into ( ) ,
372+ CanonicalVarKind :: Region ( ui) => self . next_region_var_in_universe (
373+ RegionVariableOrigin :: MiscVariable ( span) ,
374+ universe_map ( ui) ,
375+ ) . into ( ) ,
376+
377+ CanonicalVarKind :: PlaceholderRegion ( ty:: Placeholder { universe, name } ) => {
378+ let universe_mapped = universe_map ( universe) ;
379+ let placeholder_mapped = ty:: Placeholder {
380+ universe : universe_mapped,
381+ name,
382+ } ;
383+ self . tcx
384+ . mk_region ( ty:: RePlaceholder ( placeholder_mapped) )
385+ . into ( )
386+ }
321387 }
322388 }
323389}
0 commit comments