1 use rustc_hir::def_id::DefId; 2 use rustc_middle::ty::{self, Ty, TyVid}; 3 use rustc_span::symbol::Symbol; 4 use rustc_span::Span; 5 6 use crate::infer::InferCtxtUndoLogs; 7 8 use rustc_data_structures::snapshot_vec as sv; 9 use rustc_data_structures::unify as ut; 10 use std::cmp; 11 use std::marker::PhantomData; 12 use std::ops::Range; 13 14 use rustc_data_structures::undo_log::{Rollback, UndoLogs}; 15 16 /// Represents a single undo-able action that affects a type inference variable. 17 #[derive(Clone)] 18 pub(crate) enum UndoLog<'tcx> { 19 EqRelation(sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>), 20 SubRelation(sv::UndoLog<ut::Delegate<ty::TyVid>>), 21 Values(sv::UndoLog<Delegate>), 22 } 23 24 /// Convert from a specific kind of undo to the more general UndoLog 25 impl<'tcx> From<sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>> for UndoLog<'tcx> { from(l: sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>) -> Self26 fn from(l: sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>) -> Self { 27 UndoLog::EqRelation(l) 28 } 29 } 30 31 /// Convert from a specific kind of undo to the more general UndoLog 32 impl<'tcx> From<sv::UndoLog<ut::Delegate<ty::TyVid>>> for UndoLog<'tcx> { from(l: sv::UndoLog<ut::Delegate<ty::TyVid>>) -> Self33 fn from(l: sv::UndoLog<ut::Delegate<ty::TyVid>>) -> Self { 34 UndoLog::SubRelation(l) 35 } 36 } 37 38 /// Convert from a specific kind of undo to the more general UndoLog 39 impl<'tcx> From<sv::UndoLog<Delegate>> for UndoLog<'tcx> { from(l: sv::UndoLog<Delegate>) -> Self40 fn from(l: sv::UndoLog<Delegate>) -> Self { 41 UndoLog::Values(l) 42 } 43 } 44 45 /// Convert from a specific kind of undo to the more general UndoLog 46 impl<'tcx> From<Instantiate> for UndoLog<'tcx> { from(l: Instantiate) -> Self47 fn from(l: Instantiate) -> Self { 48 UndoLog::Values(sv::UndoLog::Other(l)) 49 } 50 } 51 52 impl<'tcx> Rollback<UndoLog<'tcx>> for TypeVariableStorage<'tcx> { reverse(&mut self, undo: UndoLog<'tcx>)53 fn reverse(&mut self, undo: UndoLog<'tcx>) { 54 match undo { 55 UndoLog::EqRelation(undo) => self.eq_relations.reverse(undo), 56 UndoLog::SubRelation(undo) => self.sub_relations.reverse(undo), 57 UndoLog::Values(undo) => self.values.reverse(undo), 58 } 59 } 60 } 61 62 #[derive(Clone)] 63 pub struct TypeVariableStorage<'tcx> { 64 values: sv::SnapshotVecStorage<Delegate>, 65 66 /// Two variables are unified in `eq_relations` when we have a 67 /// constraint `?X == ?Y`. This table also stores, for each key, 68 /// the known value. 69 eq_relations: ut::UnificationTableStorage<TyVidEqKey<'tcx>>, 70 71 /// Two variables are unified in `sub_relations` when we have a 72 /// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second 73 /// table exists only to help with the occurs check. In particular, 74 /// we want to report constraints like these as an occurs check 75 /// violation: 76 /// ``` text 77 /// ?1 <: ?3 78 /// Box<?3> <: ?1 79 /// ``` 80 /// Without this second table, what would happen in a case like 81 /// this is that we would instantiate `?1` with a generalized 82 /// type like `Box<?6>`. We would then relate `Box<?3> <: Box<?6>` 83 /// and infer that `?3 <: ?6`. Next, since `?1` was instantiated, 84 /// we would process `?1 <: ?3`, generalize `?1 = Box<?6>` to `Box<?9>`, 85 /// and instantiate `?3` with `Box<?9>`. Finally, we would relate 86 /// `?6 <: ?9`. But now that we instantiated `?3`, we can process 87 /// `?3 <: ?6`, which gives us `Box<?9> <: ?6`... and the cycle 88 /// continues. (This is `occurs-check-2.rs`.) 89 /// 90 /// What prevents this cycle is that when we generalize 91 /// `Box<?3>` to `Box<?6>`, we also sub-unify `?3` and `?6` 92 /// (in the generalizer). When we then process `Box<?6> <: ?3`, 93 /// the occurs check then fails because `?6` and `?3` are sub-unified, 94 /// and hence generalization fails. 95 /// 96 /// This is reasonable because, in Rust, subtypes have the same 97 /// "skeleton" and hence there is no possible type such that 98 /// (e.g.) `Box<?3> <: ?3` for any `?3`. 99 /// 100 /// In practice, we sometimes sub-unify variables in other spots, such 101 /// as when processing subtype predicates. This is not necessary but is 102 /// done to aid diagnostics, as it allows us to be more effective when 103 /// we guide the user towards where they should insert type hints. 104 sub_relations: ut::UnificationTableStorage<ty::TyVid>, 105 } 106 107 pub struct TypeVariableTable<'a, 'tcx> { 108 storage: &'a mut TypeVariableStorage<'tcx>, 109 110 undo_log: &'a mut InferCtxtUndoLogs<'tcx>, 111 } 112 113 #[derive(Copy, Clone, Debug)] 114 pub struct TypeVariableOrigin { 115 pub kind: TypeVariableOriginKind, 116 pub span: Span, 117 } 118 119 /// Reasons to create a type inference variable 120 #[derive(Copy, Clone, Debug)] 121 pub enum TypeVariableOriginKind { 122 MiscVariable, 123 NormalizeProjectionType, 124 TypeInference, 125 OpaqueTypeInference(DefId), 126 TypeParameterDefinition(Symbol, DefId), 127 128 /// One of the upvars or closure kind parameters in a `ClosureSubsts` 129 /// (before it has been determined). 130 // FIXME(eddyb) distinguish upvar inference variables from the rest. 131 ClosureSynthetic, 132 AutoDeref, 133 AdjustmentType, 134 135 /// In type check, when we are type checking a function that 136 /// returns `-> dyn Foo`, we substitute a type variable for the 137 /// return type for diagnostic purposes. 138 DynReturnFn, 139 LatticeVariable, 140 } 141 142 #[derive(Clone)] 143 pub(crate) struct TypeVariableData { 144 origin: TypeVariableOrigin, 145 } 146 147 #[derive(Copy, Clone, Debug)] 148 pub enum TypeVariableValue<'tcx> { 149 Known { value: Ty<'tcx> }, 150 Unknown { universe: ty::UniverseIndex }, 151 } 152 153 impl<'tcx> TypeVariableValue<'tcx> { 154 /// If this value is known, returns the type it is known to be. 155 /// Otherwise, `None`. known(&self) -> Option<Ty<'tcx>>156 pub fn known(&self) -> Option<Ty<'tcx>> { 157 match *self { 158 TypeVariableValue::Unknown { .. } => None, 159 TypeVariableValue::Known { value } => Some(value), 160 } 161 } 162 is_unknown(&self) -> bool163 pub fn is_unknown(&self) -> bool { 164 match *self { 165 TypeVariableValue::Unknown { .. } => true, 166 TypeVariableValue::Known { .. } => false, 167 } 168 } 169 } 170 171 #[derive(Clone)] 172 pub(crate) struct Instantiate; 173 174 pub(crate) struct Delegate; 175 176 impl<'tcx> TypeVariableStorage<'tcx> { new() -> TypeVariableStorage<'tcx>177 pub fn new() -> TypeVariableStorage<'tcx> { 178 TypeVariableStorage { 179 values: sv::SnapshotVecStorage::new(), 180 eq_relations: ut::UnificationTableStorage::new(), 181 sub_relations: ut::UnificationTableStorage::new(), 182 } 183 } 184 185 #[inline] with_log<'a>( &'a mut self, undo_log: &'a mut InferCtxtUndoLogs<'tcx>, ) -> TypeVariableTable<'a, 'tcx>186 pub(crate) fn with_log<'a>( 187 &'a mut self, 188 undo_log: &'a mut InferCtxtUndoLogs<'tcx>, 189 ) -> TypeVariableTable<'a, 'tcx> { 190 TypeVariableTable { storage: self, undo_log } 191 } 192 193 #[inline] eq_relations_ref(&self) -> &ut::UnificationTableStorage<TyVidEqKey<'tcx>>194 pub(crate) fn eq_relations_ref(&self) -> &ut::UnificationTableStorage<TyVidEqKey<'tcx>> { 195 &self.eq_relations 196 } 197 } 198 199 impl<'tcx> TypeVariableTable<'_, 'tcx> { 200 /// Returns the origin that was given when `vid` was created. 201 /// 202 /// Note that this function does not return care whether 203 /// `vid` has been unified with something else or not. var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin204 pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin { 205 &self.storage.values.get(vid.as_usize()).origin 206 } 207 208 /// Records that `a == b`, depending on `dir`. 209 /// 210 /// Precondition: neither `a` nor `b` are known. equate(&mut self, a: ty::TyVid, b: ty::TyVid)211 pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) { 212 debug_assert!(self.probe(a).is_unknown()); 213 debug_assert!(self.probe(b).is_unknown()); 214 self.eq_relations().union(a, b); 215 self.sub_relations().union(a, b); 216 } 217 218 /// Records that `a <: b`, depending on `dir`. 219 /// 220 /// Precondition: neither `a` nor `b` are known. sub(&mut self, a: ty::TyVid, b: ty::TyVid)221 pub fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) { 222 debug_assert!(self.probe(a).is_unknown()); 223 debug_assert!(self.probe(b).is_unknown()); 224 self.sub_relations().union(a, b); 225 } 226 227 /// Instantiates `vid` with the type `ty`. 228 /// 229 /// Precondition: `vid` must not have been previously instantiated. instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>)230 pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) { 231 let vid = self.root_var(vid); 232 debug_assert!(self.probe(vid).is_unknown()); 233 debug_assert!( 234 self.eq_relations().probe_value(vid).is_unknown(), 235 "instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}", 236 vid, 237 ty, 238 self.eq_relations().probe_value(vid) 239 ); 240 self.eq_relations().union_value(vid, TypeVariableValue::Known { value: ty }); 241 242 // Hack: we only need this so that `types_escaping_snapshot` 243 // can see what has been unified; see the Delegate impl for 244 // more details. 245 self.undo_log.push(Instantiate); 246 } 247 248 /// Creates a new type variable. 249 /// 250 /// - `diverging`: indicates if this is a "diverging" type 251 /// variable, e.g., one created as the type of a `return` 252 /// expression. The code in this module doesn't care if a 253 /// variable is diverging, but the main Rust type-checker will 254 /// sometimes "unify" such variables with the `!` or `()` types. 255 /// - `origin`: indicates *why* the type variable was created. 256 /// The code in this module doesn't care, but it can be useful 257 /// for improving error messages. new_var( &mut self, universe: ty::UniverseIndex, origin: TypeVariableOrigin, ) -> ty::TyVid258 pub fn new_var( 259 &mut self, 260 universe: ty::UniverseIndex, 261 origin: TypeVariableOrigin, 262 ) -> ty::TyVid { 263 let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe }); 264 265 let sub_key = self.sub_relations().new_key(()); 266 assert_eq!(eq_key.vid, sub_key); 267 268 let index = self.values().push(TypeVariableData { origin }); 269 assert_eq!(eq_key.vid.as_u32(), index as u32); 270 271 debug!("new_var(index={:?}, universe={:?}, origin={:?})", eq_key.vid, universe, origin); 272 273 eq_key.vid 274 } 275 276 /// Returns the number of type variables created thus far. num_vars(&self) -> usize277 pub fn num_vars(&self) -> usize { 278 self.storage.values.len() 279 } 280 281 /// Returns the "root" variable of `vid` in the `eq_relations` 282 /// equivalence table. All type variables that have been equated 283 /// will yield the same root variable (per the union-find 284 /// algorithm), so `root_var(a) == root_var(b)` implies that `a == 285 /// b` (transitively). root_var(&mut self, vid: ty::TyVid) -> ty::TyVid286 pub fn root_var(&mut self, vid: ty::TyVid) -> ty::TyVid { 287 self.eq_relations().find(vid).vid 288 } 289 290 /// Returns the "root" variable of `vid` in the `sub_relations` 291 /// equivalence table. All type variables that have been are 292 /// related via equality or subtyping will yield the same root 293 /// variable (per the union-find algorithm), so `sub_root_var(a) 294 /// == sub_root_var(b)` implies that: 295 /// ```text 296 /// exists X. (a <: X || X <: a) && (b <: X || X <: b) 297 /// ``` sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid298 pub fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid { 299 self.sub_relations().find(vid) 300 } 301 302 /// Returns `true` if `a` and `b` have same "sub-root" (i.e., exists some 303 /// type X such that `forall i in {a, b}. (i <: X || X <: i)`. sub_unified(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool304 pub fn sub_unified(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool { 305 self.sub_root_var(a) == self.sub_root_var(b) 306 } 307 308 /// Retrieves the type to which `vid` has been instantiated, if 309 /// any. probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx>310 pub fn probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> { 311 self.inlined_probe(vid) 312 } 313 314 /// An always-inlined variant of `probe`, for very hot call sites. 315 #[inline(always)] inlined_probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx>316 pub fn inlined_probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> { 317 self.eq_relations().inlined_probe_value(vid) 318 } 319 320 /// If `t` is a type-inference variable, and it has been 321 /// instantiated, then return the with which it was 322 /// instantiated. Otherwise, returns `t`. replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx>323 pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { 324 match *t.kind() { 325 ty::Infer(ty::TyVar(v)) => match self.probe(v) { 326 TypeVariableValue::Unknown { .. } => t, 327 TypeVariableValue::Known { value } => value, 328 }, 329 _ => t, 330 } 331 } 332 333 #[inline] values( &mut self, ) -> sv::SnapshotVec<Delegate, &mut Vec<TypeVariableData>, &mut InferCtxtUndoLogs<'tcx>>334 fn values( 335 &mut self, 336 ) -> sv::SnapshotVec<Delegate, &mut Vec<TypeVariableData>, &mut InferCtxtUndoLogs<'tcx>> { 337 self.storage.values.with_log(self.undo_log) 338 } 339 340 #[inline] eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>>341 fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> { 342 self.storage.eq_relations.with_log(self.undo_log) 343 } 344 345 #[inline] sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, ty::TyVid>346 fn sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, ty::TyVid> { 347 self.storage.sub_relations.with_log(self.undo_log) 348 } 349 350 /// Returns a range of the type variables created during the snapshot. vars_since_snapshot( &mut self, value_count: usize, ) -> (Range<TyVid>, Vec<TypeVariableOrigin>)351 pub fn vars_since_snapshot( 352 &mut self, 353 value_count: usize, 354 ) -> (Range<TyVid>, Vec<TypeVariableOrigin>) { 355 let range = TyVid::from_usize(value_count)..TyVid::from_usize(self.num_vars()); 356 ( 357 range.start..range.end, 358 (range.start.as_usize()..range.end.as_usize()) 359 .map(|index| self.storage.values.get(index).origin) 360 .collect(), 361 ) 362 } 363 364 /// Returns indices of all variables that are not yet 365 /// instantiated. unsolved_variables(&mut self) -> Vec<ty::TyVid>366 pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> { 367 (0..self.storage.values.len()) 368 .filter_map(|i| { 369 let vid = ty::TyVid::from_usize(i); 370 match self.probe(vid) { 371 TypeVariableValue::Unknown { .. } => Some(vid), 372 TypeVariableValue::Known { .. } => None, 373 } 374 }) 375 .collect() 376 } 377 } 378 379 impl sv::SnapshotVecDelegate for Delegate { 380 type Value = TypeVariableData; 381 type Undo = Instantiate; 382 reverse(_values: &mut Vec<TypeVariableData>, _action: Instantiate)383 fn reverse(_values: &mut Vec<TypeVariableData>, _action: Instantiate) { 384 // We don't actually have to *do* anything to reverse an 385 // instantiation; the value for a variable is stored in the 386 // `eq_relations` and hence its rollback code will handle 387 // it. In fact, we could *almost* just remove the 388 // `SnapshotVec` entirely, except that we would have to 389 // reproduce *some* of its logic, since we want to know which 390 // type variables have been instantiated since the snapshot 391 // was started, so we can implement `types_escaping_snapshot`. 392 // 393 // (If we extended the `UnificationTable` to let us see which 394 // values have been unified and so forth, that might also 395 // suffice.) 396 } 397 } 398 399 /////////////////////////////////////////////////////////////////////////// 400 401 /// These structs (a newtyped TyVid) are used as the unification key 402 /// for the `eq_relations`; they carry a `TypeVariableValue` along 403 /// with them. 404 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 405 pub(crate) struct TyVidEqKey<'tcx> { 406 vid: ty::TyVid, 407 408 // in the table, we map each ty-vid to one of these: 409 phantom: PhantomData<TypeVariableValue<'tcx>>, 410 } 411 412 impl<'tcx> From<ty::TyVid> for TyVidEqKey<'tcx> { 413 #[inline] // make this function eligible for inlining - it is quite hot. from(vid: ty::TyVid) -> Self414 fn from(vid: ty::TyVid) -> Self { 415 TyVidEqKey { vid, phantom: PhantomData } 416 } 417 } 418 419 impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> { 420 type Value = TypeVariableValue<'tcx>; 421 #[inline(always)] index(&self) -> u32422 fn index(&self) -> u32 { 423 self.vid.as_u32() 424 } 425 #[inline] from_index(i: u32) -> Self426 fn from_index(i: u32) -> Self { 427 TyVidEqKey::from(ty::TyVid::from_u32(i)) 428 } tag() -> &'static str429 fn tag() -> &'static str { 430 "TyVidEqKey" 431 } 432 } 433 434 impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { 435 type Error = ut::NoError; 436 unify_values(value1: &Self, value2: &Self) -> Result<Self, ut::NoError>437 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, ut::NoError> { 438 match (value1, value2) { 439 // We never equate two type variables, both of which 440 // have known types. Instead, we recursively equate 441 // those types. 442 (&TypeVariableValue::Known { .. }, &TypeVariableValue::Known { .. }) => { 443 bug!("equating two type variables, both of which have known types") 444 } 445 446 // If one side is known, prefer that one. 447 (&TypeVariableValue::Known { .. }, &TypeVariableValue::Unknown { .. }) => Ok(*value1), 448 (&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2), 449 450 // If both sides are *unknown*, it hardly matters, does it? 451 ( 452 &TypeVariableValue::Unknown { universe: universe1 }, 453 &TypeVariableValue::Unknown { universe: universe2 }, 454 ) => { 455 // If we unify two unbound variables, ?T and ?U, then whatever 456 // value they wind up taking (which must be the same value) must 457 // be nameable by both universes. Therefore, the resulting 458 // universe is the minimum of the two universes, because that is 459 // the one which contains the fewest names in scope. 460 let universe = cmp::min(universe1, universe2); 461 Ok(TypeVariableValue::Unknown { universe }) 462 } 463 } 464 } 465 } 466