@@ -12,6 +12,7 @@ use syntax::ast;
1212use syntax_pos:: Span ;
1313use ty:: { self , Ty } ;
1414
15+ use std:: cmp;
1516use std:: marker:: PhantomData ;
1617use std:: u32;
1718use rustc_data_structures:: fx:: FxHashMap ;
@@ -81,17 +82,33 @@ struct TypeVariableData {
8182#[ derive( Copy , Clone , Debug ) ]
8283pub enum TypeVariableValue < ' tcx > {
8384 Known { value : Ty < ' tcx > } ,
84- Unknown ,
85+ Unknown { universe : ty:: UniverseIndex } ,
86+ }
87+
88+ #[ derive( Copy , Clone , Debug ) ]
89+ pub enum ProbeTyValue < ' tcx > {
90+ Ty ( Ty < ' tcx > ) ,
91+ Vid ( ty:: TyVid ) ,
8592}
8693
8794impl < ' tcx > TypeVariableValue < ' tcx > {
95+ /// If this value is known, returns the type it is known to be.
96+ /// Otherwise, `None`.
8897 pub fn known ( & self ) -> Option < Ty < ' tcx > > {
8998 match * self {
9099 TypeVariableValue :: Unknown { .. } => None ,
91100 TypeVariableValue :: Known { value } => Some ( value) ,
92101 }
93102 }
94103
104+ /// If this value is unknown, returns the universe, otherwise `None`.
105+ pub fn universe ( & self ) -> Option < ty:: UniverseIndex > {
106+ match * self {
107+ TypeVariableValue :: Unknown { universe } => Some ( universe) ,
108+ TypeVariableValue :: Known { .. } => None ,
109+ }
110+ }
111+
95112 pub fn is_unknown ( & self ) -> bool {
96113 match * self {
97114 TypeVariableValue :: Unknown { .. } => true ,
@@ -178,10 +195,11 @@ impl<'tcx> TypeVariableTable<'tcx> {
178195 /// The code in this module doesn't care, but it can be useful
179196 /// for improving error messages.
180197 pub fn new_var ( & mut self ,
198+ universe : ty:: UniverseIndex ,
181199 diverging : bool ,
182200 origin : TypeVariableOrigin )
183201 -> ty:: TyVid {
184- let eq_key = self . eq_relations . new_key ( TypeVariableValue :: Unknown ) ;
202+ let eq_key = self . eq_relations . new_key ( TypeVariableValue :: Unknown { universe } ) ;
185203
186204 let sub_key = self . sub_relations . new_key ( ( ) ) ;
187205 assert_eq ! ( eq_key. vid, sub_key) ;
@@ -388,8 +406,12 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> {
388406 ( & TypeVariableValue :: Known { .. } , & TypeVariableValue :: Unknown { .. } ) => Ok ( * value1) ,
389407 ( & TypeVariableValue :: Unknown { .. } , & TypeVariableValue :: Known { .. } ) => Ok ( * value2) ,
390408
391- // If both sides are *unknown*, it hardly matters, does it?
392- ( & TypeVariableValue :: Unknown , & TypeVariableValue :: Unknown ) => Ok ( * value1) ,
409+ // If both sides are unknown, we need to pick the most restrictive universe.
410+ ( & TypeVariableValue :: Unknown { universe : universe1 } ,
411+ & TypeVariableValue :: Unknown { universe : universe2 } ) => {
412+ let universe = cmp:: min ( universe1, universe2) ;
413+ Ok ( TypeVariableValue :: Unknown { universe } )
414+ }
393415 }
394416 }
395417}
0 commit comments