1 pub use self::freshen::TypeFreshener; 2 pub use self::lexical_region_resolve::RegionResolutionError; 3 pub use self::LateBoundRegionConversionTime::*; 4 pub use self::RegionVariableOrigin::*; 5 pub use self::SubregionOrigin::*; 6 pub use self::ValuePairs::*; 7 8 use self::opaque_types::OpaqueTypeMap; 9 pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; 10 11 use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine}; 12 13 use hir::def_id::CRATE_DEF_ID; 14 use rustc_data_structures::fx::{FxHashMap, FxHashSet}; 15 use rustc_data_structures::sync::Lrc; 16 use rustc_data_structures::undo_log::Rollback; 17 use rustc_data_structures::unify as ut; 18 use rustc_errors::DiagnosticBuilder; 19 use rustc_hir as hir; 20 use rustc_hir::def_id::{DefId, LocalDefId}; 21 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; 22 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; 23 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; 24 use rustc_middle::mir::interpret::EvalToConstValueResult; 25 use rustc_middle::traits::select; 26 use rustc_middle::ty::error::{ExpectedFound, TypeError}; 27 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; 28 use rustc_middle::ty::relate::RelateResult; 29 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; 30 pub use rustc_middle::ty::IntVarValue; 31 use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; 32 use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid}; 33 use rustc_session::config::BorrowckMode; 34 use rustc_span::symbol::Symbol; 35 use rustc_span::Span; 36 37 use std::cell::{Cell, Ref, RefCell}; 38 use std::collections::BTreeMap; 39 use std::fmt; 40 41 use self::combine::CombineFields; 42 use self::free_regions::RegionRelations; 43 use self::lexical_region_resolve::LexicalRegionResolutions; 44 use self::outlives::env::OutlivesEnvironment; 45 use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound}; 46 use self::region_constraints::{ 47 RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot, 48 }; 49 use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; 50 51 pub mod at; 52 pub mod canonical; 53 mod combine; 54 mod equate; 55 pub mod error_reporting; 56 pub mod free_regions; 57 mod freshen; 58 mod fudge; 59 mod glb; 60 mod higher_ranked; 61 pub mod lattice; 62 mod lexical_region_resolve; 63 mod lub; 64 pub mod nll_relate; 65 pub mod opaque_types; 66 pub mod outlives; 67 mod projection; 68 pub mod region_constraints; 69 pub mod resolve; 70 mod sub; 71 pub mod type_variable; 72 mod undo_log; 73 74 use crate::infer::canonical::OriginalQueryValues; 75 pub use rustc_middle::infer::unify_key; 76 77 #[must_use] 78 #[derive(Debug)] 79 pub struct InferOk<'tcx, T> { 80 pub value: T, 81 pub obligations: PredicateObligations<'tcx>, 82 } 83 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>; 84 85 pub type Bound<T> = Option<T>; 86 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" 87 pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result" 88 89 pub(crate) type UnificationTable<'a, 'tcx, T> = ut::UnificationTable< 90 ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'a mut InferCtxtUndoLogs<'tcx>>, 91 >; 92 93 /// How we should handle region solving. 94 /// 95 /// This is used so that the region values inferred by HIR region solving are 96 /// not exposed, and so that we can avoid doing work in HIR typeck that MIR 97 /// typeck will also do. 98 #[derive(Copy, Clone, Debug, Default)] 99 pub enum RegionckMode { 100 /// The default mode: report region errors, don't erase regions. 101 #[default] 102 Solve, 103 /// Erase the results of region after solving. 104 Erase { 105 /// A flag that is used to suppress region errors, when we are doing 106 /// region checks that the NLL borrow checker will also do -- it might 107 /// be set to true. 108 suppress_errors: bool, 109 }, 110 } 111 112 impl RegionckMode { 113 /// Indicates that the MIR borrowck will repeat these region 114 /// checks, so we should ignore errors if NLL is (unconditionally) 115 /// enabled. for_item_body(tcx: TyCtxt<'_>) -> Self116 pub fn for_item_body(tcx: TyCtxt<'_>) -> Self { 117 // FIXME(Centril): Once we actually remove `::Migrate` also make 118 // this always `true` and then proceed to eliminate the dead code. 119 match tcx.borrowck_mode() { 120 // If we're on Migrate mode, report AST region errors 121 BorrowckMode::Migrate => RegionckMode::Erase { suppress_errors: false }, 122 123 // If we're on MIR, don't report AST region errors as they should be reported by NLL 124 BorrowckMode::Mir => RegionckMode::Erase { suppress_errors: true }, 125 } 126 } 127 } 128 129 /// This type contains all the things within `InferCtxt` that sit within a 130 /// `RefCell` and are involved with taking/rolling back snapshots. Snapshot 131 /// operations are hot enough that we want only one call to `borrow_mut` per 132 /// call to `start_snapshot` and `rollback_to`. 133 pub struct InferCtxtInner<'tcx> { 134 /// Cache for projections. This cache is snapshotted along with the infcx. 135 /// 136 /// Public so that `traits::project` can use it. 137 pub projection_cache: traits::ProjectionCacheStorage<'tcx>, 138 139 /// We instantiate `UnificationTable` with `bounds<Ty>` because the types 140 /// that might instantiate a general type variable have an order, 141 /// represented by its upper and lower bounds. 142 type_variable_storage: type_variable::TypeVariableStorage<'tcx>, 143 144 /// Map from const parameter variable to the kind of const it represents. 145 const_unification_storage: ut::UnificationTableStorage<ty::ConstVid<'tcx>>, 146 147 /// Map from integral variable to the kind of integer it represents. 148 int_unification_storage: ut::UnificationTableStorage<ty::IntVid>, 149 150 /// Map from floating variable to the kind of float it represents. 151 float_unification_storage: ut::UnificationTableStorage<ty::FloatVid>, 152 153 /// Tracks the set of region variables and the constraints between them. 154 /// This is initially `Some(_)` but when 155 /// `resolve_regions_and_report_errors` is invoked, this gets set to `None` 156 /// -- further attempts to perform unification, etc., may fail if new 157 /// region constraints would've been added. 158 region_constraint_storage: Option<RegionConstraintStorage<'tcx>>, 159 160 /// A set of constraints that regionck must validate. Each 161 /// constraint has the form `T:'a`, meaning "some type `T` must 162 /// outlive the lifetime 'a". These constraints derive from 163 /// instantiated type parameters. So if you had a struct defined 164 /// like 165 /// 166 /// struct Foo<T:'static> { ... } 167 /// 168 /// then in some expression `let x = Foo { ... }` it will 169 /// instantiate the type parameter `T` with a fresh type `$0`. At 170 /// the same time, it will record a region obligation of 171 /// `$0:'static`. This will get checked later by regionck. (We 172 /// can't generally check these things right away because we have 173 /// to wait until types are resolved.) 174 /// 175 /// These are stored in a map keyed to the id of the innermost 176 /// enclosing fn body / static initializer expression. This is 177 /// because the location where the obligation was incurred can be 178 /// relevant with respect to which sublifetime assumptions are in 179 /// place. The reason that we store under the fn-id, and not 180 /// something more fine-grained, is so that it is easier for 181 /// regionck to be sure that it has found *all* the region 182 /// obligations (otherwise, it's easy to fail to walk to a 183 /// particular node-id). 184 /// 185 /// Before running `resolve_regions_and_report_errors`, the creator 186 /// of the inference context is expected to invoke 187 /// `process_region_obligations` (defined in `self::region_obligations`) 188 /// for each body-id in this map, which will process the 189 /// obligations within. This is expected to be done 'late enough' 190 /// that all type inference variables have been bound and so forth. 191 region_obligations: Vec<(hir::HirId, RegionObligation<'tcx>)>, 192 193 undo_log: InferCtxtUndoLogs<'tcx>, 194 195 // Opaque types found in explicit return types and their 196 // associated fresh inference variable. Writeback resolves these 197 // variables to get the concrete type, which can be used to 198 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions. 199 pub opaque_types: OpaqueTypeMap<'tcx>, 200 201 /// A map from inference variables created from opaque 202 /// type instantiations (`ty::Infer`) to the actual opaque 203 /// type (`ty::Opaque`). Used during fallback to map unconstrained 204 /// opaque type inference variables to their corresponding 205 /// opaque type. 206 pub opaque_types_vars: FxHashMap<Ty<'tcx>, Ty<'tcx>>, 207 } 208 209 impl<'tcx> InferCtxtInner<'tcx> { new() -> InferCtxtInner<'tcx>210 fn new() -> InferCtxtInner<'tcx> { 211 InferCtxtInner { 212 projection_cache: Default::default(), 213 type_variable_storage: type_variable::TypeVariableStorage::new(), 214 undo_log: InferCtxtUndoLogs::default(), 215 const_unification_storage: ut::UnificationTableStorage::new(), 216 int_unification_storage: ut::UnificationTableStorage::new(), 217 float_unification_storage: ut::UnificationTableStorage::new(), 218 region_constraint_storage: Some(RegionConstraintStorage::new()), 219 region_obligations: vec![], 220 opaque_types: Default::default(), 221 opaque_types_vars: Default::default(), 222 } 223 } 224 225 #[inline] region_obligations(&self) -> &[(hir::HirId, RegionObligation<'tcx>)]226 pub fn region_obligations(&self) -> &[(hir::HirId, RegionObligation<'tcx>)] { 227 &self.region_obligations 228 } 229 230 #[inline] projection_cache(&mut self) -> traits::ProjectionCache<'_, 'tcx>231 pub fn projection_cache(&mut self) -> traits::ProjectionCache<'_, 'tcx> { 232 self.projection_cache.with_log(&mut self.undo_log) 233 } 234 235 #[inline] type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx>236 fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { 237 self.type_variable_storage.with_log(&mut self.undo_log) 238 } 239 240 #[inline] int_unification_table( &mut self, ) -> ut::UnificationTable< ut::InPlace< ty::IntVid, &mut ut::UnificationStorage<ty::IntVid>, &mut InferCtxtUndoLogs<'tcx>, >, >241 fn int_unification_table( 242 &mut self, 243 ) -> ut::UnificationTable< 244 ut::InPlace< 245 ty::IntVid, 246 &mut ut::UnificationStorage<ty::IntVid>, 247 &mut InferCtxtUndoLogs<'tcx>, 248 >, 249 > { 250 self.int_unification_storage.with_log(&mut self.undo_log) 251 } 252 253 #[inline] float_unification_table( &mut self, ) -> ut::UnificationTable< ut::InPlace< ty::FloatVid, &mut ut::UnificationStorage<ty::FloatVid>, &mut InferCtxtUndoLogs<'tcx>, >, >254 fn float_unification_table( 255 &mut self, 256 ) -> ut::UnificationTable< 257 ut::InPlace< 258 ty::FloatVid, 259 &mut ut::UnificationStorage<ty::FloatVid>, 260 &mut InferCtxtUndoLogs<'tcx>, 261 >, 262 > { 263 self.float_unification_storage.with_log(&mut self.undo_log) 264 } 265 266 #[inline] const_unification_table( &mut self, ) -> ut::UnificationTable< ut::InPlace< ty::ConstVid<'tcx>, &mut ut::UnificationStorage<ty::ConstVid<'tcx>>, &mut InferCtxtUndoLogs<'tcx>, >, >267 fn const_unification_table( 268 &mut self, 269 ) -> ut::UnificationTable< 270 ut::InPlace< 271 ty::ConstVid<'tcx>, 272 &mut ut::UnificationStorage<ty::ConstVid<'tcx>>, 273 &mut InferCtxtUndoLogs<'tcx>, 274 >, 275 > { 276 self.const_unification_storage.with_log(&mut self.undo_log) 277 } 278 279 #[inline] unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx>280 pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> { 281 self.region_constraint_storage 282 .as_mut() 283 .expect("region constraints already solved") 284 .with_log(&mut self.undo_log) 285 } 286 } 287 288 pub struct InferCtxt<'a, 'tcx> { 289 pub tcx: TyCtxt<'tcx>, 290 291 /// The `DefId` of the item in whose context we are performing inference or typeck. 292 /// It is used to check whether an opaque type use is a defining use. 293 pub defining_use_anchor: LocalDefId, 294 295 /// During type-checking/inference of a body, `in_progress_typeck_results` 296 /// contains a reference to the typeck results being built up, which are 297 /// used for reading closure kinds/signatures as they are inferred, 298 /// and for error reporting logic to read arbitrary node types. 299 pub in_progress_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>, 300 301 pub inner: RefCell<InferCtxtInner<'tcx>>, 302 303 /// If set, this flag causes us to skip the 'leak check' during 304 /// higher-ranked subtyping operations. This flag is a temporary one used 305 /// to manage the removal of the leak-check: for the time being, we still run the 306 /// leak-check, but we issue warnings. This flag can only be set to true 307 /// when entering a snapshot. 308 skip_leak_check: Cell<bool>, 309 310 /// Once region inference is done, the values for each variable. 311 lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>, 312 313 /// Caches the results of trait selection. This cache is used 314 /// for things that have to do with the parameters in scope. 315 pub selection_cache: select::SelectionCache<'tcx>, 316 317 /// Caches the results of trait evaluation. 318 pub evaluation_cache: select::EvaluationCache<'tcx>, 319 320 /// the set of predicates on which errors have been reported, to 321 /// avoid reporting the same error twice. 322 pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>, 323 324 pub reported_closure_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>, 325 326 /// When an error occurs, we want to avoid reporting "derived" 327 /// errors that are due to this original failure. Normally, we 328 /// handle this with the `err_count_on_creation` count, which 329 /// basically just tracks how many errors were reported when we 330 /// started type-checking a fn and checks to see if any new errors 331 /// have been reported since then. Not great, but it works. 332 /// 333 /// However, when errors originated in other passes -- notably 334 /// resolve -- this heuristic breaks down. Therefore, we have this 335 /// auxiliary flag that one can set whenever one creates a 336 /// type-error that is due to an error in a prior pass. 337 /// 338 /// Don't read this flag directly, call `is_tainted_by_errors()` 339 /// and `set_tainted_by_errors()`. 340 tainted_by_errors_flag: Cell<bool>, 341 342 /// Track how many errors were reported when this infcx is created. 343 /// If the number of errors increases, that's also a sign (line 344 /// `tained_by_errors`) to avoid reporting certain kinds of errors. 345 // FIXME(matthewjasper) Merge into `tainted_by_errors_flag` 346 err_count_on_creation: usize, 347 348 /// This flag is true while there is an active snapshot. 349 in_snapshot: Cell<bool>, 350 351 /// What is the innermost universe we have created? Starts out as 352 /// `UniverseIndex::root()` but grows from there as we enter 353 /// universal quantifiers. 354 /// 355 /// N.B., at present, we exclude the universal quantifiers on the 356 /// item we are type-checking, and just consider those names as 357 /// part of the root universe. So this would only get incremented 358 /// when we enter into a higher-ranked (`for<..>`) type or trait 359 /// bound. 360 universe: Cell<ty::UniverseIndex>, 361 } 362 363 /// See the `error_reporting` module for more details. 364 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)] 365 pub enum ValuePairs<'tcx> { 366 Types(ExpectedFound<Ty<'tcx>>), 367 Regions(ExpectedFound<ty::Region<'tcx>>), 368 Consts(ExpectedFound<&'tcx ty::Const<'tcx>>), 369 TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>), 370 PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>), 371 } 372 373 /// The trace designates the path through inference that we took to 374 /// encounter an error or subtyping constraint. 375 /// 376 /// See the `error_reporting` module for more details. 377 #[derive(Clone, Debug)] 378 pub struct TypeTrace<'tcx> { 379 cause: ObligationCause<'tcx>, 380 values: ValuePairs<'tcx>, 381 } 382 383 /// The origin of a `r1 <= r2` constraint. 384 /// 385 /// See `error_reporting` module for more details 386 #[derive(Clone, Debug)] 387 pub enum SubregionOrigin<'tcx> { 388 /// Arose from a subtyping relation 389 Subtype(Box<TypeTrace<'tcx>>), 390 391 /// When casting `&'a T` to an `&'b Trait` object, 392 /// relating `'a` to `'b` 393 RelateObjectBound(Span), 394 395 /// Some type parameter was instantiated with the given type, 396 /// and that type must outlive some region. 397 RelateParamBound(Span, Ty<'tcx>, Option<Span>), 398 399 /// The given region parameter was instantiated with a region 400 /// that must outlive some other region. 401 RelateRegionParamBound(Span), 402 403 /// Creating a pointer `b` to contents of another reference 404 Reborrow(Span), 405 406 /// Creating a pointer `b` to contents of an upvar 407 ReborrowUpvar(Span, ty::UpvarId), 408 409 /// Data with type `Ty<'tcx>` was borrowed 410 DataBorrowed(Ty<'tcx>, Span), 411 412 /// (&'a &'b T) where a >= b 413 ReferenceOutlivesReferent(Ty<'tcx>, Span), 414 415 /// Comparing the signature and requirements of an impl method against 416 /// the containing trait. 417 CompareImplMethodObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, 418 419 /// Comparing the signature and requirements of an impl associated type 420 /// against the containing trait 421 CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, 422 } 423 424 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger. 425 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] 426 static_assert_size!(SubregionOrigin<'_>, 32); 427 428 /// Times when we replace late-bound regions with variables: 429 #[derive(Clone, Copy, Debug)] 430 pub enum LateBoundRegionConversionTime { 431 /// when a fn is called 432 FnCall, 433 434 /// when two higher-ranked types are compared 435 HigherRankedType, 436 437 /// when projecting an associated type 438 AssocTypeProjection(DefId), 439 } 440 441 /// Reasons to create a region inference variable 442 /// 443 /// See `error_reporting` module for more details 444 #[derive(Copy, Clone, Debug)] 445 pub enum RegionVariableOrigin { 446 /// Region variables created for ill-categorized reasons, 447 /// mostly indicates places in need of refactoring 448 MiscVariable(Span), 449 450 /// Regions created by a `&P` or `[...]` pattern 451 PatternRegion(Span), 452 453 /// Regions created by `&` operator 454 AddrOfRegion(Span), 455 456 /// Regions created as part of an autoref of a method receiver 457 Autoref(Span), 458 459 /// Regions created as part of an automatic coercion 460 Coercion(Span), 461 462 /// Region variables created as the values for early-bound regions 463 EarlyBoundRegion(Span, Symbol), 464 465 /// Region variables created for bound regions 466 /// in a function or method that is called 467 LateBoundRegion(Span, ty::BoundRegionKind, LateBoundRegionConversionTime), 468 469 UpvarRegion(ty::UpvarId, Span), 470 471 /// This origin is used for the inference variables that we create 472 /// during NLL region processing. 473 Nll(NllRegionVariableOrigin), 474 } 475 476 #[derive(Copy, Clone, Debug)] 477 pub enum NllRegionVariableOrigin { 478 /// During NLL region processing, we create variables for free 479 /// regions that we encounter in the function signature and 480 /// elsewhere. This origin indices we've got one of those. 481 FreeRegion, 482 483 /// "Universal" instantiation of a higher-ranked region (e.g., 484 /// from a `for<'a> T` binder). Meant to represent "any region". 485 Placeholder(ty::PlaceholderRegion), 486 487 /// The variable we create to represent `'empty(U0)`. 488 RootEmptyRegion, 489 490 Existential { 491 /// If this is true, then this variable was created to represent a lifetime 492 /// bound in a `for` binder. For example, it might have been created to 493 /// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`. 494 /// Such variables are created when we are trying to figure out if there 495 /// is any valid instantiation of `'a` that could fit into some scenario. 496 /// 497 /// This is used to inform error reporting: in the case that we are trying to 498 /// determine whether there is any valid instantiation of a `'a` variable that meets 499 /// some constraint C, we want to blame the "source" of that `for` type, 500 /// rather than blaming the source of the constraint C. 501 from_forall: bool, 502 }, 503 } 504 505 // FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`. 506 #[derive(Copy, Clone, Debug)] 507 pub enum FixupError<'tcx> { 508 UnresolvedIntTy(IntVid), 509 UnresolvedFloatTy(FloatVid), 510 UnresolvedTy(TyVid), 511 UnresolvedConst(ConstVid<'tcx>), 512 } 513 514 /// See the `region_obligations` field for more information. 515 #[derive(Clone)] 516 pub struct RegionObligation<'tcx> { 517 pub sub_region: ty::Region<'tcx>, 518 pub sup_type: Ty<'tcx>, 519 pub origin: SubregionOrigin<'tcx>, 520 } 521 522 impl<'tcx> fmt::Display for FixupError<'tcx> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result523 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 524 use self::FixupError::*; 525 526 match *self { 527 UnresolvedIntTy(_) => write!( 528 f, 529 "cannot determine the type of this integer; \ 530 add a suffix to specify the type explicitly" 531 ), 532 UnresolvedFloatTy(_) => write!( 533 f, 534 "cannot determine the type of this number; \ 535 add a suffix to specify the type explicitly" 536 ), 537 UnresolvedTy(_) => write!(f, "unconstrained type"), 538 UnresolvedConst(_) => write!(f, "unconstrained const value"), 539 } 540 } 541 } 542 543 /// Helper type of a temporary returned by `tcx.infer_ctxt()`. 544 /// Necessary because we can't write the following bound: 545 /// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`. 546 pub struct InferCtxtBuilder<'tcx> { 547 tcx: TyCtxt<'tcx>, 548 fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>, 549 defining_use_anchor: LocalDefId, 550 } 551 552 pub trait TyCtxtInferExt<'tcx> { infer_ctxt(self) -> InferCtxtBuilder<'tcx>553 fn infer_ctxt(self) -> InferCtxtBuilder<'tcx>; 554 } 555 556 impl TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { infer_ctxt(self) -> InferCtxtBuilder<'tcx>557 fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { 558 InferCtxtBuilder { 559 tcx: self, 560 defining_use_anchor: CRATE_DEF_ID, 561 fresh_typeck_results: None, 562 } 563 } 564 } 565 566 impl<'tcx> InferCtxtBuilder<'tcx> { 567 /// Used only by `rustc_typeck` during body type-checking/inference, 568 /// will initialize `in_progress_typeck_results` with fresh `TypeckResults`. 569 /// Will also change the scope for opaque type defining use checks to the given owner. with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self570 pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self { 571 self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner))); 572 self.with_opaque_type_inference(table_owner) 573 } 574 575 /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types, 576 /// you need to call this function. Otherwise the opaque type will be treated opaquely. 577 /// 578 /// It is only meant to be called in two places, for typeck 579 /// (via `with_fresh_in_progress_typeck_results`) and for the inference context used 580 /// in mir borrowck. with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self581 pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self { 582 self.defining_use_anchor = defining_use_anchor; 583 self 584 } 585 586 /// Given a canonical value `C` as a starting point, create an 587 /// inference context that contains each of the bound values 588 /// within instantiated as a fresh variable. The `f` closure is 589 /// invoked with the new infcx, along with the instantiated value 590 /// `V` and a substitution `S`. This substitution `S` maps from 591 /// the bound values in `C` to their instantiated values in `V` 592 /// (in other words, `S(C) = V`). enter_with_canonical<T, R>( &mut self, span: Span, canonical: &Canonical<'tcx, T>, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>, T, CanonicalVarValues<'tcx>) -> R, ) -> R where T: TypeFoldable<'tcx>,593 pub fn enter_with_canonical<T, R>( 594 &mut self, 595 span: Span, 596 canonical: &Canonical<'tcx, T>, 597 f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>, T, CanonicalVarValues<'tcx>) -> R, 598 ) -> R 599 where 600 T: TypeFoldable<'tcx>, 601 { 602 self.enter(|infcx| { 603 let (value, subst) = 604 infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); 605 f(infcx, value, subst) 606 }) 607 } 608 enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R609 pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R { 610 let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self; 611 let in_progress_typeck_results = fresh_typeck_results.as_ref(); 612 f(InferCtxt { 613 tcx, 614 defining_use_anchor, 615 in_progress_typeck_results, 616 inner: RefCell::new(InferCtxtInner::new()), 617 lexical_region_resolutions: RefCell::new(None), 618 selection_cache: Default::default(), 619 evaluation_cache: Default::default(), 620 reported_trait_errors: Default::default(), 621 reported_closure_mismatch: Default::default(), 622 tainted_by_errors_flag: Cell::new(false), 623 err_count_on_creation: tcx.sess.err_count(), 624 in_snapshot: Cell::new(false), 625 skip_leak_check: Cell::new(false), 626 universe: Cell::new(ty::UniverseIndex::ROOT), 627 }) 628 } 629 } 630 631 impl<'tcx, T> InferOk<'tcx, T> { unit(self) -> InferOk<'tcx, ()>632 pub fn unit(self) -> InferOk<'tcx, ()> { 633 InferOk { value: (), obligations: self.obligations } 634 } 635 636 /// Extracts `value`, registering any obligations into `fulfill_cx`. into_value_registering_obligations( self, infcx: &InferCtxt<'_, 'tcx>, fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> T637 pub fn into_value_registering_obligations( 638 self, 639 infcx: &InferCtxt<'_, 'tcx>, 640 fulfill_cx: &mut dyn TraitEngine<'tcx>, 641 ) -> T { 642 let InferOk { value, obligations } = self; 643 for obligation in obligations { 644 fulfill_cx.register_predicate_obligation(infcx, obligation); 645 } 646 value 647 } 648 } 649 650 impl<'tcx> InferOk<'tcx, ()> { into_obligations(self) -> PredicateObligations<'tcx>651 pub fn into_obligations(self) -> PredicateObligations<'tcx> { 652 self.obligations 653 } 654 } 655 656 #[must_use = "once you start a snapshot, you should always consume it"] 657 pub struct CombinedSnapshot<'a, 'tcx> { 658 undo_snapshot: Snapshot<'tcx>, 659 region_constraints_snapshot: RegionSnapshot, 660 universe: ty::UniverseIndex, 661 was_in_snapshot: bool, 662 _in_progress_typeck_results: Option<Ref<'a, ty::TypeckResults<'tcx>>>, 663 } 664 665 impl<'a, 'tcx> InferCtxt<'a, 'tcx> { 666 /// calls `tcx.try_unify_abstract_consts` after 667 /// canonicalizing the consts. try_unify_abstract_consts( &self, a: ty::Unevaluated<'tcx, ()>, b: ty::Unevaluated<'tcx, ()>, ) -> bool668 pub fn try_unify_abstract_consts( 669 &self, 670 a: ty::Unevaluated<'tcx, ()>, 671 b: ty::Unevaluated<'tcx, ()>, 672 ) -> bool { 673 let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default()); 674 debug!("canonical consts: {:?}", &canonical.value); 675 676 self.tcx.try_unify_abstract_consts(canonical.value) 677 } 678 is_in_snapshot(&self) -> bool679 pub fn is_in_snapshot(&self) -> bool { 680 self.in_snapshot.get() 681 } 682 freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T683 pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T { 684 t.fold_with(&mut self.freshener()) 685 } 686 687 /// Returns the origin of the type variable identified by `vid`, or `None` 688 /// if this is not a type variable. 689 /// 690 /// No attempt is made to resolve `ty`. type_var_origin(&'a self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin>691 pub fn type_var_origin(&'a self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin> { 692 match *ty.kind() { 693 ty::Infer(ty::TyVar(vid)) => { 694 Some(*self.inner.borrow_mut().type_variables().var_origin(vid)) 695 } 696 _ => None, 697 } 698 } 699 freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx>700 pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { 701 freshen::TypeFreshener::new(self, false) 702 } 703 704 /// Like `freshener`, but does not replace `'static` regions. freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx>705 pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { 706 freshen::TypeFreshener::new(self, true) 707 } 708 unsolved_variables(&self) -> Vec<Ty<'tcx>>709 pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> { 710 let mut inner = self.inner.borrow_mut(); 711 let mut vars: Vec<Ty<'_>> = inner 712 .type_variables() 713 .unsolved_variables() 714 .into_iter() 715 .map(|t| self.tcx.mk_ty_var(t)) 716 .collect(); 717 vars.extend( 718 (0..inner.int_unification_table().len()) 719 .map(|i| ty::IntVid { index: i as u32 }) 720 .filter(|&vid| inner.int_unification_table().probe_value(vid).is_none()) 721 .map(|v| self.tcx.mk_int_var(v)), 722 ); 723 vars.extend( 724 (0..inner.float_unification_table().len()) 725 .map(|i| ty::FloatVid { index: i as u32 }) 726 .filter(|&vid| inner.float_unification_table().probe_value(vid).is_none()) 727 .map(|v| self.tcx.mk_float_var(v)), 728 ); 729 vars 730 } 731 combine_fields( &'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> CombineFields<'a, 'tcx>732 fn combine_fields( 733 &'a self, 734 trace: TypeTrace<'tcx>, 735 param_env: ty::ParamEnv<'tcx>, 736 ) -> CombineFields<'a, 'tcx> { 737 CombineFields { 738 infcx: self, 739 trace, 740 cause: None, 741 param_env, 742 obligations: PredicateObligations::new(), 743 } 744 } 745 746 /// Clear the "currently in a snapshot" flag, invoke the closure, 747 /// then restore the flag to its original value. This flag is a 748 /// debugging measure designed to detect cases where we start a 749 /// snapshot, create type variables, and register obligations 750 /// which may involve those type variables in the fulfillment cx, 751 /// potentially leaving "dangling type variables" behind. 752 /// In such cases, an assertion will fail when attempting to 753 /// register obligations, within a snapshot. Very useful, much 754 /// better than grovelling through megabytes of `RUSTC_LOG` output. 755 /// 756 /// HOWEVER, in some cases the flag is unhelpful. In particular, we 757 /// sometimes create a "mini-fulfilment-cx" in which we enroll 758 /// obligations. As long as this fulfillment cx is fully drained 759 /// before we return, this is not a problem, as there won't be any 760 /// escaping obligations in the main cx. In those cases, you can 761 /// use this function. save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R where F: FnOnce(&Self) -> R,762 pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R 763 where 764 F: FnOnce(&Self) -> R, 765 { 766 let flag = self.in_snapshot.replace(false); 767 let result = func(self); 768 self.in_snapshot.set(flag); 769 result 770 } 771 start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx>772 fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> { 773 debug!("start_snapshot()"); 774 775 let in_snapshot = self.in_snapshot.replace(true); 776 777 let mut inner = self.inner.borrow_mut(); 778 779 CombinedSnapshot { 780 undo_snapshot: inner.undo_log.start_snapshot(), 781 region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(), 782 universe: self.universe(), 783 was_in_snapshot: in_snapshot, 784 // Borrow typeck results "in progress" (i.e., during typeck) 785 // to ban writes from within a snapshot to them. 786 _in_progress_typeck_results: self 787 .in_progress_typeck_results 788 .map(|typeck_results| typeck_results.borrow()), 789 } 790 } 791 792 #[instrument(skip(self, snapshot), level = "debug")] rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>)793 fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) { 794 let CombinedSnapshot { 795 undo_snapshot, 796 region_constraints_snapshot, 797 universe, 798 was_in_snapshot, 799 _in_progress_typeck_results, 800 } = snapshot; 801 802 self.in_snapshot.set(was_in_snapshot); 803 self.universe.set(universe); 804 805 let mut inner = self.inner.borrow_mut(); 806 inner.rollback_to(undo_snapshot); 807 inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot); 808 } 809 810 #[instrument(skip(self, snapshot), level = "debug")] commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>)811 fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) { 812 let CombinedSnapshot { 813 undo_snapshot, 814 region_constraints_snapshot: _, 815 universe: _, 816 was_in_snapshot, 817 _in_progress_typeck_results, 818 } = snapshot; 819 820 self.in_snapshot.set(was_in_snapshot); 821 822 self.inner.borrow_mut().commit(undo_snapshot); 823 } 824 825 /// Executes `f` and commit the bindings. 826 #[instrument(skip(self, f), level = "debug")] commit_unconditionally<R, F>(&self, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,827 pub fn commit_unconditionally<R, F>(&self, f: F) -> R 828 where 829 F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, 830 { 831 let snapshot = self.start_snapshot(); 832 let r = f(&snapshot); 833 self.commit_from(snapshot); 834 r 835 } 836 837 /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`. 838 #[instrument(skip(self, f), level = "debug")] commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>,839 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> 840 where 841 F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>, 842 { 843 let snapshot = self.start_snapshot(); 844 let r = f(&snapshot); 845 debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok()); 846 match r { 847 Ok(_) => { 848 self.commit_from(snapshot); 849 } 850 Err(_) => { 851 self.rollback_to("commit_if_ok -- error", snapshot); 852 } 853 } 854 r 855 } 856 857 /// Execute `f` then unroll any bindings it creates. 858 #[instrument(skip(self, f), level = "debug")] probe<R, F>(&self, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,859 pub fn probe<R, F>(&self, f: F) -> R 860 where 861 F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, 862 { 863 let snapshot = self.start_snapshot(); 864 let r = f(&snapshot); 865 self.rollback_to("probe", snapshot); 866 r 867 } 868 869 /// If `should_skip` is true, then execute `f` then unroll any bindings it creates. 870 #[instrument(skip(self, f), level = "debug")] probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,871 pub fn probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R 872 where 873 F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, 874 { 875 let snapshot = self.start_snapshot(); 876 let was_skip_leak_check = self.skip_leak_check.get(); 877 if should_skip { 878 self.skip_leak_check.set(true); 879 } 880 let r = f(&snapshot); 881 self.rollback_to("probe", snapshot); 882 self.skip_leak_check.set(was_skip_leak_check); 883 r 884 } 885 886 /// Scan the constraints produced since `snapshot` began and returns: 887 /// 888 /// - `None` -- if none of them involve "region outlives" constraints 889 /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder 890 /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders region_constraints_added_in_snapshot( &self, snapshot: &CombinedSnapshot<'a, 'tcx>, ) -> Option<bool>891 pub fn region_constraints_added_in_snapshot( 892 &self, 893 snapshot: &CombinedSnapshot<'a, 'tcx>, 894 ) -> Option<bool> { 895 self.inner 896 .borrow_mut() 897 .unwrap_region_constraints() 898 .region_constraints_added_in_snapshot(&snapshot.undo_snapshot) 899 } 900 add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid)901 pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { 902 self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); 903 } 904 can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> where T: at::ToTrace<'tcx>,905 pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> 906 where 907 T: at::ToTrace<'tcx>, 908 { 909 let origin = &ObligationCause::dummy(); 910 self.probe(|_| { 911 self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { 912 // Ignore obligations, since we are unrolling 913 // everything anyway. 914 }) 915 }) 916 } 917 can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> where T: at::ToTrace<'tcx>,918 pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> 919 where 920 T: at::ToTrace<'tcx>, 921 { 922 let origin = &ObligationCause::dummy(); 923 self.probe(|_| { 924 self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { 925 // Ignore obligations, since we are unrolling 926 // everything anyway. 927 }) 928 }) 929 } 930 931 #[instrument(skip(self), level = "debug")] sub_regions( &self, origin: SubregionOrigin<'tcx>, a: ty::Region<'tcx>, b: ty::Region<'tcx>, )932 pub fn sub_regions( 933 &self, 934 origin: SubregionOrigin<'tcx>, 935 a: ty::Region<'tcx>, 936 b: ty::Region<'tcx>, 937 ) { 938 self.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin, a, b); 939 } 940 941 /// Require that the region `r` be equal to one of the regions in 942 /// the set `regions`. 943 #[instrument(skip(self), level = "debug")] member_constraint( &self, opaque_type_def_id: DefId, definition_span: Span, hidden_ty: Ty<'tcx>, region: ty::Region<'tcx>, in_regions: &Lrc<Vec<ty::Region<'tcx>>>, )944 pub fn member_constraint( 945 &self, 946 opaque_type_def_id: DefId, 947 definition_span: Span, 948 hidden_ty: Ty<'tcx>, 949 region: ty::Region<'tcx>, 950 in_regions: &Lrc<Vec<ty::Region<'tcx>>>, 951 ) { 952 self.inner.borrow_mut().unwrap_region_constraints().member_constraint( 953 opaque_type_def_id, 954 definition_span, 955 hidden_ty, 956 region, 957 in_regions, 958 ); 959 } 960 961 /// Processes a `Coerce` predicate from the fulfillment context. 962 /// This is NOT the preferred way to handle coercion, which is to 963 /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`). 964 /// 965 /// This method here is actually a fallback that winds up being 966 /// invoked when `FnCtxt::coerce` encounters unresolved type variables 967 /// and records a coercion predicate. Presently, this method is equivalent 968 /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up 969 /// actually requiring `a <: b`. This is of course a valid coercion, 970 /// but it's not as flexible as `FnCtxt::coerce` would be. 971 /// 972 /// (We may refactor this in the future, but there are a number of 973 /// practical obstacles. Among other things, `FnCtxt::coerce` presently 974 /// records adjustments that are required on the HIR in order to perform 975 /// the coercion, and we don't currently have a way to manage that.) coerce_predicate( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, predicate: ty::PolyCoercePredicate<'tcx>, ) -> Option<InferResult<'tcx, ()>>976 pub fn coerce_predicate( 977 &self, 978 cause: &ObligationCause<'tcx>, 979 param_env: ty::ParamEnv<'tcx>, 980 predicate: ty::PolyCoercePredicate<'tcx>, 981 ) -> Option<InferResult<'tcx, ()>> { 982 let subtype_predicate = predicate.map_bound(|p| ty::SubtypePredicate { 983 a_is_expected: false, // when coercing from `a` to `b`, `b` is expected 984 a: p.a, 985 b: p.b, 986 }); 987 self.subtype_predicate(cause, param_env, subtype_predicate) 988 } 989 subtype_predicate( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, predicate: ty::PolySubtypePredicate<'tcx>, ) -> Option<InferResult<'tcx, ()>>990 pub fn subtype_predicate( 991 &self, 992 cause: &ObligationCause<'tcx>, 993 param_env: ty::ParamEnv<'tcx>, 994 predicate: ty::PolySubtypePredicate<'tcx>, 995 ) -> Option<InferResult<'tcx, ()>> { 996 // Check for two unresolved inference variables, in which case we can 997 // make no progress. This is partly a micro-optimization, but it's 998 // also an opportunity to "sub-unify" the variables. This isn't 999 // *necessary* to prevent cycles, because they would eventually be sub-unified 1000 // anyhow during generalization, but it helps with diagnostics (we can detect 1001 // earlier that they are sub-unified). 1002 // 1003 // Note that we can just skip the binders here because 1004 // type variables can't (at present, at 1005 // least) capture any of the things bound by this binder. 1006 // 1007 // Note that this sub here is not just for diagnostics - it has semantic 1008 // effects as well. 1009 let r_a = self.shallow_resolve(predicate.skip_binder().a); 1010 let r_b = self.shallow_resolve(predicate.skip_binder().b); 1011 match (r_a.kind(), r_b.kind()) { 1012 (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { 1013 self.inner.borrow_mut().type_variables().sub(a_vid, b_vid); 1014 return None; 1015 } 1016 _ => {} 1017 } 1018 1019 Some(self.commit_if_ok(|_snapshot| { 1020 let ty::SubtypePredicate { a_is_expected, a, b } = 1021 self.replace_bound_vars_with_placeholders(predicate); 1022 1023 let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; 1024 1025 Ok(ok.unit()) 1026 })) 1027 } 1028 region_outlives_predicate( &self, cause: &traits::ObligationCause<'tcx>, predicate: ty::PolyRegionOutlivesPredicate<'tcx>, ) -> UnitResult<'tcx>1029 pub fn region_outlives_predicate( 1030 &self, 1031 cause: &traits::ObligationCause<'tcx>, 1032 predicate: ty::PolyRegionOutlivesPredicate<'tcx>, 1033 ) -> UnitResult<'tcx> { 1034 self.commit_if_ok(|_snapshot| { 1035 let ty::OutlivesPredicate(r_a, r_b) = 1036 self.replace_bound_vars_with_placeholders(predicate); 1037 let origin = SubregionOrigin::from_obligation_cause(cause, || { 1038 RelateRegionParamBound(cause.span) 1039 }); 1040 self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` 1041 Ok(()) 1042 }) 1043 } 1044 1045 /// Number of type variables created so far. num_ty_vars(&self) -> usize1046 pub fn num_ty_vars(&self) -> usize { 1047 self.inner.borrow_mut().type_variables().num_vars() 1048 } 1049 next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid1050 pub fn next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid { 1051 self.inner.borrow_mut().type_variables().new_var(self.universe(), origin) 1052 } 1053 next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx>1054 pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { 1055 self.tcx.mk_ty_var(self.next_ty_var_id(origin)) 1056 } 1057 next_ty_var_in_universe( &self, origin: TypeVariableOrigin, universe: ty::UniverseIndex, ) -> Ty<'tcx>1058 pub fn next_ty_var_in_universe( 1059 &self, 1060 origin: TypeVariableOrigin, 1061 universe: ty::UniverseIndex, 1062 ) -> Ty<'tcx> { 1063 let vid = self.inner.borrow_mut().type_variables().new_var(universe, origin); 1064 self.tcx.mk_ty_var(vid) 1065 } 1066 next_const_var( &self, ty: Ty<'tcx>, origin: ConstVariableOrigin, ) -> &'tcx ty::Const<'tcx>1067 pub fn next_const_var( 1068 &self, 1069 ty: Ty<'tcx>, 1070 origin: ConstVariableOrigin, 1071 ) -> &'tcx ty::Const<'tcx> { 1072 self.tcx.mk_const_var(self.next_const_var_id(origin), ty) 1073 } 1074 next_const_var_in_universe( &self, ty: Ty<'tcx>, origin: ConstVariableOrigin, universe: ty::UniverseIndex, ) -> &'tcx ty::Const<'tcx>1075 pub fn next_const_var_in_universe( 1076 &self, 1077 ty: Ty<'tcx>, 1078 origin: ConstVariableOrigin, 1079 universe: ty::UniverseIndex, 1080 ) -> &'tcx ty::Const<'tcx> { 1081 let vid = self 1082 .inner 1083 .borrow_mut() 1084 .const_unification_table() 1085 .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } }); 1086 self.tcx.mk_const_var(vid, ty) 1087 } 1088 next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx>1089 pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> { 1090 self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue { 1091 origin, 1092 val: ConstVariableValue::Unknown { universe: self.universe() }, 1093 }) 1094 } 1095 next_int_var_id(&self) -> IntVid1096 fn next_int_var_id(&self) -> IntVid { 1097 self.inner.borrow_mut().int_unification_table().new_key(None) 1098 } 1099 next_int_var(&self) -> Ty<'tcx>1100 pub fn next_int_var(&self) -> Ty<'tcx> { 1101 self.tcx.mk_int_var(self.next_int_var_id()) 1102 } 1103 next_float_var_id(&self) -> FloatVid1104 fn next_float_var_id(&self) -> FloatVid { 1105 self.inner.borrow_mut().float_unification_table().new_key(None) 1106 } 1107 next_float_var(&self) -> Ty<'tcx>1108 pub fn next_float_var(&self) -> Ty<'tcx> { 1109 self.tcx.mk_float_var(self.next_float_var_id()) 1110 } 1111 1112 /// Creates a fresh region variable with the next available index. 1113 /// The variable will be created in the maximum universe created 1114 /// thus far, allowing it to name any region created thus far. next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx>1115 pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { 1116 self.next_region_var_in_universe(origin, self.universe()) 1117 } 1118 1119 /// Creates a fresh region variable with the next available index 1120 /// in the given universe; typically, you can use 1121 /// `next_region_var` and just use the maximal universe. next_region_var_in_universe( &self, origin: RegionVariableOrigin, universe: ty::UniverseIndex, ) -> ty::Region<'tcx>1122 pub fn next_region_var_in_universe( 1123 &self, 1124 origin: RegionVariableOrigin, 1125 universe: ty::UniverseIndex, 1126 ) -> ty::Region<'tcx> { 1127 let region_var = 1128 self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin); 1129 self.tcx.mk_region(ty::ReVar(region_var)) 1130 } 1131 1132 /// Return the universe that the region `r` was created in. For 1133 /// most regions (e.g., `'static`, named regions from the user, 1134 /// etc) this is the root universe U0. For inference variables or 1135 /// placeholders, however, it will return the universe which which 1136 /// they are associated. universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex1137 pub fn universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex { 1138 self.inner.borrow_mut().unwrap_region_constraints().universe(r) 1139 } 1140 1141 /// Number of region variables created so far. num_region_vars(&self) -> usize1142 pub fn num_region_vars(&self) -> usize { 1143 self.inner.borrow_mut().unwrap_region_constraints().num_region_vars() 1144 } 1145 1146 /// Just a convenient wrapper of `next_region_var` for using during NLL. next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx>1147 pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> { 1148 self.next_region_var(RegionVariableOrigin::Nll(origin)) 1149 } 1150 1151 /// Just a convenient wrapper of `next_region_var` for using during NLL. next_nll_region_var_in_universe( &self, origin: NllRegionVariableOrigin, universe: ty::UniverseIndex, ) -> ty::Region<'tcx>1152 pub fn next_nll_region_var_in_universe( 1153 &self, 1154 origin: NllRegionVariableOrigin, 1155 universe: ty::UniverseIndex, 1156 ) -> ty::Region<'tcx> { 1157 self.next_region_var_in_universe(RegionVariableOrigin::Nll(origin), universe) 1158 } 1159 var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg<'tcx>1160 pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg<'tcx> { 1161 match param.kind { 1162 GenericParamDefKind::Lifetime => { 1163 // Create a region inference variable for the given 1164 // region parameter definition. 1165 self.next_region_var(EarlyBoundRegion(span, param.name)).into() 1166 } 1167 GenericParamDefKind::Type { .. } => { 1168 // Create a type inference variable for the given 1169 // type parameter definition. The substitutions are 1170 // for actual parameters that may be referred to by 1171 // the default of this type parameter, if it exists. 1172 // e.g., `struct Foo<A, B, C = (A, B)>(...);` when 1173 // used in a path such as `Foo::<T, U>::new()` will 1174 // use an inference variable for `C` with `[T, U]` 1175 // as the substitutions for the default, `(T, U)`. 1176 let ty_var_id = self.inner.borrow_mut().type_variables().new_var( 1177 self.universe(), 1178 TypeVariableOrigin { 1179 kind: TypeVariableOriginKind::TypeParameterDefinition( 1180 param.name, 1181 Some(param.def_id), 1182 ), 1183 span, 1184 }, 1185 ); 1186 1187 self.tcx.mk_ty_var(ty_var_id).into() 1188 } 1189 GenericParamDefKind::Const { .. } => { 1190 let origin = ConstVariableOrigin { 1191 kind: ConstVariableOriginKind::ConstParameterDefinition( 1192 param.name, 1193 param.def_id, 1194 ), 1195 span, 1196 }; 1197 let const_var_id = 1198 self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue { 1199 origin, 1200 val: ConstVariableValue::Unknown { universe: self.universe() }, 1201 }); 1202 self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() 1203 } 1204 } 1205 } 1206 1207 /// Given a set of generics defined on a type or impl, returns a substitution mapping each 1208 /// type/region parameter to a fresh inference variable. fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx>1209 pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> { 1210 InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) 1211 } 1212 1213 /// Returns `true` if errors have been reported since this infcx was 1214 /// created. This is sometimes used as a heuristic to skip 1215 /// reporting errors that often occur as a result of earlier 1216 /// errors, but where it's hard to be 100% sure (e.g., unresolved 1217 /// inference variables, regionck errors). is_tainted_by_errors(&self) -> bool1218 pub fn is_tainted_by_errors(&self) -> bool { 1219 debug!( 1220 "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \ 1221 tainted_by_errors_flag={})", 1222 self.tcx.sess.err_count(), 1223 self.err_count_on_creation, 1224 self.tainted_by_errors_flag.get() 1225 ); 1226 1227 if self.tcx.sess.err_count() > self.err_count_on_creation { 1228 return true; // errors reported since this infcx was made 1229 } 1230 self.tainted_by_errors_flag.get() 1231 } 1232 1233 /// Set the "tainted by errors" flag to true. We call this when we 1234 /// observe an error from a prior pass. set_tainted_by_errors(&self)1235 pub fn set_tainted_by_errors(&self) { 1236 debug!("set_tainted_by_errors()"); 1237 self.tainted_by_errors_flag.set(true) 1238 } 1239 1240 /// Process the region constraints and return any any errors that 1241 /// result. After this, no more unification operations should be 1242 /// done -- or the compiler will panic -- but it is legal to use 1243 /// `resolve_vars_if_possible` as well as `fully_resolve`. resolve_regions( &self, region_context: DefId, outlives_env: &OutlivesEnvironment<'tcx>, mode: RegionckMode, ) -> Vec<RegionResolutionError<'tcx>>1244 pub fn resolve_regions( 1245 &self, 1246 region_context: DefId, 1247 outlives_env: &OutlivesEnvironment<'tcx>, 1248 mode: RegionckMode, 1249 ) -> Vec<RegionResolutionError<'tcx>> { 1250 let (var_infos, data) = { 1251 let mut inner = self.inner.borrow_mut(); 1252 let inner = &mut *inner; 1253 assert!( 1254 self.is_tainted_by_errors() || inner.region_obligations.is_empty(), 1255 "region_obligations not empty: {:#?}", 1256 inner.region_obligations 1257 ); 1258 inner 1259 .region_constraint_storage 1260 .take() 1261 .expect("regions already resolved") 1262 .with_log(&mut inner.undo_log) 1263 .into_infos_and_data() 1264 }; 1265 1266 let region_rels = 1267 &RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map()); 1268 1269 let (lexical_region_resolutions, errors) = 1270 lexical_region_resolve::resolve(region_rels, var_infos, data, mode); 1271 1272 let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); 1273 assert!(old_value.is_none()); 1274 1275 errors 1276 } 1277 1278 /// Process the region constraints and report any errors that 1279 /// result. After this, no more unification operations should be 1280 /// done -- or the compiler will panic -- but it is legal to use 1281 /// `resolve_vars_if_possible` as well as `fully_resolve`. resolve_regions_and_report_errors( &self, region_context: DefId, outlives_env: &OutlivesEnvironment<'tcx>, mode: RegionckMode, )1282 pub fn resolve_regions_and_report_errors( 1283 &self, 1284 region_context: DefId, 1285 outlives_env: &OutlivesEnvironment<'tcx>, 1286 mode: RegionckMode, 1287 ) { 1288 let errors = self.resolve_regions(region_context, outlives_env, mode); 1289 1290 if !self.is_tainted_by_errors() { 1291 // As a heuristic, just skip reporting region errors 1292 // altogether if other errors have been reported while 1293 // this infcx was in use. This is totally hokey but 1294 // otherwise we have a hard time separating legit region 1295 // errors from silly ones. 1296 self.report_region_errors(&errors); 1297 } 1298 } 1299 1300 /// Obtains (and clears) the current set of region 1301 /// constraints. The inference context is still usable: further 1302 /// unifications will simply add new constraints. 1303 /// 1304 /// This method is not meant to be used with normal lexical region 1305 /// resolution. Rather, it is used in the NLL mode as a kind of 1306 /// interim hack: basically we run normal type-check and generate 1307 /// region constraints as normal, but then we take them and 1308 /// translate them into the form that the NLL solver 1309 /// understands. See the NLL module for mode details. take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx>1310 pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> { 1311 assert!( 1312 self.inner.borrow().region_obligations.is_empty(), 1313 "region_obligations not empty: {:#?}", 1314 self.inner.borrow().region_obligations 1315 ); 1316 1317 self.inner.borrow_mut().unwrap_region_constraints().take_and_reset_data() 1318 } 1319 1320 /// Gives temporary access to the region constraint data. with_region_constraints<R>( &self, op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, ) -> R1321 pub fn with_region_constraints<R>( 1322 &self, 1323 op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, 1324 ) -> R { 1325 let mut inner = self.inner.borrow_mut(); 1326 op(inner.unwrap_region_constraints().data()) 1327 } 1328 region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin1329 pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin { 1330 let mut inner = self.inner.borrow_mut(); 1331 let inner = &mut *inner; 1332 inner 1333 .region_constraint_storage 1334 .as_mut() 1335 .expect("regions already resolved") 1336 .with_log(&mut inner.undo_log) 1337 .var_origin(vid) 1338 } 1339 1340 /// Takes ownership of the list of variable regions. This implies 1341 /// that all the region constraints have already been taken, and 1342 /// hence that `resolve_regions_and_report_errors` can never be 1343 /// called. This is used only during NLL processing to "hand off" ownership 1344 /// of the set of region variables into the NLL region context. take_region_var_origins(&self) -> VarInfos1345 pub fn take_region_var_origins(&self) -> VarInfos { 1346 let mut inner = self.inner.borrow_mut(); 1347 let (var_infos, data) = inner 1348 .region_constraint_storage 1349 .take() 1350 .expect("regions already resolved") 1351 .with_log(&mut inner.undo_log) 1352 .into_infos_and_data(); 1353 assert!(data.is_empty()); 1354 var_infos 1355 } 1356 ty_to_string(&self, t: Ty<'tcx>) -> String1357 pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { 1358 self.resolve_vars_if_possible(t).to_string() 1359 } 1360 1361 /// If `TyVar(vid)` resolves to a type, return that type. Else, return the 1362 /// universe index of `TyVar(vid)`. probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex>1363 pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> { 1364 use self::type_variable::TypeVariableValue; 1365 1366 match self.inner.borrow_mut().type_variables().probe(vid) { 1367 TypeVariableValue::Known { value } => Ok(value), 1368 TypeVariableValue::Unknown { universe } => Err(universe), 1369 } 1370 } 1371 1372 /// Resolve any type variables found in `value` -- but only one 1373 /// level. So, if the variable `?X` is bound to some type 1374 /// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may 1375 /// itself be bound to a type). 1376 /// 1377 /// Useful when you only need to inspect the outermost level of 1378 /// the type and don't care about nested types (or perhaps you 1379 /// will be resolving them as well, e.g. in a loop). shallow_resolve<T>(&self, value: T) -> T where T: TypeFoldable<'tcx>,1380 pub fn shallow_resolve<T>(&self, value: T) -> T 1381 where 1382 T: TypeFoldable<'tcx>, 1383 { 1384 value.fold_with(&mut ShallowResolver { infcx: self }) 1385 } 1386 root_var(&self, var: ty::TyVid) -> ty::TyVid1387 pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { 1388 self.inner.borrow_mut().type_variables().root_var(var) 1389 } 1390 1391 /// Where possible, replaces type/const variables in 1392 /// `value` with their final value. Note that region variables 1393 /// are unaffected. If a type/const variable has not been unified, it 1394 /// is left as is. This is an idempotent operation that does 1395 /// not affect inference state in any way and so you can do it 1396 /// at will. resolve_vars_if_possible<T>(&self, value: T) -> T where T: TypeFoldable<'tcx>,1397 pub fn resolve_vars_if_possible<T>(&self, value: T) -> T 1398 where 1399 T: TypeFoldable<'tcx>, 1400 { 1401 if !value.needs_infer() { 1402 return value; // Avoid duplicated subst-folding. 1403 } 1404 let mut r = resolve::OpportunisticVarResolver::new(self); 1405 value.fold_with(&mut r) 1406 } 1407 1408 /// Returns the first unresolved variable contained in `T`. In the 1409 /// process of visiting `T`, this will resolve (where possible) 1410 /// type variables in `T`, but it never constructs the final, 1411 /// resolved type, so it's more efficient than 1412 /// `resolve_vars_if_possible()`. unresolved_type_vars<T>(&self, value: &T) -> Option<(Ty<'tcx>, Option<Span>)> where T: TypeFoldable<'tcx>,1413 pub fn unresolved_type_vars<T>(&self, value: &T) -> Option<(Ty<'tcx>, Option<Span>)> 1414 where 1415 T: TypeFoldable<'tcx>, 1416 { 1417 value.visit_with(&mut resolve::UnresolvedTypeFinder::new(self)).break_value() 1418 } 1419 probe_const_var( &self, vid: ty::ConstVid<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex>1420 pub fn probe_const_var( 1421 &self, 1422 vid: ty::ConstVid<'tcx>, 1423 ) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> { 1424 match self.inner.borrow_mut().const_unification_table().probe_value(vid).val { 1425 ConstVariableValue::Known { value } => Ok(value), 1426 ConstVariableValue::Unknown { universe } => Err(universe), 1427 } 1428 } 1429 fully_resolve<T: TypeFoldable<'tcx>>(&self, value: T) -> FixupResult<'tcx, T>1430 pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: T) -> FixupResult<'tcx, T> { 1431 /*! 1432 * Attempts to resolve all type/region/const variables in 1433 * `value`. Region inference must have been run already (e.g., 1434 * by calling `resolve_regions_and_report_errors`). If some 1435 * variable was never unified, an `Err` results. 1436 * 1437 * This method is idempotent, but it not typically not invoked 1438 * except during the writeback phase. 1439 */ 1440 1441 resolve::fully_resolve(self, value) 1442 } 1443 1444 // [Note-Type-error-reporting] 1445 // An invariant is that anytime the expected or actual type is Error (the special 1446 // error type, meaning that an error occurred when typechecking this expression), 1447 // this is a derived error. The error cascaded from another error (that was already 1448 // reported), so it's not useful to display it to the user. 1449 // The following methods implement this logic. 1450 // They check if either the actual or expected type is Error, and don't print the error 1451 // in this case. The typechecker should only ever report type errors involving mismatched 1452 // types using one of these methods, and should not call span_err directly for such 1453 // errors. 1454 type_error_struct_with_diag<M>( &self, sp: Span, mk_diag: M, actual_ty: Ty<'tcx>, ) -> DiagnosticBuilder<'tcx> where M: FnOnce(String) -> DiagnosticBuilder<'tcx>,1455 pub fn type_error_struct_with_diag<M>( 1456 &self, 1457 sp: Span, 1458 mk_diag: M, 1459 actual_ty: Ty<'tcx>, 1460 ) -> DiagnosticBuilder<'tcx> 1461 where 1462 M: FnOnce(String) -> DiagnosticBuilder<'tcx>, 1463 { 1464 let actual_ty = self.resolve_vars_if_possible(actual_ty); 1465 debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); 1466 1467 // Don't report an error if actual type is `Error`. 1468 if actual_ty.references_error() { 1469 return self.tcx.sess.diagnostic().struct_dummy(); 1470 } 1471 1472 mk_diag(self.ty_to_string(actual_ty)) 1473 } 1474 report_mismatched_types( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, ) -> DiagnosticBuilder<'tcx>1475 pub fn report_mismatched_types( 1476 &self, 1477 cause: &ObligationCause<'tcx>, 1478 expected: Ty<'tcx>, 1479 actual: Ty<'tcx>, 1480 err: TypeError<'tcx>, 1481 ) -> DiagnosticBuilder<'tcx> { 1482 let trace = TypeTrace::types(cause, true, expected, actual); 1483 self.report_and_explain_type_error(trace, &err) 1484 } 1485 report_mismatched_consts( &self, cause: &ObligationCause<'tcx>, expected: &'tcx ty::Const<'tcx>, actual: &'tcx ty::Const<'tcx>, err: TypeError<'tcx>, ) -> DiagnosticBuilder<'tcx>1486 pub fn report_mismatched_consts( 1487 &self, 1488 cause: &ObligationCause<'tcx>, 1489 expected: &'tcx ty::Const<'tcx>, 1490 actual: &'tcx ty::Const<'tcx>, 1491 err: TypeError<'tcx>, 1492 ) -> DiagnosticBuilder<'tcx> { 1493 let trace = TypeTrace::consts(cause, true, expected, actual); 1494 self.report_and_explain_type_error(trace, &err) 1495 } 1496 replace_bound_vars_with_fresh_vars<T>( &self, span: Span, lbrct: LateBoundRegionConversionTime, value: ty::Binder<'tcx, T>, ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>) where T: TypeFoldable<'tcx>,1497 pub fn replace_bound_vars_with_fresh_vars<T>( 1498 &self, 1499 span: Span, 1500 lbrct: LateBoundRegionConversionTime, 1501 value: ty::Binder<'tcx, T>, 1502 ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>) 1503 where 1504 T: TypeFoldable<'tcx>, 1505 { 1506 let fld_r = 1507 |br: ty::BoundRegion| self.next_region_var(LateBoundRegion(span, br.kind, lbrct)); 1508 let fld_t = |_| { 1509 self.next_ty_var(TypeVariableOrigin { 1510 kind: TypeVariableOriginKind::MiscVariable, 1511 span, 1512 }) 1513 }; 1514 let fld_c = |_, ty| { 1515 self.next_const_var( 1516 ty, 1517 ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, 1518 ) 1519 }; 1520 self.tcx.replace_bound_vars(value, fld_r, fld_t, fld_c) 1521 } 1522 1523 /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method. verify_generic_bound( &self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, a: ty::Region<'tcx>, bound: VerifyBound<'tcx>, )1524 pub fn verify_generic_bound( 1525 &self, 1526 origin: SubregionOrigin<'tcx>, 1527 kind: GenericKind<'tcx>, 1528 a: ty::Region<'tcx>, 1529 bound: VerifyBound<'tcx>, 1530 ) { 1531 debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, a, bound); 1532 1533 self.inner 1534 .borrow_mut() 1535 .unwrap_region_constraints() 1536 .verify_generic_bound(origin, kind, a, bound); 1537 } 1538 1539 /// Obtains the latest type of the given closure; this may be a 1540 /// closure in the current function, in which case its 1541 /// `ClosureKind` may not yet be known. closure_kind(&self, closure_substs: SubstsRef<'tcx>) -> Option<ty::ClosureKind>1542 pub fn closure_kind(&self, closure_substs: SubstsRef<'tcx>) -> Option<ty::ClosureKind> { 1543 let closure_kind_ty = closure_substs.as_closure().kind_ty(); 1544 let closure_kind_ty = self.shallow_resolve(closure_kind_ty); 1545 closure_kind_ty.to_opt_closure_kind() 1546 } 1547 1548 /// Clears the selection, evaluation, and projection caches. This is useful when 1549 /// repeatedly attempting to select an `Obligation` while changing only 1550 /// its `ParamEnv`, since `FulfillmentContext` doesn't use probing. clear_caches(&self)1551 pub fn clear_caches(&self) { 1552 self.selection_cache.clear(); 1553 self.evaluation_cache.clear(); 1554 self.inner.borrow_mut().projection_cache().clear(); 1555 } 1556 universe(&self) -> ty::UniverseIndex1557 pub fn universe(&self) -> ty::UniverseIndex { 1558 self.universe.get() 1559 } 1560 1561 /// Creates and return a fresh universe that extends all previous 1562 /// universes. Updates `self.universe` to that new universe. create_next_universe(&self) -> ty::UniverseIndex1563 pub fn create_next_universe(&self) -> ty::UniverseIndex { 1564 let u = self.universe.get().next_universe(); 1565 self.universe.set(u); 1566 u 1567 } 1568 1569 /// Resolves and evaluates a constant. 1570 /// 1571 /// The constant can be located on a trait like `<A as B>::C`, in which case the given 1572 /// substitutions and environment are used to resolve the constant. Alternatively if the 1573 /// constant has generic parameters in scope the substitutions are used to evaluate the value of 1574 /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count 1575 /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still 1576 /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is 1577 /// returned. 1578 /// 1579 /// This handles inferences variables within both `param_env` and `substs` by 1580 /// performing the operation on their respective canonical forms. const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, unevaluated: ty::Unevaluated<'tcx>, span: Option<Span>, ) -> EvalToConstValueResult<'tcx>1581 pub fn const_eval_resolve( 1582 &self, 1583 param_env: ty::ParamEnv<'tcx>, 1584 unevaluated: ty::Unevaluated<'tcx>, 1585 span: Option<Span>, 1586 ) -> EvalToConstValueResult<'tcx> { 1587 let mut original_values = OriginalQueryValues::default(); 1588 let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values); 1589 1590 let (param_env, unevaluated) = canonical.value; 1591 // The return value is the evaluated value which doesn't contain any reference to inference 1592 // variables, thus we don't need to substitute back the original values. 1593 self.tcx.const_eval_resolve(param_env, unevaluated, span) 1594 } 1595 1596 /// If `typ` is a type variable of some kind, resolve it one level 1597 /// (but do not resolve types found in the result). If `typ` is 1598 /// not a type variable, just return it unmodified. 1599 // FIXME(eddyb) inline into `ShallowResolver::visit_ty`. shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx>1600 fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> { 1601 match *typ.kind() { 1602 ty::Infer(ty::TyVar(v)) => { 1603 // Not entirely obvious: if `typ` is a type variable, 1604 // it can be resolved to an int/float variable, which 1605 // can then be recursively resolved, hence the 1606 // recursion. Note though that we prevent type 1607 // variables from unifying to other type variables 1608 // directly (though they may be embedded 1609 // structurally), and we prevent cycles in any case, 1610 // so this recursion should always be of very limited 1611 // depth. 1612 // 1613 // Note: if these two lines are combined into one we get 1614 // dynamic borrow errors on `self.inner`. 1615 let known = self.inner.borrow_mut().type_variables().probe(v).known(); 1616 known.map_or(typ, |t| self.shallow_resolve_ty(t)) 1617 } 1618 1619 ty::Infer(ty::IntVar(v)) => self 1620 .inner 1621 .borrow_mut() 1622 .int_unification_table() 1623 .probe_value(v) 1624 .map(|v| v.to_type(self.tcx)) 1625 .unwrap_or(typ), 1626 1627 ty::Infer(ty::FloatVar(v)) => self 1628 .inner 1629 .borrow_mut() 1630 .float_unification_table() 1631 .probe_value(v) 1632 .map(|v| v.to_type(self.tcx)) 1633 .unwrap_or(typ), 1634 1635 _ => typ, 1636 } 1637 } 1638 1639 /// `ty_or_const_infer_var_changed` is equivalent to one of these two: 1640 /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`) 1641 /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`) 1642 /// 1643 /// However, `ty_or_const_infer_var_changed` is more efficient. It's always 1644 /// inlined, despite being large, because it has only two call sites that 1645 /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on` 1646 /// inference variables), and it handles both `Ty` and `ty::Const` without 1647 /// having to resort to storing full `GenericArg`s in `stalled_on`. 1648 #[inline(always)] ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool1649 pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool { 1650 match infer_var { 1651 TyOrConstInferVar::Ty(v) => { 1652 use self::type_variable::TypeVariableValue; 1653 1654 // If `inlined_probe` returns a `Known` value, it never equals 1655 // `ty::Infer(ty::TyVar(v))`. 1656 match self.inner.borrow_mut().type_variables().inlined_probe(v) { 1657 TypeVariableValue::Unknown { .. } => false, 1658 TypeVariableValue::Known { .. } => true, 1659 } 1660 } 1661 1662 TyOrConstInferVar::TyInt(v) => { 1663 // If `inlined_probe_value` returns a value it's always a 1664 // `ty::Int(_)` or `ty::UInt(_)`, which never matches a 1665 // `ty::Infer(_)`. 1666 self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_some() 1667 } 1668 1669 TyOrConstInferVar::TyFloat(v) => { 1670 // If `probe_value` returns a value it's always a 1671 // `ty::Float(_)`, which never matches a `ty::Infer(_)`. 1672 // 1673 // Not `inlined_probe_value(v)` because this call site is colder. 1674 self.inner.borrow_mut().float_unification_table().probe_value(v).is_some() 1675 } 1676 1677 TyOrConstInferVar::Const(v) => { 1678 // If `probe_value` returns a `Known` value, it never equals 1679 // `ty::ConstKind::Infer(ty::InferConst::Var(v))`. 1680 // 1681 // Not `inlined_probe_value(v)` because this call site is colder. 1682 match self.inner.borrow_mut().const_unification_table().probe_value(v).val { 1683 ConstVariableValue::Unknown { .. } => false, 1684 ConstVariableValue::Known { .. } => true, 1685 } 1686 } 1687 } 1688 } 1689 } 1690 1691 /// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently 1692 /// used only for `traits::fulfill`'s list of `stalled_on` inference variables. 1693 #[derive(Copy, Clone, Debug)] 1694 pub enum TyOrConstInferVar<'tcx> { 1695 /// Equivalent to `ty::Infer(ty::TyVar(_))`. 1696 Ty(TyVid), 1697 /// Equivalent to `ty::Infer(ty::IntVar(_))`. 1698 TyInt(IntVid), 1699 /// Equivalent to `ty::Infer(ty::FloatVar(_))`. 1700 TyFloat(FloatVid), 1701 1702 /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`. 1703 Const(ConstVid<'tcx>), 1704 } 1705 1706 impl TyOrConstInferVar<'tcx> { 1707 /// Tries to extract an inference variable from a type or a constant, returns `None` 1708 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and 1709 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option<Self>1710 pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option<Self> { 1711 match arg.unpack() { 1712 GenericArgKind::Type(ty) => Self::maybe_from_ty(ty), 1713 GenericArgKind::Const(ct) => Self::maybe_from_const(ct), 1714 GenericArgKind::Lifetime(_) => None, 1715 } 1716 } 1717 1718 /// Tries to extract an inference variable from a type, returns `None` 1719 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`). maybe_from_ty(ty: Ty<'tcx>) -> Option<Self>1720 pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option<Self> { 1721 match *ty.kind() { 1722 ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)), 1723 ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)), 1724 ty::Infer(ty::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)), 1725 _ => None, 1726 } 1727 } 1728 1729 /// Tries to extract an inference variable from a constant, returns `None` 1730 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self>1731 pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self> { 1732 match ct.val { 1733 ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)), 1734 _ => None, 1735 } 1736 } 1737 } 1738 1739 struct ShallowResolver<'a, 'tcx> { 1740 infcx: &'a InferCtxt<'a, 'tcx>, 1741 } 1742 1743 impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { tcx<'b>(&'b self) -> TyCtxt<'tcx>1744 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { 1745 self.infcx.tcx 1746 } 1747 fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx>1748 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { 1749 self.infcx.shallow_resolve_ty(ty) 1750 } 1751 fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>1752 fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { 1753 if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct { 1754 self.infcx 1755 .inner 1756 .borrow_mut() 1757 .const_unification_table() 1758 .probe_value(*vid) 1759 .val 1760 .known() 1761 .unwrap_or(ct) 1762 } else { 1763 ct 1764 } 1765 } 1766 } 1767 1768 impl<'tcx> TypeTrace<'tcx> { span(&self) -> Span1769 pub fn span(&self) -> Span { 1770 self.cause.span 1771 } 1772 types( cause: &ObligationCause<'tcx>, a_is_expected: bool, a: Ty<'tcx>, b: Ty<'tcx>, ) -> TypeTrace<'tcx>1773 pub fn types( 1774 cause: &ObligationCause<'tcx>, 1775 a_is_expected: bool, 1776 a: Ty<'tcx>, 1777 b: Ty<'tcx>, 1778 ) -> TypeTrace<'tcx> { 1779 TypeTrace { cause: cause.clone(), values: Types(ExpectedFound::new(a_is_expected, a, b)) } 1780 } 1781 consts( cause: &ObligationCause<'tcx>, a_is_expected: bool, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> TypeTrace<'tcx>1782 pub fn consts( 1783 cause: &ObligationCause<'tcx>, 1784 a_is_expected: bool, 1785 a: &'tcx ty::Const<'tcx>, 1786 b: &'tcx ty::Const<'tcx>, 1787 ) -> TypeTrace<'tcx> { 1788 TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) } 1789 } 1790 } 1791 1792 impl<'tcx> SubregionOrigin<'tcx> { span(&self) -> Span1793 pub fn span(&self) -> Span { 1794 match *self { 1795 Subtype(ref a) => a.span(), 1796 RelateObjectBound(a) => a, 1797 RelateParamBound(a, ..) => a, 1798 RelateRegionParamBound(a) => a, 1799 Reborrow(a) => a, 1800 ReborrowUpvar(a, _) => a, 1801 DataBorrowed(_, a) => a, 1802 ReferenceOutlivesReferent(_, a) => a, 1803 CompareImplMethodObligation { span, .. } => span, 1804 CompareImplTypeObligation { span, .. } => span, 1805 } 1806 } 1807 from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default: F) -> Self where F: FnOnce() -> Self,1808 pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default: F) -> Self 1809 where 1810 F: FnOnce() -> Self, 1811 { 1812 match cause.code { 1813 traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) => { 1814 SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span) 1815 } 1816 1817 traits::ObligationCauseCode::CompareImplMethodObligation { 1818 impl_item_def_id, 1819 trait_item_def_id, 1820 } => SubregionOrigin::CompareImplMethodObligation { 1821 span: cause.span, 1822 impl_item_def_id, 1823 trait_item_def_id, 1824 }, 1825 1826 traits::ObligationCauseCode::CompareImplTypeObligation { 1827 impl_item_def_id, 1828 trait_item_def_id, 1829 } => SubregionOrigin::CompareImplTypeObligation { 1830 span: cause.span, 1831 impl_item_def_id, 1832 trait_item_def_id, 1833 }, 1834 1835 _ => default(), 1836 } 1837 } 1838 } 1839 1840 impl RegionVariableOrigin { span(&self) -> Span1841 pub fn span(&self) -> Span { 1842 match *self { 1843 MiscVariable(a) 1844 | PatternRegion(a) 1845 | AddrOfRegion(a) 1846 | Autoref(a) 1847 | Coercion(a) 1848 | EarlyBoundRegion(a, ..) 1849 | LateBoundRegion(a, ..) 1850 | UpvarRegion(_, a) => a, 1851 Nll(..) => bug!("NLL variable used with `span`"), 1852 } 1853 } 1854 } 1855 1856 impl<'tcx> fmt::Debug for RegionObligation<'tcx> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1857 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1858 write!( 1859 f, 1860 "RegionObligation(sub_region={:?}, sup_type={:?})", 1861 self.sub_region, self.sup_type 1862 ) 1863 } 1864 } 1865