@@ -12,6 +12,7 @@ use syntax::ast;
12
12
use syntax_pos:: Span ;
13
13
use ty:: { self , Ty } ;
14
14
15
+ use std:: cmp;
15
16
use std:: marker:: PhantomData ;
16
17
use std:: u32;
17
18
use rustc_data_structures:: fx:: FxHashMap ;
@@ -81,17 +82,33 @@ struct TypeVariableData {
81
82
#[ derive( Copy , Clone , Debug ) ]
82
83
pub enum TypeVariableValue < ' tcx > {
83
84
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 ) ,
85
92
}
86
93
87
94
impl < ' tcx > TypeVariableValue < ' tcx > {
95
+ /// If this value is known, returns the type it is known to be.
96
+ /// Otherwise, `None`.
88
97
pub fn known ( & self ) -> Option < Ty < ' tcx > > {
89
98
match * self {
90
99
TypeVariableValue :: Unknown { .. } => None ,
91
100
TypeVariableValue :: Known { value } => Some ( value) ,
92
101
}
93
102
}
94
103
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
+
95
112
pub fn is_unknown ( & self ) -> bool {
96
113
match * self {
97
114
TypeVariableValue :: Unknown { .. } => true ,
@@ -178,10 +195,11 @@ impl<'tcx> TypeVariableTable<'tcx> {
178
195
/// The code in this module doesn't care, but it can be useful
179
196
/// for improving error messages.
180
197
pub fn new_var ( & mut self ,
198
+ universe : ty:: UniverseIndex ,
181
199
diverging : bool ,
182
200
origin : TypeVariableOrigin )
183
201
-> 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 } ) ;
185
203
186
204
let sub_key = self . sub_relations . new_key ( ( ) ) ;
187
205
assert_eq ! ( eq_key. vid, sub_key) ;
@@ -388,8 +406,12 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> {
388
406
( & TypeVariableValue :: Known { .. } , & TypeVariableValue :: Unknown { .. } ) => Ok ( * value1) ,
389
407
( & TypeVariableValue :: Unknown { .. } , & TypeVariableValue :: Known { .. } ) => Ok ( * value2) ,
390
408
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
+ }
393
415
}
394
416
}
395
417
}
0 commit comments