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
::*;
8 use self::opaque_types
::OpaqueTypeMap
;
9 pub(crate) use self::undo_log
::{InferCtxtUndoLogs, Snapshot, UndoLog}
;
11 use crate::traits
::{self, ObligationCause, PredicateObligations, TraitEngine}
;
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
;
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
;
37 use std
::cell
::{Cell, Ref, RefCell}
;
38 use std
::collections
::BTreeMap
;
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
,
49 use self::type_variable
::{Diverging, TypeVariableOrigin, TypeVariableOriginKind}
;
55 pub mod error_reporting
;
62 mod lexical_region_resolve
;
67 pub mod region_constraints
;
70 pub mod type_variable
;
73 use crate::infer
::canonical
::OriginalQueryValues
;
74 pub use rustc_middle
::infer
::unify_key
;
78 pub struct InferOk
<'tcx
, T
> {
80 pub obligations
: PredicateObligations
<'tcx
>,
82 pub type InferResult
<'tcx
, T
> = Result
<InferOk
<'tcx
, T
>, TypeError
<'tcx
>>;
84 pub type Bound
<T
> = Option
<T
>;
85 pub type UnitResult
<'tcx
> = RelateResult
<'tcx
, ()>; // "unify result"
86 pub type FixupResult
<'tcx
, T
> = Result
<T
, FixupError
<'tcx
>>; // "fixup result"
88 pub(crate) type UnificationTable
<'a
, 'tcx
, T
> = ut
::UnificationTable
<
89 ut
::InPlace
<T
, &'a
mut ut
::UnificationStorage
<T
>, &'a
mut InferCtxtUndoLogs
<'tcx
>>,
92 /// How we should handle region solving.
94 /// This is used so that the region values inferred by HIR region solving are
95 /// not exposed, and so that we can avoid doing work in HIR typeck that MIR
96 /// typeck will also do.
97 #[derive(Copy, Clone, Debug)]
98 pub enum RegionckMode
{
99 /// The default mode: report region errors, don't erase regions.
101 /// Erase the results of region after solving.
103 /// A flag that is used to suppress region errors, when we are doing
104 /// region checks that the NLL borrow checker will also do -- it might
106 suppress_errors
: bool
,
110 impl Default
for RegionckMode
{
111 fn default() -> Self {
117 /// Indicates that the MIR borrowck will repeat these region
118 /// checks, so we should ignore errors if NLL is (unconditionally)
120 pub fn for_item_body(tcx
: TyCtxt
<'_
>) -> Self {
121 // FIXME(Centril): Once we actually remove `::Migrate` also make
122 // this always `true` and then proceed to eliminate the dead code.
123 match tcx
.borrowck_mode() {
124 // If we're on Migrate mode, report AST region errors
125 BorrowckMode
::Migrate
=> RegionckMode
::Erase { suppress_errors: false }
,
127 // If we're on MIR, don't report AST region errors as they should be reported by NLL
128 BorrowckMode
::Mir
=> RegionckMode
::Erase { suppress_errors: true }
,
133 /// This type contains all the things within `InferCtxt` that sit within a
134 /// `RefCell` and are involved with taking/rolling back snapshots. Snapshot
135 /// operations are hot enough that we want only one call to `borrow_mut` per
136 /// call to `start_snapshot` and `rollback_to`.
137 pub struct InferCtxtInner
<'tcx
> {
138 /// Cache for projections. This cache is snapshotted along with the infcx.
140 /// Public so that `traits::project` can use it.
141 pub projection_cache
: traits
::ProjectionCacheStorage
<'tcx
>,
143 /// We instantiate `UnificationTable` with `bounds<Ty>` because the types
144 /// that might instantiate a general type variable have an order,
145 /// represented by its upper and lower bounds.
146 type_variable_storage
: type_variable
::TypeVariableStorage
<'tcx
>,
148 /// Map from const parameter variable to the kind of const it represents.
149 const_unification_storage
: ut
::UnificationTableStorage
<ty
::ConstVid
<'tcx
>>,
151 /// Map from integral variable to the kind of integer it represents.
152 int_unification_storage
: ut
::UnificationTableStorage
<ty
::IntVid
>,
154 /// Map from floating variable to the kind of float it represents.
155 float_unification_storage
: ut
::UnificationTableStorage
<ty
::FloatVid
>,
157 /// Tracks the set of region variables and the constraints between them.
158 /// This is initially `Some(_)` but when
159 /// `resolve_regions_and_report_errors` is invoked, this gets set to `None`
160 /// -- further attempts to perform unification, etc., may fail if new
161 /// region constraints would've been added.
162 region_constraint_storage
: Option
<RegionConstraintStorage
<'tcx
>>,
164 /// A set of constraints that regionck must validate. Each
165 /// constraint has the form `T:'a`, meaning "some type `T` must
166 /// outlive the lifetime 'a". These constraints derive from
167 /// instantiated type parameters. So if you had a struct defined
170 /// struct Foo<T:'static> { ... }
172 /// then in some expression `let x = Foo { ... }` it will
173 /// instantiate the type parameter `T` with a fresh type `$0`. At
174 /// the same time, it will record a region obligation of
175 /// `$0:'static`. This will get checked later by regionck. (We
176 /// can't generally check these things right away because we have
177 /// to wait until types are resolved.)
179 /// These are stored in a map keyed to the id of the innermost
180 /// enclosing fn body / static initializer expression. This is
181 /// because the location where the obligation was incurred can be
182 /// relevant with respect to which sublifetime assumptions are in
183 /// place. The reason that we store under the fn-id, and not
184 /// something more fine-grained, is so that it is easier for
185 /// regionck to be sure that it has found *all* the region
186 /// obligations (otherwise, it's easy to fail to walk to a
187 /// particular node-id).
189 /// Before running `resolve_regions_and_report_errors`, the creator
190 /// of the inference context is expected to invoke
191 /// `process_region_obligations` (defined in `self::region_obligations`)
192 /// for each body-id in this map, which will process the
193 /// obligations within. This is expected to be done 'late enough'
194 /// that all type inference variables have been bound and so forth.
195 region_obligations
: Vec
<(hir
::HirId
, RegionObligation
<'tcx
>)>,
197 undo_log
: InferCtxtUndoLogs
<'tcx
>,
199 // Opaque types found in explicit return types and their
200 // associated fresh inference variable. Writeback resolves these
201 // variables to get the concrete type, which can be used to
202 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
203 pub opaque_types
: OpaqueTypeMap
<'tcx
>,
205 /// A map from inference variables created from opaque
206 /// type instantiations (`ty::Infer`) to the actual opaque
207 /// type (`ty::Opaque`). Used during fallback to map unconstrained
208 /// opaque type inference variables to their corresponding
210 pub opaque_types_vars
: FxHashMap
<Ty
<'tcx
>, Ty
<'tcx
>>,
213 impl<'tcx
> InferCtxtInner
<'tcx
> {
214 fn new() -> InferCtxtInner
<'tcx
> {
216 projection_cache
: Default
::default(),
217 type_variable_storage
: type_variable
::TypeVariableStorage
::new(),
218 undo_log
: InferCtxtUndoLogs
::default(),
219 const_unification_storage
: ut
::UnificationTableStorage
::new(),
220 int_unification_storage
: ut
::UnificationTableStorage
::new(),
221 float_unification_storage
: ut
::UnificationTableStorage
::new(),
222 region_constraint_storage
: Some(RegionConstraintStorage
::new()),
223 region_obligations
: vec
![],
224 opaque_types
: Default
::default(),
225 opaque_types_vars
: Default
::default(),
230 pub fn region_obligations(&self) -> &[(hir
::HirId
, RegionObligation
<'tcx
>)] {
231 &self.region_obligations
235 pub fn projection_cache(&mut self) -> traits
::ProjectionCache
<'_
, 'tcx
> {
236 self.projection_cache
.with_log(&mut self.undo_log
)
240 fn type_variables(&mut self) -> type_variable
::TypeVariableTable
<'_
, 'tcx
> {
241 self.type_variable_storage
.with_log(&mut self.undo_log
)
245 fn int_unification_table(
247 ) -> ut
::UnificationTable
<
250 &mut ut
::UnificationStorage
<ty
::IntVid
>,
251 &mut InferCtxtUndoLogs
<'tcx
>,
254 self.int_unification_storage
.with_log(&mut self.undo_log
)
258 fn float_unification_table(
260 ) -> ut
::UnificationTable
<
263 &mut ut
::UnificationStorage
<ty
::FloatVid
>,
264 &mut InferCtxtUndoLogs
<'tcx
>,
267 self.float_unification_storage
.with_log(&mut self.undo_log
)
271 fn const_unification_table(
273 ) -> ut
::UnificationTable
<
276 &mut ut
::UnificationStorage
<ty
::ConstVid
<'tcx
>>,
277 &mut InferCtxtUndoLogs
<'tcx
>,
280 self.const_unification_storage
.with_log(&mut self.undo_log
)
284 pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector
<'_
, 'tcx
> {
285 self.region_constraint_storage
287 .expect("region constraints already solved")
288 .with_log(&mut self.undo_log
)
292 pub struct InferCtxt
<'a
, 'tcx
> {
293 pub tcx
: TyCtxt
<'tcx
>,
295 /// The `DefId` of the item in whose context we are performing inference or typeck.
296 /// It is used to check whether an opaque type use is a defining use.
297 pub defining_use_anchor
: LocalDefId
,
299 /// During type-checking/inference of a body, `in_progress_typeck_results`
300 /// contains a reference to the typeck results being built up, which are
301 /// used for reading closure kinds/signatures as they are inferred,
302 /// and for error reporting logic to read arbitrary node types.
303 pub in_progress_typeck_results
: Option
<&'a RefCell
<ty
::TypeckResults
<'tcx
>>>,
305 pub inner
: RefCell
<InferCtxtInner
<'tcx
>>,
307 /// If set, this flag causes us to skip the 'leak check' during
308 /// higher-ranked subtyping operations. This flag is a temporary one used
309 /// to manage the removal of the leak-check: for the time being, we still run the
310 /// leak-check, but we issue warnings. This flag can only be set to true
311 /// when entering a snapshot.
312 skip_leak_check
: Cell
<bool
>,
314 /// Once region inference is done, the values for each variable.
315 lexical_region_resolutions
: RefCell
<Option
<LexicalRegionResolutions
<'tcx
>>>,
317 /// Caches the results of trait selection. This cache is used
318 /// for things that have to do with the parameters in scope.
319 pub selection_cache
: select
::SelectionCache
<'tcx
>,
321 /// Caches the results of trait evaluation.
322 pub evaluation_cache
: select
::EvaluationCache
<'tcx
>,
324 /// the set of predicates on which errors have been reported, to
325 /// avoid reporting the same error twice.
326 pub reported_trait_errors
: RefCell
<FxHashMap
<Span
, Vec
<ty
::Predicate
<'tcx
>>>>,
328 pub reported_closure_mismatch
: RefCell
<FxHashSet
<(Span
, Option
<Span
>)>>,
330 /// When an error occurs, we want to avoid reporting "derived"
331 /// errors that are due to this original failure. Normally, we
332 /// handle this with the `err_count_on_creation` count, which
333 /// basically just tracks how many errors were reported when we
334 /// started type-checking a fn and checks to see if any new errors
335 /// have been reported since then. Not great, but it works.
337 /// However, when errors originated in other passes -- notably
338 /// resolve -- this heuristic breaks down. Therefore, we have this
339 /// auxiliary flag that one can set whenever one creates a
340 /// type-error that is due to an error in a prior pass.
342 /// Don't read this flag directly, call `is_tainted_by_errors()`
343 /// and `set_tainted_by_errors()`.
344 tainted_by_errors_flag
: Cell
<bool
>,
346 /// Track how many errors were reported when this infcx is created.
347 /// If the number of errors increases, that's also a sign (line
348 /// `tained_by_errors`) to avoid reporting certain kinds of errors.
349 // FIXME(matthewjasper) Merge into `tainted_by_errors_flag`
350 err_count_on_creation
: usize,
352 /// This flag is true while there is an active snapshot.
353 in_snapshot
: Cell
<bool
>,
355 /// What is the innermost universe we have created? Starts out as
356 /// `UniverseIndex::root()` but grows from there as we enter
357 /// universal quantifiers.
359 /// N.B., at present, we exclude the universal quantifiers on the
360 /// item we are type-checking, and just consider those names as
361 /// part of the root universe. So this would only get incremented
362 /// when we enter into a higher-ranked (`for<..>`) type or trait
364 universe
: Cell
<ty
::UniverseIndex
>,
367 /// See the `error_reporting` module for more details.
368 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)]
369 pub enum ValuePairs
<'tcx
> {
370 Types(ExpectedFound
<Ty
<'tcx
>>),
371 Regions(ExpectedFound
<ty
::Region
<'tcx
>>),
372 Consts(ExpectedFound
<&'tcx ty
::Const
<'tcx
>>),
373 TraitRefs(ExpectedFound
<ty
::TraitRef
<'tcx
>>),
374 PolyTraitRefs(ExpectedFound
<ty
::PolyTraitRef
<'tcx
>>),
377 /// The trace designates the path through inference that we took to
378 /// encounter an error or subtyping constraint.
380 /// See the `error_reporting` module for more details.
381 #[derive(Clone, Debug)]
382 pub struct TypeTrace
<'tcx
> {
383 cause
: ObligationCause
<'tcx
>,
384 values
: ValuePairs
<'tcx
>,
387 /// The origin of a `r1 <= r2` constraint.
389 /// See `error_reporting` module for more details
390 #[derive(Clone, Debug)]
391 pub enum SubregionOrigin
<'tcx
> {
392 /// Arose from a subtyping relation
393 Subtype(Box
<TypeTrace
<'tcx
>>),
395 /// When casting `&'a T` to an `&'b Trait` object,
396 /// relating `'a` to `'b`
397 RelateObjectBound(Span
),
399 /// Some type parameter was instantiated with the given type,
400 /// and that type must outlive some region.
401 RelateParamBound(Span
, Ty
<'tcx
>, Option
<Span
>),
403 /// The given region parameter was instantiated with a region
404 /// that must outlive some other region.
405 RelateRegionParamBound(Span
),
407 /// Creating a pointer `b` to contents of another reference
410 /// Creating a pointer `b` to contents of an upvar
411 ReborrowUpvar(Span
, ty
::UpvarId
),
413 /// Data with type `Ty<'tcx>` was borrowed
414 DataBorrowed(Ty
<'tcx
>, Span
),
416 /// (&'a &'b T) where a >= b
417 ReferenceOutlivesReferent(Ty
<'tcx
>, Span
),
419 /// Region in return type of invoked fn must enclose call
422 /// Comparing the signature and requirements of an impl method against
423 /// the containing trait.
424 CompareImplMethodObligation
{
427 impl_item_def_id
: DefId
,
428 trait_item_def_id
: DefId
,
432 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
433 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
434 static_assert_size
!(SubregionOrigin
<'_
>, 32);
436 /// Times when we replace late-bound regions with variables:
437 #[derive(Clone, Copy, Debug)]
438 pub enum LateBoundRegionConversionTime
{
439 /// when a fn is called
442 /// when two higher-ranked types are compared
445 /// when projecting an associated type
446 AssocTypeProjection(DefId
),
449 /// Reasons to create a region inference variable
451 /// See `error_reporting` module for more details
452 #[derive(Copy, Clone, Debug)]
453 pub enum RegionVariableOrigin
{
454 /// Region variables created for ill-categorized reasons,
455 /// mostly indicates places in need of refactoring
458 /// Regions created by a `&P` or `[...]` pattern
461 /// Regions created by `&` operator
464 /// Regions created as part of an autoref of a method receiver
465 Autoref(Span
, ty
::AssocItem
),
467 /// Regions created as part of an automatic coercion
470 /// Region variables created as the values for early-bound regions
471 EarlyBoundRegion(Span
, Symbol
),
473 /// Region variables created for bound regions
474 /// in a function or method that is called
475 LateBoundRegion(Span
, ty
::BoundRegionKind
, LateBoundRegionConversionTime
),
477 UpvarRegion(ty
::UpvarId
, Span
),
479 /// This origin is used for the inference variables that we create
480 /// during NLL region processing.
481 Nll(NllRegionVariableOrigin
),
484 #[derive(Copy, Clone, Debug)]
485 pub enum NllRegionVariableOrigin
{
486 /// During NLL region processing, we create variables for free
487 /// regions that we encounter in the function signature and
488 /// elsewhere. This origin indices we've got one of those.
491 /// "Universal" instantiation of a higher-ranked region (e.g.,
492 /// from a `for<'a> T` binder). Meant to represent "any region".
493 Placeholder(ty
::PlaceholderRegion
),
495 /// The variable we create to represent `'empty(U0)`.
499 /// If this is true, then this variable was created to represent a lifetime
500 /// bound in a `for` binder. For example, it might have been created to
501 /// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`.
502 /// Such variables are created when we are trying to figure out if there
503 /// is any valid instantiation of `'a` that could fit into some scenario.
505 /// This is used to inform error reporting: in the case that we are trying to
506 /// determine whether there is any valid instantiation of a `'a` variable that meets
507 /// some constraint C, we want to blame the "source" of that `for` type,
508 /// rather than blaming the source of the constraint C.
513 // FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
514 #[derive(Copy, Clone, Debug)]
515 pub enum FixupError
<'tcx
> {
516 UnresolvedIntTy(IntVid
),
517 UnresolvedFloatTy(FloatVid
),
519 UnresolvedConst(ConstVid
<'tcx
>),
522 /// See the `region_obligations` field for more information.
524 pub struct RegionObligation
<'tcx
> {
525 pub sub_region
: ty
::Region
<'tcx
>,
526 pub sup_type
: Ty
<'tcx
>,
527 pub origin
: SubregionOrigin
<'tcx
>,
530 impl<'tcx
> fmt
::Display
for FixupError
<'tcx
> {
531 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
532 use self::FixupError
::*;
535 UnresolvedIntTy(_
) => write
!(
537 "cannot determine the type of this integer; \
538 add a suffix to specify the type explicitly"
540 UnresolvedFloatTy(_
) => write
!(
542 "cannot determine the type of this number; \
543 add a suffix to specify the type explicitly"
545 UnresolvedTy(_
) => write
!(f
, "unconstrained type"),
546 UnresolvedConst(_
) => write
!(f
, "unconstrained const value"),
551 /// Helper type of a temporary returned by `tcx.infer_ctxt()`.
552 /// Necessary because we can't write the following bound:
553 /// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`.
554 pub struct InferCtxtBuilder
<'tcx
> {
556 fresh_typeck_results
: Option
<RefCell
<ty
::TypeckResults
<'tcx
>>>,
557 defining_use_anchor
: LocalDefId
,
560 pub trait TyCtxtInferExt
<'tcx
> {
561 fn infer_ctxt(self) -> InferCtxtBuilder
<'tcx
>;
564 impl TyCtxtInferExt
<'tcx
> for TyCtxt
<'tcx
> {
565 fn infer_ctxt(self) -> InferCtxtBuilder
<'tcx
> {
568 defining_use_anchor
: CRATE_DEF_ID
,
569 fresh_typeck_results
: None
,
574 impl<'tcx
> InferCtxtBuilder
<'tcx
> {
575 /// Used only by `rustc_typeck` during body type-checking/inference,
576 /// will initialize `in_progress_typeck_results` with fresh `TypeckResults`.
577 /// Will also change the scope for opaque type defining use checks to the given owner.
578 pub fn with_fresh_in_progress_typeck_results(mut self, table_owner
: LocalDefId
) -> Self {
579 self.fresh_typeck_results
= Some(RefCell
::new(ty
::TypeckResults
::new(table_owner
)));
580 self.with_opaque_type_inference(table_owner
)
583 /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
584 /// you need to call this function. Otherwise the opaque type will be treated opaquely.
586 /// It is only meant to be called in two places, for typeck
587 /// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
589 pub fn with_opaque_type_inference(mut self, defining_use_anchor
: LocalDefId
) -> Self {
590 self.defining_use_anchor
= defining_use_anchor
;
594 /// Given a canonical value `C` as a starting point, create an
595 /// inference context that contains each of the bound values
596 /// within instantiated as a fresh variable. The `f` closure is
597 /// invoked with the new infcx, along with the instantiated value
598 /// `V` and a substitution `S`. This substitution `S` maps from
599 /// the bound values in `C` to their instantiated values in `V`
600 /// (in other words, `S(C) = V`).
601 pub fn enter_with_canonical
<T
, R
>(
604 canonical
: &Canonical
<'tcx
, T
>,
605 f
: impl for<'a
> FnOnce(InferCtxt
<'a
, 'tcx
>, T
, CanonicalVarValues
<'tcx
>) -> R
,
608 T
: TypeFoldable
<'tcx
>,
612 infcx
.instantiate_canonical_with_fresh_inference_vars(span
, canonical
);
613 f(infcx
, value
, subst
)
617 pub fn enter
<R
>(&mut self, f
: impl for<'a
> FnOnce(InferCtxt
<'a
, 'tcx
>) -> R
) -> R
{
618 let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results }
= *self;
619 let in_progress_typeck_results
= fresh_typeck_results
.as_ref();
623 in_progress_typeck_results
,
624 inner
: RefCell
::new(InferCtxtInner
::new()),
625 lexical_region_resolutions
: RefCell
::new(None
),
626 selection_cache
: Default
::default(),
627 evaluation_cache
: Default
::default(),
628 reported_trait_errors
: Default
::default(),
629 reported_closure_mismatch
: Default
::default(),
630 tainted_by_errors_flag
: Cell
::new(false),
631 err_count_on_creation
: tcx
.sess
.err_count(),
632 in_snapshot
: Cell
::new(false),
633 skip_leak_check
: Cell
::new(false),
634 universe
: Cell
::new(ty
::UniverseIndex
::ROOT
),
639 impl<'tcx
, T
> InferOk
<'tcx
, T
> {
640 pub fn unit(self) -> InferOk
<'tcx
, ()> {
641 InferOk { value: (), obligations: self.obligations }
644 /// Extracts `value`, registering any obligations into `fulfill_cx`.
645 pub fn into_value_registering_obligations(
647 infcx
: &InferCtxt
<'_
, 'tcx
>,
648 fulfill_cx
: &mut dyn TraitEngine
<'tcx
>,
650 let InferOk { value, obligations }
= self;
651 for obligation
in obligations
{
652 fulfill_cx
.register_predicate_obligation(infcx
, obligation
);
658 impl<'tcx
> InferOk
<'tcx
, ()> {
659 pub fn into_obligations(self) -> PredicateObligations
<'tcx
> {
664 #[must_use = "once you start a snapshot, you should always consume it"]
665 pub struct CombinedSnapshot
<'a
, 'tcx
> {
666 undo_snapshot
: Snapshot
<'tcx
>,
667 region_constraints_snapshot
: RegionSnapshot
,
668 universe
: ty
::UniverseIndex
,
669 was_in_snapshot
: bool
,
670 _in_progress_typeck_results
: Option
<Ref
<'a
, ty
::TypeckResults
<'tcx
>>>,
673 impl<'a
, 'tcx
> InferCtxt
<'a
, 'tcx
> {
674 /// calls `tcx.try_unify_abstract_consts` after
675 /// canonicalizing the consts.
676 pub fn try_unify_abstract_consts(
678 a
: ty
::Unevaluated
<'tcx
, ()>,
679 b
: ty
::Unevaluated
<'tcx
, ()>,
681 let canonical
= self.canonicalize_query((a
, b
), &mut OriginalQueryValues
::default());
682 debug
!("canonical consts: {:?}", &canonical
.value
);
684 self.tcx
.try_unify_abstract_consts(canonical
.value
)
687 pub fn is_in_snapshot(&self) -> bool
{
688 self.in_snapshot
.get()
691 pub fn freshen
<T
: TypeFoldable
<'tcx
>>(&self, t
: T
) -> T
{
692 t
.fold_with(&mut self.freshener())
695 /// Returns whether `ty` is a diverging type variable or not.
696 /// (If `ty` is not a type variable at all, returns not diverging.)
698 /// No attempt is made to resolve `ty`.
699 pub fn type_var_diverges(&'a
self, ty
: Ty
<'_
>) -> Diverging
{
701 ty
::Infer(ty
::TyVar(vid
)) => self.inner
.borrow_mut().type_variables().var_diverges(vid
),
702 _
=> Diverging
::NotDiverging
,
706 /// Returns the origin of the type variable identified by `vid`, or `None`
707 /// if this is not a type variable.
709 /// No attempt is made to resolve `ty`.
710 pub fn type_var_origin(&'a
self, ty
: Ty
<'tcx
>) -> Option
<TypeVariableOrigin
> {
712 ty
::Infer(ty
::TyVar(vid
)) => {
713 Some(*self.inner
.borrow_mut().type_variables().var_origin(vid
))
719 pub fn freshener
<'b
>(&'b
self) -> TypeFreshener
<'b
, 'tcx
> {
720 freshen
::TypeFreshener
::new(self, false)
723 /// Like `freshener`, but does not replace `'static` regions.
724 pub fn freshener_keep_static
<'b
>(&'b
self) -> TypeFreshener
<'b
, 'tcx
> {
725 freshen
::TypeFreshener
::new(self, true)
728 pub fn unsolved_variables(&self) -> Vec
<Ty
<'tcx
>> {
729 let mut inner
= self.inner
.borrow_mut();
730 let mut vars
: Vec
<Ty
<'_
>> = inner
732 .unsolved_variables()
734 .map(|t
| self.tcx
.mk_ty_var(t
))
737 (0..inner
.int_unification_table().len())
738 .map(|i
| ty
::IntVid { index: i as u32 }
)
739 .filter(|&vid
| inner
.int_unification_table().probe_value(vid
).is_none())
740 .map(|v
| self.tcx
.mk_int_var(v
)),
743 (0..inner
.float_unification_table().len())
744 .map(|i
| ty
::FloatVid { index: i as u32 }
)
745 .filter(|&vid
| inner
.float_unification_table().probe_value(vid
).is_none())
746 .map(|v
| self.tcx
.mk_float_var(v
)),
753 trace
: TypeTrace
<'tcx
>,
754 param_env
: ty
::ParamEnv
<'tcx
>,
755 ) -> CombineFields
<'a
, 'tcx
> {
761 obligations
: PredicateObligations
::new(),
765 /// Clear the "currently in a snapshot" flag, invoke the closure,
766 /// then restore the flag to its original value. This flag is a
767 /// debugging measure designed to detect cases where we start a
768 /// snapshot, create type variables, and register obligations
769 /// which may involve those type variables in the fulfillment cx,
770 /// potentially leaving "dangling type variables" behind.
771 /// In such cases, an assertion will fail when attempting to
772 /// register obligations, within a snapshot. Very useful, much
773 /// better than grovelling through megabytes of `RUSTC_LOG` output.
775 /// HOWEVER, in some cases the flag is unhelpful. In particular, we
776 /// sometimes create a "mini-fulfilment-cx" in which we enroll
777 /// obligations. As long as this fulfillment cx is fully drained
778 /// before we return, this is not a problem, as there won't be any
779 /// escaping obligations in the main cx. In those cases, you can
780 /// use this function.
781 pub fn save_and_restore_in_snapshot_flag
<F
, R
>(&self, func
: F
) -> R
783 F
: FnOnce(&Self) -> R
,
785 let flag
= self.in_snapshot
.replace(false);
786 let result
= func(self);
787 self.in_snapshot
.set(flag
);
791 fn start_snapshot(&self) -> CombinedSnapshot
<'a
, 'tcx
> {
792 debug
!("start_snapshot()");
794 let in_snapshot
= self.in_snapshot
.replace(true);
796 let mut inner
= self.inner
.borrow_mut();
799 undo_snapshot
: inner
.undo_log
.start_snapshot(),
800 region_constraints_snapshot
: inner
.unwrap_region_constraints().start_snapshot(),
801 universe
: self.universe(),
802 was_in_snapshot
: in_snapshot
,
803 // Borrow typeck results "in progress" (i.e., during typeck)
804 // to ban writes from within a snapshot to them.
805 _in_progress_typeck_results
: self
806 .in_progress_typeck_results
807 .map(|typeck_results
| typeck_results
.borrow()),
811 fn rollback_to(&self, cause
: &str, snapshot
: CombinedSnapshot
<'a
, 'tcx
>) {
812 debug
!("rollback_to(cause={})", cause
);
813 let CombinedSnapshot
{
815 region_constraints_snapshot
,
818 _in_progress_typeck_results
,
821 self.in_snapshot
.set(was_in_snapshot
);
822 self.universe
.set(universe
);
824 let mut inner
= self.inner
.borrow_mut();
825 inner
.rollback_to(undo_snapshot
);
826 inner
.unwrap_region_constraints().rollback_to(region_constraints_snapshot
);
829 fn commit_from(&self, snapshot
: CombinedSnapshot
<'a
, 'tcx
>) {
830 debug
!("commit_from()");
831 let CombinedSnapshot
{
833 region_constraints_snapshot
: _
,
836 _in_progress_typeck_results
,
839 self.in_snapshot
.set(was_in_snapshot
);
841 self.inner
.borrow_mut().commit(undo_snapshot
);
844 /// Executes `f` and commit the bindings.
845 pub fn commit_unconditionally
<R
, F
>(&self, f
: F
) -> R
847 F
: FnOnce(&CombinedSnapshot
<'a
, 'tcx
>) -> R
,
849 debug
!("commit_unconditionally()");
850 let snapshot
= self.start_snapshot();
851 let r
= f(&snapshot
);
852 self.commit_from(snapshot
);
856 /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`.
857 pub fn commit_if_ok
<T
, E
, F
>(&self, f
: F
) -> Result
<T
, E
>
859 F
: FnOnce(&CombinedSnapshot
<'a
, 'tcx
>) -> Result
<T
, E
>,
861 debug
!("commit_if_ok()");
862 let snapshot
= self.start_snapshot();
863 let r
= f(&snapshot
);
864 debug
!("commit_if_ok() -- r.is_ok() = {}", r
.is_ok());
867 self.commit_from(snapshot
);
870 self.rollback_to("commit_if_ok -- error", snapshot
);
876 /// Execute `f` then unroll any bindings it creates.
877 pub fn probe
<R
, F
>(&self, f
: F
) -> R
879 F
: FnOnce(&CombinedSnapshot
<'a
, 'tcx
>) -> R
,
882 let snapshot
= self.start_snapshot();
883 let r
= f(&snapshot
);
884 self.rollback_to("probe", snapshot
);
888 /// If `should_skip` is true, then execute `f` then unroll any bindings it creates.
889 pub fn probe_maybe_skip_leak_check
<R
, F
>(&self, should_skip
: bool
, f
: F
) -> R
891 F
: FnOnce(&CombinedSnapshot
<'a
, 'tcx
>) -> R
,
894 let snapshot
= self.start_snapshot();
895 let was_skip_leak_check
= self.skip_leak_check
.get();
897 self.skip_leak_check
.set(true);
899 let r
= f(&snapshot
);
900 self.rollback_to("probe", snapshot
);
901 self.skip_leak_check
.set(was_skip_leak_check
);
905 /// Scan the constraints produced since `snapshot` began and returns:
907 /// - `None` -- if none of them involve "region outlives" constraints
908 /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder
909 /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders
910 pub fn region_constraints_added_in_snapshot(
912 snapshot
: &CombinedSnapshot
<'a
, 'tcx
>,
916 .unwrap_region_constraints()
917 .region_constraints_added_in_snapshot(&snapshot
.undo_snapshot
)
920 pub fn add_given(&self, sub
: ty
::Region
<'tcx
>, sup
: ty
::RegionVid
) {
921 self.inner
.borrow_mut().unwrap_region_constraints().add_given(sub
, sup
);
924 pub fn can_sub
<T
>(&self, param_env
: ty
::ParamEnv
<'tcx
>, a
: T
, b
: T
) -> UnitResult
<'tcx
>
926 T
: at
::ToTrace
<'tcx
>,
928 let origin
= &ObligationCause
::dummy();
930 self.at(origin
, param_env
).sub(a
, b
).map(|InferOk { obligations: _, .. }
| {
931 // Ignore obligations, since we are unrolling
932 // everything anyway.
937 pub fn can_eq
<T
>(&self, param_env
: ty
::ParamEnv
<'tcx
>, a
: T
, b
: T
) -> UnitResult
<'tcx
>
939 T
: at
::ToTrace
<'tcx
>,
941 let origin
= &ObligationCause
::dummy();
943 self.at(origin
, param_env
).eq(a
, b
).map(|InferOk { obligations: _, .. }
| {
944 // Ignore obligations, since we are unrolling
945 // everything anyway.
952 origin
: SubregionOrigin
<'tcx
>,
956 debug
!("sub_regions({:?} <: {:?})", a
, b
);
957 self.inner
.borrow_mut().unwrap_region_constraints().make_subregion(origin
, a
, b
);
960 /// Require that the region `r` be equal to one of the regions in
961 /// the set `regions`.
962 pub fn member_constraint(
964 opaque_type_def_id
: DefId
,
965 definition_span
: Span
,
967 region
: ty
::Region
<'tcx
>,
968 in_regions
: &Lrc
<Vec
<ty
::Region
<'tcx
>>>,
970 debug
!("member_constraint({:?} <: {:?})", region
, in_regions
);
971 self.inner
.borrow_mut().unwrap_region_constraints().member_constraint(
980 /// Processes a `Coerce` predicate from the fulfillment context.
981 /// This is NOT the preferred way to handle coercion, which is to
982 /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
984 /// This method here is actually a fallback that winds up being
985 /// invoked when `FnCtxt::coerce` encounters unresolved type variables
986 /// and records a coercion predicate. Presently, this method is equivalent
987 /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
988 /// actually requiring `a <: b`. This is of course a valid coercion,
989 /// but it's not as flexible as `FnCtxt::coerce` would be.
991 /// (We may refactor this in the future, but there are a number of
992 /// practical obstacles. Among other things, `FnCtxt::coerce` presently
993 /// records adjustments that are required on the HIR in order to perform
994 /// the coercion, and we don't currently have a way to manage that.)
995 pub fn coerce_predicate(
997 cause
: &ObligationCause
<'tcx
>,
998 param_env
: ty
::ParamEnv
<'tcx
>,
999 predicate
: ty
::PolyCoercePredicate
<'tcx
>,
1000 ) -> Option
<InferResult
<'tcx
, ()>> {
1001 let subtype_predicate
= predicate
.map_bound(|p
| ty
::SubtypePredicate
{
1002 a_is_expected
: false, // when coercing from `a` to `b`, `b` is expected
1006 self.subtype_predicate(cause
, param_env
, subtype_predicate
)
1009 pub fn subtype_predicate(
1011 cause
: &ObligationCause
<'tcx
>,
1012 param_env
: ty
::ParamEnv
<'tcx
>,
1013 predicate
: ty
::PolySubtypePredicate
<'tcx
>,
1014 ) -> Option
<InferResult
<'tcx
, ()>> {
1015 // Check for two unresolved inference variables, in which case we can
1016 // make no progress. This is partly a micro-optimization, but it's
1017 // also an opportunity to "sub-unify" the variables. This isn't
1018 // *necessary* to prevent cycles, because they would eventually be sub-unified
1019 // anyhow during generalization, but it helps with diagnostics (we can detect
1020 // earlier that they are sub-unified).
1022 // Note that we can just skip the binders here because
1023 // type variables can't (at present, at
1024 // least) capture any of the things bound by this binder.
1026 // Note that this sub here is not just for diagnostics - it has semantic
1028 let r_a
= self.shallow_resolve(predicate
.skip_binder().a
);
1029 let r_b
= self.shallow_resolve(predicate
.skip_binder().b
);
1030 match (r_a
.kind(), r_b
.kind()) {
1031 (&ty
::Infer(ty
::TyVar(a_vid
)), &ty
::Infer(ty
::TyVar(b_vid
))) => {
1032 self.inner
.borrow_mut().type_variables().sub(a_vid
, b_vid
);
1038 Some(self.commit_if_ok(|_snapshot
| {
1039 let ty
::SubtypePredicate { a_is_expected, a, b }
=
1040 self.replace_bound_vars_with_placeholders(predicate
);
1042 let ok
= self.at(cause
, param_env
).sub_exp(a_is_expected
, a
, b
)?
;
1048 pub fn region_outlives_predicate(
1050 cause
: &traits
::ObligationCause
<'tcx
>,
1051 predicate
: ty
::PolyRegionOutlivesPredicate
<'tcx
>,
1052 ) -> UnitResult
<'tcx
> {
1053 self.commit_if_ok(|_snapshot
| {
1054 let ty
::OutlivesPredicate(r_a
, r_b
) =
1055 self.replace_bound_vars_with_placeholders(predicate
);
1056 let origin
= SubregionOrigin
::from_obligation_cause(cause
, || {
1057 RelateRegionParamBound(cause
.span
)
1059 self.sub_regions(origin
, r_b
, r_a
); // `b : a` ==> `a <= b`
1064 pub fn next_ty_var_id(&self, diverging
: Diverging
, origin
: TypeVariableOrigin
) -> TyVid
{
1065 self.inner
.borrow_mut().type_variables().new_var(self.universe(), diverging
, origin
)
1068 pub fn next_ty_var(&self, origin
: TypeVariableOrigin
) -> Ty
<'tcx
> {
1069 self.tcx
.mk_ty_var(self.next_ty_var_id(Diverging
::NotDiverging
, origin
))
1072 pub fn next_ty_var_in_universe(
1074 origin
: TypeVariableOrigin
,
1075 universe
: ty
::UniverseIndex
,
1077 let vid
= self.inner
.borrow_mut().type_variables().new_var(
1079 Diverging
::NotDiverging
,
1082 self.tcx
.mk_ty_var(vid
)
1085 pub fn next_diverging_ty_var(&self, origin
: TypeVariableOrigin
) -> Ty
<'tcx
> {
1086 self.tcx
.mk_ty_var(self.next_ty_var_id(Diverging
::Diverges
, origin
))
1089 pub fn next_const_var(
1092 origin
: ConstVariableOrigin
,
1093 ) -> &'tcx ty
::Const
<'tcx
> {
1094 self.tcx
.mk_const_var(self.next_const_var_id(origin
), ty
)
1097 pub fn next_const_var_in_universe(
1100 origin
: ConstVariableOrigin
,
1101 universe
: ty
::UniverseIndex
,
1102 ) -> &'tcx ty
::Const
<'tcx
> {
1106 .const_unification_table()
1107 .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe }
});
1108 self.tcx
.mk_const_var(vid
, ty
)
1111 pub fn next_const_var_id(&self, origin
: ConstVariableOrigin
) -> ConstVid
<'tcx
> {
1112 self.inner
.borrow_mut().const_unification_table().new_key(ConstVarValue
{
1114 val
: ConstVariableValue
::Unknown { universe: self.universe() }
,
1118 fn next_int_var_id(&self) -> IntVid
{
1119 self.inner
.borrow_mut().int_unification_table().new_key(None
)
1122 pub fn next_int_var(&self) -> Ty
<'tcx
> {
1123 self.tcx
.mk_int_var(self.next_int_var_id())
1126 fn next_float_var_id(&self) -> FloatVid
{
1127 self.inner
.borrow_mut().float_unification_table().new_key(None
)
1130 pub fn next_float_var(&self) -> Ty
<'tcx
> {
1131 self.tcx
.mk_float_var(self.next_float_var_id())
1134 /// Creates a fresh region variable with the next available index.
1135 /// The variable will be created in the maximum universe created
1136 /// thus far, allowing it to name any region created thus far.
1137 pub fn next_region_var(&self, origin
: RegionVariableOrigin
) -> ty
::Region
<'tcx
> {
1138 self.next_region_var_in_universe(origin
, self.universe())
1141 /// Creates a fresh region variable with the next available index
1142 /// in the given universe; typically, you can use
1143 /// `next_region_var` and just use the maximal universe.
1144 pub fn next_region_var_in_universe(
1146 origin
: RegionVariableOrigin
,
1147 universe
: ty
::UniverseIndex
,
1148 ) -> ty
::Region
<'tcx
> {
1150 self.inner
.borrow_mut().unwrap_region_constraints().new_region_var(universe
, origin
);
1151 self.tcx
.mk_region(ty
::ReVar(region_var
))
1154 /// Return the universe that the region `r` was created in. For
1155 /// most regions (e.g., `'static`, named regions from the user,
1156 /// etc) this is the root universe U0. For inference variables or
1157 /// placeholders, however, it will return the universe which which
1158 /// they are associated.
1159 pub fn universe_of_region(&self, r
: ty
::Region
<'tcx
>) -> ty
::UniverseIndex
{
1160 self.inner
.borrow_mut().unwrap_region_constraints().universe(r
)
1163 /// Number of region variables created so far.
1164 pub fn num_region_vars(&self) -> usize {
1165 self.inner
.borrow_mut().unwrap_region_constraints().num_region_vars()
1168 /// Just a convenient wrapper of `next_region_var` for using during NLL.
1169 pub fn next_nll_region_var(&self, origin
: NllRegionVariableOrigin
) -> ty
::Region
<'tcx
> {
1170 self.next_region_var(RegionVariableOrigin
::Nll(origin
))
1173 /// Just a convenient wrapper of `next_region_var` for using during NLL.
1174 pub fn next_nll_region_var_in_universe(
1176 origin
: NllRegionVariableOrigin
,
1177 universe
: ty
::UniverseIndex
,
1178 ) -> ty
::Region
<'tcx
> {
1179 self.next_region_var_in_universe(RegionVariableOrigin
::Nll(origin
), universe
)
1182 pub fn var_for_def(&self, span
: Span
, param
: &ty
::GenericParamDef
) -> GenericArg
<'tcx
> {
1184 GenericParamDefKind
::Lifetime
=> {
1185 // Create a region inference variable for the given
1186 // region parameter definition.
1187 self.next_region_var(EarlyBoundRegion(span
, param
.name
)).into()
1189 GenericParamDefKind
::Type { .. }
=> {
1190 // Create a type inference variable for the given
1191 // type parameter definition. The substitutions are
1192 // for actual parameters that may be referred to by
1193 // the default of this type parameter, if it exists.
1194 // e.g., `struct Foo<A, B, C = (A, B)>(...);` when
1195 // used in a path such as `Foo::<T, U>::new()` will
1196 // use an inference variable for `C` with `[T, U]`
1197 // as the substitutions for the default, `(T, U)`.
1198 let ty_var_id
= self.inner
.borrow_mut().type_variables().new_var(
1200 Diverging
::NotDiverging
,
1201 TypeVariableOrigin
{
1202 kind
: TypeVariableOriginKind
::TypeParameterDefinition(
1210 self.tcx
.mk_ty_var(ty_var_id
).into()
1212 GenericParamDefKind
::Const { .. }
=> {
1213 let origin
= ConstVariableOrigin
{
1214 kind
: ConstVariableOriginKind
::ConstParameterDefinition(
1221 self.inner
.borrow_mut().const_unification_table().new_key(ConstVarValue
{
1223 val
: ConstVariableValue
::Unknown { universe: self.universe() }
,
1225 self.tcx
.mk_const_var(const_var_id
, self.tcx
.type_of(param
.def_id
)).into()
1230 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
1231 /// type/region parameter to a fresh inference variable.
1232 pub fn fresh_substs_for_item(&self, span
: Span
, def_id
: DefId
) -> SubstsRef
<'tcx
> {
1233 InternalSubsts
::for_item(self.tcx
, def_id
, |param
, _
| self.var_for_def(span
, param
))
1236 /// Returns `true` if errors have been reported since this infcx was
1237 /// created. This is sometimes used as a heuristic to skip
1238 /// reporting errors that often occur as a result of earlier
1239 /// errors, but where it's hard to be 100% sure (e.g., unresolved
1240 /// inference variables, regionck errors).
1241 pub fn is_tainted_by_errors(&self) -> bool
{
1243 "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
1244 tainted_by_errors_flag={})",
1245 self.tcx
.sess
.err_count(),
1246 self.err_count_on_creation
,
1247 self.tainted_by_errors_flag
.get()
1250 if self.tcx
.sess
.err_count() > self.err_count_on_creation
{
1251 return true; // errors reported since this infcx was made
1253 self.tainted_by_errors_flag
.get()
1256 /// Set the "tainted by errors" flag to true. We call this when we
1257 /// observe an error from a prior pass.
1258 pub fn set_tainted_by_errors(&self) {
1259 debug
!("set_tainted_by_errors()");
1260 self.tainted_by_errors_flag
.set(true)
1263 /// Process the region constraints and report any errors that
1264 /// result. After this, no more unification operations should be
1265 /// done -- or the compiler will panic -- but it is legal to use
1266 /// `resolve_vars_if_possible` as well as `fully_resolve`.
1267 pub fn resolve_regions_and_report_errors(
1269 region_context
: DefId
,
1270 outlives_env
: &OutlivesEnvironment
<'tcx
>,
1273 let (var_infos
, data
) = {
1274 let mut inner
= self.inner
.borrow_mut();
1275 let inner
= &mut *inner
;
1277 self.is_tainted_by_errors() || inner
.region_obligations
.is_empty(),
1278 "region_obligations not empty: {:#?}",
1279 inner
.region_obligations
1282 .region_constraint_storage
1284 .expect("regions already resolved")
1285 .with_log(&mut inner
.undo_log
)
1286 .into_infos_and_data()
1290 &RegionRelations
::new(self.tcx
, region_context
, outlives_env
.free_region_map());
1292 let (lexical_region_resolutions
, errors
) =
1293 lexical_region_resolve
::resolve(region_rels
, var_infos
, data
, mode
);
1295 let old_value
= self.lexical_region_resolutions
.replace(Some(lexical_region_resolutions
));
1296 assert
!(old_value
.is_none());
1298 if !self.is_tainted_by_errors() {
1299 // As a heuristic, just skip reporting region errors
1300 // altogether if other errors have been reported while
1301 // this infcx was in use. This is totally hokey but
1302 // otherwise we have a hard time separating legit region
1303 // errors from silly ones.
1304 self.report_region_errors(&errors
);
1308 /// Obtains (and clears) the current set of region
1309 /// constraints. The inference context is still usable: further
1310 /// unifications will simply add new constraints.
1312 /// This method is not meant to be used with normal lexical region
1313 /// resolution. Rather, it is used in the NLL mode as a kind of
1314 /// interim hack: basically we run normal type-check and generate
1315 /// region constraints as normal, but then we take them and
1316 /// translate them into the form that the NLL solver
1317 /// understands. See the NLL module for mode details.
1318 pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData
<'tcx
> {
1320 self.inner
.borrow().region_obligations
.is_empty(),
1321 "region_obligations not empty: {:#?}",
1322 self.inner
.borrow().region_obligations
1325 self.inner
.borrow_mut().unwrap_region_constraints().take_and_reset_data()
1328 /// Gives temporary access to the region constraint data.
1329 pub fn with_region_constraints
<R
>(
1331 op
: impl FnOnce(&RegionConstraintData
<'tcx
>) -> R
,
1333 let mut inner
= self.inner
.borrow_mut();
1334 op(inner
.unwrap_region_constraints().data())
1337 pub fn region_var_origin(&self, vid
: ty
::RegionVid
) -> RegionVariableOrigin
{
1338 let mut inner
= self.inner
.borrow_mut();
1339 let inner
= &mut *inner
;
1341 .region_constraint_storage
1343 .expect("regions already resolved")
1344 .with_log(&mut inner
.undo_log
)
1348 /// Takes ownership of the list of variable regions. This implies
1349 /// that all the region constraints have already been taken, and
1350 /// hence that `resolve_regions_and_report_errors` can never be
1351 /// called. This is used only during NLL processing to "hand off" ownership
1352 /// of the set of region variables into the NLL region context.
1353 pub fn take_region_var_origins(&self) -> VarInfos
{
1354 let mut inner
= self.inner
.borrow_mut();
1355 let (var_infos
, data
) = inner
1356 .region_constraint_storage
1358 .expect("regions already resolved")
1359 .with_log(&mut inner
.undo_log
)
1360 .into_infos_and_data();
1361 assert
!(data
.is_empty());
1365 pub fn ty_to_string(&self, t
: Ty
<'tcx
>) -> String
{
1366 self.resolve_vars_if_possible(t
).to_string()
1369 /// If `TyVar(vid)` resolves to a type, return that type. Else, return the
1370 /// universe index of `TyVar(vid)`.
1371 pub fn probe_ty_var(&self, vid
: TyVid
) -> Result
<Ty
<'tcx
>, ty
::UniverseIndex
> {
1372 use self::type_variable
::TypeVariableValue
;
1374 match self.inner
.borrow_mut().type_variables().probe(vid
) {
1375 TypeVariableValue
::Known { value }
=> Ok(value
),
1376 TypeVariableValue
::Unknown { universe }
=> Err(universe
),
1380 /// Resolve any type variables found in `value` -- but only one
1381 /// level. So, if the variable `?X` is bound to some type
1382 /// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
1383 /// itself be bound to a type).
1385 /// Useful when you only need to inspect the outermost level of
1386 /// the type and don't care about nested types (or perhaps you
1387 /// will be resolving them as well, e.g. in a loop).
1388 pub fn shallow_resolve
<T
>(&self, value
: T
) -> T
1390 T
: TypeFoldable
<'tcx
>,
1392 value
.fold_with(&mut ShallowResolver { infcx: self }
)
1395 pub fn root_var(&self, var
: ty
::TyVid
) -> ty
::TyVid
{
1396 self.inner
.borrow_mut().type_variables().root_var(var
)
1399 /// Where possible, replaces type/const variables in
1400 /// `value` with their final value. Note that region variables
1401 /// are unaffected. If a type/const variable has not been unified, it
1402 /// is left as is. This is an idempotent operation that does
1403 /// not affect inference state in any way and so you can do it
1405 pub fn resolve_vars_if_possible
<T
>(&self, value
: T
) -> T
1407 T
: TypeFoldable
<'tcx
>,
1409 if !value
.needs_infer() {
1410 return value
; // Avoid duplicated subst-folding.
1412 let mut r
= resolve
::OpportunisticVarResolver
::new(self);
1413 value
.fold_with(&mut r
)
1416 /// Returns the first unresolved variable contained in `T`. In the
1417 /// process of visiting `T`, this will resolve (where possible)
1418 /// type variables in `T`, but it never constructs the final,
1419 /// resolved type, so it's more efficient than
1420 /// `resolve_vars_if_possible()`.
1421 pub fn unresolved_type_vars
<T
>(&self, value
: &T
) -> Option
<(Ty
<'tcx
>, Option
<Span
>)>
1423 T
: TypeFoldable
<'tcx
>,
1425 value
.visit_with(&mut resolve
::UnresolvedTypeFinder
::new(self)).break_value()
1428 pub fn probe_const_var(
1430 vid
: ty
::ConstVid
<'tcx
>,
1431 ) -> Result
<&'tcx ty
::Const
<'tcx
>, ty
::UniverseIndex
> {
1432 match self.inner
.borrow_mut().const_unification_table().probe_value(vid
).val
{
1433 ConstVariableValue
::Known { value }
=> Ok(value
),
1434 ConstVariableValue
::Unknown { universe }
=> Err(universe
),
1438 pub fn fully_resolve
<T
: TypeFoldable
<'tcx
>>(&self, value
: T
) -> FixupResult
<'tcx
, T
> {
1440 * Attempts to resolve all type/region/const variables in
1441 * `value`. Region inference must have been run already (e.g.,
1442 * by calling `resolve_regions_and_report_errors`). If some
1443 * variable was never unified, an `Err` results.
1445 * This method is idempotent, but it not typically not invoked
1446 * except during the writeback phase.
1449 resolve
::fully_resolve(self, value
)
1452 // [Note-Type-error-reporting]
1453 // An invariant is that anytime the expected or actual type is Error (the special
1454 // error type, meaning that an error occurred when typechecking this expression),
1455 // this is a derived error. The error cascaded from another error (that was already
1456 // reported), so it's not useful to display it to the user.
1457 // The following methods implement this logic.
1458 // They check if either the actual or expected type is Error, and don't print the error
1459 // in this case. The typechecker should only ever report type errors involving mismatched
1460 // types using one of these methods, and should not call span_err directly for such
1463 pub fn type_error_struct_with_diag
<M
>(
1467 actual_ty
: Ty
<'tcx
>,
1468 ) -> DiagnosticBuilder
<'tcx
>
1470 M
: FnOnce(String
) -> DiagnosticBuilder
<'tcx
>,
1472 let actual_ty
= self.resolve_vars_if_possible(actual_ty
);
1473 debug
!("type_error_struct_with_diag({:?}, {:?})", sp
, actual_ty
);
1475 // Don't report an error if actual type is `Error`.
1476 if actual_ty
.references_error() {
1477 return self.tcx
.sess
.diagnostic().struct_dummy();
1480 mk_diag(self.ty_to_string(actual_ty
))
1483 pub fn report_mismatched_types(
1485 cause
: &ObligationCause
<'tcx
>,
1488 err
: TypeError
<'tcx
>,
1489 ) -> DiagnosticBuilder
<'tcx
> {
1490 let trace
= TypeTrace
::types(cause
, true, expected
, actual
);
1491 self.report_and_explain_type_error(trace
, &err
)
1494 pub fn report_mismatched_consts(
1496 cause
: &ObligationCause
<'tcx
>,
1497 expected
: &'tcx ty
::Const
<'tcx
>,
1498 actual
: &'tcx ty
::Const
<'tcx
>,
1499 err
: TypeError
<'tcx
>,
1500 ) -> DiagnosticBuilder
<'tcx
> {
1501 let trace
= TypeTrace
::consts(cause
, true, expected
, actual
);
1502 self.report_and_explain_type_error(trace
, &err
)
1505 pub fn replace_bound_vars_with_fresh_vars
<T
>(
1508 lbrct
: LateBoundRegionConversionTime
,
1509 value
: ty
::Binder
<'tcx
, T
>,
1510 ) -> (T
, BTreeMap
<ty
::BoundRegion
, ty
::Region
<'tcx
>>)
1512 T
: TypeFoldable
<'tcx
>,
1515 |br
: ty
::BoundRegion
| self.next_region_var(LateBoundRegion(span
, br
.kind
, lbrct
));
1517 self.next_ty_var(TypeVariableOrigin
{
1518 kind
: TypeVariableOriginKind
::MiscVariable
,
1522 let fld_c
= |_
, ty
| {
1523 self.next_const_var(
1525 ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }
,
1528 self.tcx
.replace_bound_vars(value
, fld_r
, fld_t
, fld_c
)
1531 /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method.
1532 pub fn verify_generic_bound(
1534 origin
: SubregionOrigin
<'tcx
>,
1535 kind
: GenericKind
<'tcx
>,
1536 a
: ty
::Region
<'tcx
>,
1537 bound
: VerifyBound
<'tcx
>,
1539 debug
!("verify_generic_bound({:?}, {:?} <: {:?})", kind
, a
, bound
);
1543 .unwrap_region_constraints()
1544 .verify_generic_bound(origin
, kind
, a
, bound
);
1547 /// Obtains the latest type of the given closure; this may be a
1548 /// closure in the current function, in which case its
1549 /// `ClosureKind` may not yet be known.
1550 pub fn closure_kind(&self, closure_substs
: SubstsRef
<'tcx
>) -> Option
<ty
::ClosureKind
> {
1551 let closure_kind_ty
= closure_substs
.as_closure().kind_ty();
1552 let closure_kind_ty
= self.shallow_resolve(closure_kind_ty
);
1553 closure_kind_ty
.to_opt_closure_kind()
1556 /// Clears the selection, evaluation, and projection caches. This is useful when
1557 /// repeatedly attempting to select an `Obligation` while changing only
1558 /// its `ParamEnv`, since `FulfillmentContext` doesn't use probing.
1559 pub fn clear_caches(&self) {
1560 self.selection_cache
.clear();
1561 self.evaluation_cache
.clear();
1562 self.inner
.borrow_mut().projection_cache().clear();
1565 pub fn universe(&self) -> ty
::UniverseIndex
{
1569 /// Creates and return a fresh universe that extends all previous
1570 /// universes. Updates `self.universe` to that new universe.
1571 pub fn create_next_universe(&self) -> ty
::UniverseIndex
{
1572 let u
= self.universe
.get().next_universe();
1573 self.universe
.set(u
);
1577 /// Resolves and evaluates a constant.
1579 /// The constant can be located on a trait like `<A as B>::C`, in which case the given
1580 /// substitutions and environment are used to resolve the constant. Alternatively if the
1581 /// constant has generic parameters in scope the substitutions are used to evaluate the value of
1582 /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1583 /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
1584 /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1587 /// This handles inferences variables within both `param_env` and `substs` by
1588 /// performing the operation on their respective canonical forms.
1589 pub fn const_eval_resolve(
1591 param_env
: ty
::ParamEnv
<'tcx
>,
1592 unevaluated
: ty
::Unevaluated
<'tcx
>,
1594 ) -> EvalToConstValueResult
<'tcx
> {
1595 let mut original_values
= OriginalQueryValues
::default();
1596 let canonical
= self.canonicalize_query((param_env
, unevaluated
), &mut original_values
);
1598 let (param_env
, unevaluated
) = canonical
.value
;
1599 // The return value is the evaluated value which doesn't contain any reference to inference
1600 // variables, thus we don't need to substitute back the original values.
1601 self.tcx
.const_eval_resolve(param_env
, unevaluated
, span
)
1604 /// If `typ` is a type variable of some kind, resolve it one level
1605 /// (but do not resolve types found in the result). If `typ` is
1606 /// not a type variable, just return it unmodified.
1607 // FIXME(eddyb) inline into `ShallowResolver::visit_ty`.
1608 fn shallow_resolve_ty(&self, typ
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1610 ty
::Infer(ty
::TyVar(v
)) => {
1611 // Not entirely obvious: if `typ` is a type variable,
1612 // it can be resolved to an int/float variable, which
1613 // can then be recursively resolved, hence the
1614 // recursion. Note though that we prevent type
1615 // variables from unifying to other type variables
1616 // directly (though they may be embedded
1617 // structurally), and we prevent cycles in any case,
1618 // so this recursion should always be of very limited
1621 // Note: if these two lines are combined into one we get
1622 // dynamic borrow errors on `self.inner`.
1623 let known
= self.inner
.borrow_mut().type_variables().probe(v
).known();
1624 known
.map_or(typ
, |t
| self.shallow_resolve_ty(t
))
1627 ty
::Infer(ty
::IntVar(v
)) => self
1630 .int_unification_table()
1632 .map(|v
| v
.to_type(self.tcx
))
1635 ty
::Infer(ty
::FloatVar(v
)) => self
1638 .float_unification_table()
1640 .map(|v
| v
.to_type(self.tcx
))
1647 /// `ty_or_const_infer_var_changed` is equivalent to one of these two:
1648 /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
1649 /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
1651 /// However, `ty_or_const_infer_var_changed` is more efficient. It's always
1652 /// inlined, despite being large, because it has only two call sites that
1653 /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on`
1654 /// inference variables), and it handles both `Ty` and `ty::Const` without
1655 /// having to resort to storing full `GenericArg`s in `stalled_on`.
1657 pub fn ty_or_const_infer_var_changed(&self, infer_var
: TyOrConstInferVar
<'tcx
>) -> bool
{
1659 TyOrConstInferVar
::Ty(v
) => {
1660 use self::type_variable
::TypeVariableValue
;
1662 // If `inlined_probe` returns a `Known` value, it never equals
1663 // `ty::Infer(ty::TyVar(v))`.
1664 match self.inner
.borrow_mut().type_variables().inlined_probe(v
) {
1665 TypeVariableValue
::Unknown { .. }
=> false,
1666 TypeVariableValue
::Known { .. }
=> true,
1670 TyOrConstInferVar
::TyInt(v
) => {
1671 // If `inlined_probe_value` returns a value it's always a
1672 // `ty::Int(_)` or `ty::UInt(_)`, which never matches a
1674 self.inner
.borrow_mut().int_unification_table().inlined_probe_value(v
).is_some()
1677 TyOrConstInferVar
::TyFloat(v
) => {
1678 // If `probe_value` returns a value it's always a
1679 // `ty::Float(_)`, which never matches a `ty::Infer(_)`.
1681 // Not `inlined_probe_value(v)` because this call site is colder.
1682 self.inner
.borrow_mut().float_unification_table().probe_value(v
).is_some()
1685 TyOrConstInferVar
::Const(v
) => {
1686 // If `probe_value` returns a `Known` value, it never equals
1687 // `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
1689 // Not `inlined_probe_value(v)` because this call site is colder.
1690 match self.inner
.borrow_mut().const_unification_table().probe_value(v
).val
{
1691 ConstVariableValue
::Unknown { .. }
=> false,
1692 ConstVariableValue
::Known { .. }
=> true,
1699 /// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently
1700 /// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
1701 #[derive(Copy, Clone, Debug)]
1702 pub enum TyOrConstInferVar
<'tcx
> {
1703 /// Equivalent to `ty::Infer(ty::TyVar(_))`.
1705 /// Equivalent to `ty::Infer(ty::IntVar(_))`.
1707 /// Equivalent to `ty::Infer(ty::FloatVar(_))`.
1710 /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
1711 Const(ConstVid
<'tcx
>),
1714 impl TyOrConstInferVar
<'tcx
> {
1715 /// Tries to extract an inference variable from a type or a constant, returns `None`
1716 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
1717 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
1718 pub fn maybe_from_generic_arg(arg
: GenericArg
<'tcx
>) -> Option
<Self> {
1719 match arg
.unpack() {
1720 GenericArgKind
::Type(ty
) => Self::maybe_from_ty(ty
),
1721 GenericArgKind
::Const(ct
) => Self::maybe_from_const(ct
),
1722 GenericArgKind
::Lifetime(_
) => None
,
1726 /// Tries to extract an inference variable from a type, returns `None`
1727 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`).
1728 pub fn maybe_from_ty(ty
: Ty
<'tcx
>) -> Option
<Self> {
1730 ty
::Infer(ty
::TyVar(v
)) => Some(TyOrConstInferVar
::Ty(v
)),
1731 ty
::Infer(ty
::IntVar(v
)) => Some(TyOrConstInferVar
::TyInt(v
)),
1732 ty
::Infer(ty
::FloatVar(v
)) => Some(TyOrConstInferVar
::TyFloat(v
)),
1737 /// Tries to extract an inference variable from a constant, returns `None`
1738 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
1739 pub fn maybe_from_const(ct
: &'tcx ty
::Const
<'tcx
>) -> Option
<Self> {
1741 ty
::ConstKind
::Infer(InferConst
::Var(v
)) => Some(TyOrConstInferVar
::Const(v
)),
1747 struct ShallowResolver
<'a
, 'tcx
> {
1748 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
1751 impl<'a
, 'tcx
> TypeFolder
<'tcx
> for ShallowResolver
<'a
, 'tcx
> {
1752 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'tcx
> {
1756 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1757 self.infcx
.shallow_resolve_ty(ty
)
1760 fn fold_const(&mut self, ct
: &'tcx ty
::Const
<'tcx
>) -> &'tcx ty
::Const
<'tcx
> {
1761 if let ty
::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. }
= ct
{
1765 .const_unification_table()
1776 impl<'tcx
> TypeTrace
<'tcx
> {
1777 pub fn span(&self) -> Span
{
1782 cause
: &ObligationCause
<'tcx
>,
1783 a_is_expected
: bool
,
1786 ) -> TypeTrace
<'tcx
> {
1787 TypeTrace { cause: cause.clone(), values: Types(ExpectedFound::new(a_is_expected, a, b)) }
1791 cause
: &ObligationCause
<'tcx
>,
1792 a_is_expected
: bool
,
1793 a
: &'tcx ty
::Const
<'tcx
>,
1794 b
: &'tcx ty
::Const
<'tcx
>,
1795 ) -> TypeTrace
<'tcx
> {
1796 TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) }
1800 impl<'tcx
> SubregionOrigin
<'tcx
> {
1801 pub fn span(&self) -> Span
{
1803 Subtype(ref a
) => a
.span(),
1804 RelateObjectBound(a
) => a
,
1805 RelateParamBound(a
, ..) => a
,
1806 RelateRegionParamBound(a
) => a
,
1808 ReborrowUpvar(a
, _
) => a
,
1809 DataBorrowed(_
, a
) => a
,
1810 ReferenceOutlivesReferent(_
, a
) => a
,
1812 CompareImplMethodObligation { span, .. }
=> span
,
1816 pub fn from_obligation_cause
<F
>(cause
: &traits
::ObligationCause
<'tcx
>, default: F
) -> Self
1818 F
: FnOnce() -> Self,
1821 traits
::ObligationCauseCode
::ReferenceOutlivesReferent(ref_type
) => {
1822 SubregionOrigin
::ReferenceOutlivesReferent(ref_type
, cause
.span
)
1825 traits
::ObligationCauseCode
::CompareImplMethodObligation
{
1829 } => SubregionOrigin
::CompareImplMethodObligation
{
1841 impl RegionVariableOrigin
{
1842 pub fn span(&self) -> Span
{
1849 | EarlyBoundRegion(a
, ..)
1850 | LateBoundRegion(a
, ..)
1851 | UpvarRegion(_
, a
) => a
,
1852 Nll(..) => bug
!("NLL variable used with `span`"),
1857 impl<'tcx
> fmt
::Debug
for RegionObligation
<'tcx
> {
1858 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1861 "RegionObligation(sub_region={:?}, sup_type={:?})",
1862 self.sub_region
, self.sup_type