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
::OpaqueTypeStorage
;
9 pub(crate) use self::undo_log
::{InferCtxtUndoLogs, Snapshot, UndoLog}
;
11 use crate::traits
::{self, ObligationCause, PredicateObligations, TraitEngine, TraitEngineExt}
;
13 use rustc_data_structures
::fx
::FxIndexMap
;
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, ErrorGuaranteed}
;
19 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
20 use rustc_middle
::infer
::canonical
::{Canonical, CanonicalVarValues}
;
21 use rustc_middle
::infer
::unify_key
::{ConstVarValue, ConstVariableValue}
;
22 use rustc_middle
::infer
::unify_key
::{ConstVariableOrigin, ConstVariableOriginKind, ToType}
;
23 use rustc_middle
::mir
::interpret
::{ErrorHandled, EvalToValTreeResult}
;
24 use rustc_middle
::mir
::ConstraintCategory
;
25 use rustc_middle
::traits
::select
;
26 use rustc_middle
::ty
::error
::{ExpectedFound, TypeError}
;
27 use rustc_middle
::ty
::fold
::BoundVarReplacerDelegate
;
28 use rustc_middle
::ty
::fold
::{TypeFoldable, TypeFolder, TypeSuperFoldable}
;
29 use rustc_middle
::ty
::relate
::RelateResult
;
30 use rustc_middle
::ty
::subst
::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}
;
31 use rustc_middle
::ty
::visit
::TypeVisitable
;
32 pub use rustc_middle
::ty
::IntVarValue
;
33 use rustc_middle
::ty
::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}
;
34 use rustc_middle
::ty
::{ConstVid, FloatVid, IntVid, TyVid}
;
35 use rustc_span
::symbol
::Symbol
;
38 use std
::cell
::{Cell, RefCell}
;
41 use self::combine
::CombineFields
;
42 use self::error_reporting
::TypeErrCtxt
;
43 use self::free_regions
::RegionRelations
;
44 use self::lexical_region_resolve
::LexicalRegionResolutions
;
45 use self::outlives
::env
::OutlivesEnvironment
;
46 use self::region_constraints
::{GenericKind, RegionConstraintData, VarInfos, VerifyBound}
;
47 use self::region_constraints
::{
48 RegionConstraintCollector
, RegionConstraintStorage
, RegionSnapshot
,
50 use self::type_variable
::{TypeVariableOrigin, TypeVariableOriginKind}
;
56 pub mod error_reporting
;
63 mod lexical_region_resolve
;
69 pub mod region_constraints
;
72 pub mod type_variable
;
77 pub struct InferOk
<'tcx
, T
> {
79 pub obligations
: PredicateObligations
<'tcx
>,
81 pub type InferResult
<'tcx
, T
> = Result
<InferOk
<'tcx
, T
>, TypeError
<'tcx
>>;
83 pub type UnitResult
<'tcx
> = RelateResult
<'tcx
, ()>; // "unify result"
84 pub type FixupResult
<'tcx
, T
> = Result
<T
, FixupError
<'tcx
>>; // "fixup result"
86 pub(crate) type UnificationTable
<'a
, 'tcx
, T
> = ut
::UnificationTable
<
87 ut
::InPlace
<T
, &'a
mut ut
::UnificationStorage
<T
>, &'a
mut InferCtxtUndoLogs
<'tcx
>>,
90 /// This type contains all the things within `InferCtxt` that sit within a
91 /// `RefCell` and are involved with taking/rolling back snapshots. Snapshot
92 /// operations are hot enough that we want only one call to `borrow_mut` per
93 /// call to `start_snapshot` and `rollback_to`.
95 pub struct InferCtxtInner
<'tcx
> {
96 /// Cache for projections. This cache is snapshotted along with the infcx.
98 /// Public so that `traits::project` can use it.
99 pub projection_cache
: traits
::ProjectionCacheStorage
<'tcx
>,
101 /// We instantiate `UnificationTable` with `bounds<Ty>` because the types
102 /// that might instantiate a general type variable have an order,
103 /// represented by its upper and lower bounds.
104 type_variable_storage
: type_variable
::TypeVariableStorage
<'tcx
>,
106 /// Map from const parameter variable to the kind of const it represents.
107 const_unification_storage
: ut
::UnificationTableStorage
<ty
::ConstVid
<'tcx
>>,
109 /// Map from integral variable to the kind of integer it represents.
110 int_unification_storage
: ut
::UnificationTableStorage
<ty
::IntVid
>,
112 /// Map from floating variable to the kind of float it represents.
113 float_unification_storage
: ut
::UnificationTableStorage
<ty
::FloatVid
>,
115 /// Tracks the set of region variables and the constraints between them.
116 /// This is initially `Some(_)` but when
117 /// `resolve_regions_and_report_errors` is invoked, this gets set to `None`
118 /// -- further attempts to perform unification, etc., may fail if new
119 /// region constraints would've been added.
120 region_constraint_storage
: Option
<RegionConstraintStorage
<'tcx
>>,
122 /// A set of constraints that regionck must validate. Each
123 /// constraint has the form `T:'a`, meaning "some type `T` must
124 /// outlive the lifetime 'a". These constraints derive from
125 /// instantiated type parameters. So if you had a struct defined
127 /// ```ignore (illustrative)
128 /// struct Foo<T:'static> { ... }
130 /// then in some expression `let x = Foo { ... }` it will
131 /// instantiate the type parameter `T` with a fresh type `$0`. At
132 /// the same time, it will record a region obligation of
133 /// `$0:'static`. This will get checked later by regionck. (We
134 /// can't generally check these things right away because we have
135 /// to wait until types are resolved.)
137 /// These are stored in a map keyed to the id of the innermost
138 /// enclosing fn body / static initializer expression. This is
139 /// because the location where the obligation was incurred can be
140 /// relevant with respect to which sublifetime assumptions are in
141 /// place. The reason that we store under the fn-id, and not
142 /// something more fine-grained, is so that it is easier for
143 /// regionck to be sure that it has found *all* the region
144 /// obligations (otherwise, it's easy to fail to walk to a
145 /// particular node-id).
147 /// Before running `resolve_regions_and_report_errors`, the creator
148 /// of the inference context is expected to invoke
149 /// [`InferCtxt::process_registered_region_obligations`]
150 /// for each body-id in this map, which will process the
151 /// obligations within. This is expected to be done 'late enough'
152 /// that all type inference variables have been bound and so forth.
153 region_obligations
: Vec
<RegionObligation
<'tcx
>>,
155 undo_log
: InferCtxtUndoLogs
<'tcx
>,
157 /// Caches for opaque type inference.
158 pub opaque_type_storage
: OpaqueTypeStorage
<'tcx
>,
161 impl<'tcx
> InferCtxtInner
<'tcx
> {
162 fn new() -> InferCtxtInner
<'tcx
> {
164 projection_cache
: Default
::default(),
165 type_variable_storage
: type_variable
::TypeVariableStorage
::new(),
166 undo_log
: InferCtxtUndoLogs
::default(),
167 const_unification_storage
: ut
::UnificationTableStorage
::new(),
168 int_unification_storage
: ut
::UnificationTableStorage
::new(),
169 float_unification_storage
: ut
::UnificationTableStorage
::new(),
170 region_constraint_storage
: Some(RegionConstraintStorage
::new()),
171 region_obligations
: vec
![],
172 opaque_type_storage
: Default
::default(),
177 pub fn region_obligations(&self) -> &[RegionObligation
<'tcx
>] {
178 &self.region_obligations
182 pub fn projection_cache(&mut self) -> traits
::ProjectionCache
<'_
, 'tcx
> {
183 self.projection_cache
.with_log(&mut self.undo_log
)
187 fn type_variables(&mut self) -> type_variable
::TypeVariableTable
<'_
, 'tcx
> {
188 self.type_variable_storage
.with_log(&mut self.undo_log
)
192 pub fn opaque_types(&mut self) -> opaque_types
::OpaqueTypeTable
<'_
, 'tcx
> {
193 self.opaque_type_storage
.with_log(&mut self.undo_log
)
197 fn int_unification_table(
199 ) -> ut
::UnificationTable
<
202 &mut ut
::UnificationStorage
<ty
::IntVid
>,
203 &mut InferCtxtUndoLogs
<'tcx
>,
206 self.int_unification_storage
.with_log(&mut self.undo_log
)
210 fn float_unification_table(
212 ) -> ut
::UnificationTable
<
215 &mut ut
::UnificationStorage
<ty
::FloatVid
>,
216 &mut InferCtxtUndoLogs
<'tcx
>,
219 self.float_unification_storage
.with_log(&mut self.undo_log
)
223 fn const_unification_table(
225 ) -> ut
::UnificationTable
<
228 &mut ut
::UnificationStorage
<ty
::ConstVid
<'tcx
>>,
229 &mut InferCtxtUndoLogs
<'tcx
>,
232 self.const_unification_storage
.with_log(&mut self.undo_log
)
236 pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector
<'_
, 'tcx
> {
237 self.region_constraint_storage
239 .expect("region constraints already solved")
240 .with_log(&mut self.undo_log
)
244 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
245 pub enum DefiningAnchor
{
246 /// `DefId` of the item.
248 /// When opaque types are not resolved, we `Bubble` up, meaning
249 /// return the opaque/hidden type pair from query, for caller of query to handle it.
251 /// Used to catch type mismatch errors when handling opaque types.
255 pub struct InferCtxt
<'tcx
> {
256 pub tcx
: TyCtxt
<'tcx
>,
258 /// The `DefId` of the item in whose context we are performing inference or typeck.
259 /// It is used to check whether an opaque type use is a defining use.
261 /// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
262 /// the obligation. This frequently happens for
263 /// short lived InferCtxt within queries. The opaque type obligations are forwarded
264 /// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
266 /// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
267 /// might come up during inference or typeck.
268 pub defining_use_anchor
: DefiningAnchor
,
270 /// Whether this inference context should care about region obligations in
271 /// the root universe. Most notably, this is used during hir typeck as region
272 /// solving is left to borrowck instead.
273 pub considering_regions
: bool
,
275 pub inner
: RefCell
<InferCtxtInner
<'tcx
>>,
277 /// If set, this flag causes us to skip the 'leak check' during
278 /// higher-ranked subtyping operations. This flag is a temporary one used
279 /// to manage the removal of the leak-check: for the time being, we still run the
280 /// leak-check, but we issue warnings. This flag can only be set to true
281 /// when entering a snapshot.
282 skip_leak_check
: Cell
<bool
>,
284 /// Once region inference is done, the values for each variable.
285 lexical_region_resolutions
: RefCell
<Option
<LexicalRegionResolutions
<'tcx
>>>,
287 /// Caches the results of trait selection. This cache is used
288 /// for things that have to do with the parameters in scope.
289 pub selection_cache
: select
::SelectionCache
<'tcx
>,
291 /// Caches the results of trait evaluation.
292 pub evaluation_cache
: select
::EvaluationCache
<'tcx
>,
294 /// the set of predicates on which errors have been reported, to
295 /// avoid reporting the same error twice.
296 pub reported_trait_errors
: RefCell
<FxIndexMap
<Span
, Vec
<ty
::Predicate
<'tcx
>>>>,
298 pub reported_closure_mismatch
: RefCell
<FxHashSet
<(Span
, Option
<Span
>)>>,
300 /// When an error occurs, we want to avoid reporting "derived"
301 /// errors that are due to this original failure. Normally, we
302 /// handle this with the `err_count_on_creation` count, which
303 /// basically just tracks how many errors were reported when we
304 /// started type-checking a fn and checks to see if any new errors
305 /// have been reported since then. Not great, but it works.
307 /// However, when errors originated in other passes -- notably
308 /// resolve -- this heuristic breaks down. Therefore, we have this
309 /// auxiliary flag that one can set whenever one creates a
310 /// type-error that is due to an error in a prior pass.
312 /// Don't read this flag directly, call `is_tainted_by_errors()`
313 /// and `set_tainted_by_errors()`.
314 tainted_by_errors
: Cell
<Option
<ErrorGuaranteed
>>,
316 /// Track how many errors were reported when this infcx is created.
317 /// If the number of errors increases, that's also a sign (line
318 /// `tainted_by_errors`) to avoid reporting certain kinds of errors.
319 // FIXME(matthewjasper) Merge into `tainted_by_errors`
320 err_count_on_creation
: usize,
322 /// This flag is true while there is an active snapshot.
323 in_snapshot
: Cell
<bool
>,
325 /// What is the innermost universe we have created? Starts out as
326 /// `UniverseIndex::root()` but grows from there as we enter
327 /// universal quantifiers.
329 /// N.B., at present, we exclude the universal quantifiers on the
330 /// item we are type-checking, and just consider those names as
331 /// part of the root universe. So this would only get incremented
332 /// when we enter into a higher-ranked (`for<..>`) type or trait
334 universe
: Cell
<ty
::UniverseIndex
>,
336 /// During coherence we have to assume that other crates may add
337 /// additional impls which we currently don't know about.
339 /// To deal with this evaluation should be conservative
340 /// and consider the possibility of impls from outside this crate.
341 /// This comes up primarily when resolving ambiguity. Imagine
342 /// there is some trait reference `$0: Bar` where `$0` is an
343 /// inference variable. If `intercrate` is true, then we can never
344 /// say for sure that this reference is not implemented, even if
345 /// there are *no impls at all for `Bar`*, because `$0` could be
346 /// bound to some type that in a downstream crate that implements
349 /// Outside of coherence we set this to false because we are only
350 /// interested in types that the user could actually have written.
351 /// In other words, we consider `$0: Bar` to be unimplemented if
352 /// there is no type that the user could *actually name* that
353 /// would satisfy it. This avoids crippling inference, basically.
354 pub intercrate
: bool
,
357 /// See the `error_reporting` module for more details.
358 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
359 pub enum ValuePairs
<'tcx
> {
360 Regions(ExpectedFound
<ty
::Region
<'tcx
>>),
361 Terms(ExpectedFound
<ty
::Term
<'tcx
>>),
362 TraitRefs(ExpectedFound
<ty
::TraitRef
<'tcx
>>),
363 PolyTraitRefs(ExpectedFound
<ty
::PolyTraitRef
<'tcx
>>),
366 impl<'tcx
> ValuePairs
<'tcx
> {
367 pub fn ty(&self) -> Option
<(Ty
<'tcx
>, Ty
<'tcx
>)> {
368 if let ValuePairs
::Terms(ExpectedFound { expected, found }
) = self
369 && let Some(expected
) = expected
.ty()
370 && let Some(found
) = found
.ty()
372 Some((expected
, found
))
379 /// The trace designates the path through inference that we took to
380 /// encounter an error or subtyping constraint.
382 /// See the `error_reporting` module for more details.
383 #[derive(Clone, Debug)]
384 pub struct TypeTrace
<'tcx
> {
385 pub cause
: ObligationCause
<'tcx
>,
386 pub values
: ValuePairs
<'tcx
>,
389 /// The origin of a `r1 <= r2` constraint.
391 /// See `error_reporting` module for more details
392 #[derive(Clone, Debug)]
393 pub enum SubregionOrigin
<'tcx
> {
394 /// Arose from a subtyping relation
395 Subtype(Box
<TypeTrace
<'tcx
>>),
397 /// When casting `&'a T` to an `&'b Trait` object,
398 /// relating `'a` to `'b`
399 RelateObjectBound(Span
),
401 /// Some type parameter was instantiated with the given type,
402 /// and that type must outlive some region.
403 RelateParamBound(Span
, Ty
<'tcx
>, Option
<Span
>),
405 /// The given region parameter was instantiated with a region
406 /// that must outlive some other region.
407 RelateRegionParamBound(Span
),
409 /// Creating a pointer `b` to contents of another reference
412 /// Creating a pointer `b` to contents of an upvar
413 ReborrowUpvar(Span
, ty
::UpvarId
),
415 /// Data with type `Ty<'tcx>` was borrowed
416 DataBorrowed(Ty
<'tcx
>, Span
),
418 /// (&'a &'b T) where a >= b
419 ReferenceOutlivesReferent(Ty
<'tcx
>, Span
),
421 /// Comparing the signature and requirements of an impl method against
422 /// the containing trait.
423 CompareImplItemObligation
{
425 impl_item_def_id
: LocalDefId
,
426 trait_item_def_id
: DefId
,
429 /// Checking that the bounds of a trait's associated type hold for a given impl
430 CheckAssociatedTypeBounds
{
431 parent
: Box
<SubregionOrigin
<'tcx
>>,
432 impl_item_def_id
: LocalDefId
,
433 trait_item_def_id
: DefId
,
436 AscribeUserTypeProvePredicate(Span
),
439 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
440 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
441 static_assert_size
!(SubregionOrigin
<'_
>, 32);
443 impl<'tcx
> SubregionOrigin
<'tcx
> {
444 pub fn to_constraint_category(&self) -> ConstraintCategory
<'tcx
> {
446 Self::Subtype(type_trace
) => type_trace
.cause
.to_constraint_category(),
447 Self::AscribeUserTypeProvePredicate(span
) => ConstraintCategory
::Predicate(*span
),
448 _
=> ConstraintCategory
::BoringNoLocation
,
453 /// Times when we replace late-bound regions with variables:
454 #[derive(Clone, Copy, Debug)]
455 pub enum LateBoundRegionConversionTime
{
456 /// when a fn is called
459 /// when two higher-ranked types are compared
462 /// when projecting an associated type
463 AssocTypeProjection(DefId
),
466 /// Reasons to create a region inference variable
468 /// See `error_reporting` module for more details
469 #[derive(Copy, Clone, Debug)]
470 pub enum RegionVariableOrigin
{
471 /// Region variables created for ill-categorized reasons,
472 /// mostly indicates places in need of refactoring
475 /// Regions created by a `&P` or `[...]` pattern
478 /// Regions created by `&` operator
481 /// Regions created as part of an autoref of a method receiver
484 /// Regions created as part of an automatic coercion
487 /// Region variables created as the values for early-bound regions
488 EarlyBoundRegion(Span
, Symbol
),
490 /// Region variables created for bound regions
491 /// in a function or method that is called
492 LateBoundRegion(Span
, ty
::BoundRegionKind
, LateBoundRegionConversionTime
),
494 UpvarRegion(ty
::UpvarId
, Span
),
496 /// This origin is used for the inference variables that we create
497 /// during NLL region processing.
498 Nll(NllRegionVariableOrigin
),
501 #[derive(Copy, Clone, Debug)]
502 pub enum NllRegionVariableOrigin
{
503 /// During NLL region processing, we create variables for free
504 /// regions that we encounter in the function signature and
505 /// elsewhere. This origin indices we've got one of those.
508 /// "Universal" instantiation of a higher-ranked region (e.g.,
509 /// from a `for<'a> T` binder). Meant to represent "any region".
510 Placeholder(ty
::PlaceholderRegion
),
513 /// If this is true, then this variable was created to represent a lifetime
514 /// bound in a `for` binder. For example, it might have been created to
515 /// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`.
516 /// Such variables are created when we are trying to figure out if there
517 /// is any valid instantiation of `'a` that could fit into some scenario.
519 /// This is used to inform error reporting: in the case that we are trying to
520 /// determine whether there is any valid instantiation of a `'a` variable that meets
521 /// some constraint C, we want to blame the "source" of that `for` type,
522 /// rather than blaming the source of the constraint C.
527 // FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
528 #[derive(Copy, Clone, Debug)]
529 pub enum FixupError
<'tcx
> {
530 UnresolvedIntTy(IntVid
),
531 UnresolvedFloatTy(FloatVid
),
533 UnresolvedConst(ConstVid
<'tcx
>),
536 /// See the `region_obligations` field for more information.
537 #[derive(Clone, Debug)]
538 pub struct RegionObligation
<'tcx
> {
539 pub sub_region
: ty
::Region
<'tcx
>,
540 pub sup_type
: Ty
<'tcx
>,
541 pub origin
: SubregionOrigin
<'tcx
>,
544 impl<'tcx
> fmt
::Display
for FixupError
<'tcx
> {
545 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
546 use self::FixupError
::*;
549 UnresolvedIntTy(_
) => write
!(
551 "cannot determine the type of this integer; \
552 add a suffix to specify the type explicitly"
554 UnresolvedFloatTy(_
) => write
!(
556 "cannot determine the type of this number; \
557 add a suffix to specify the type explicitly"
559 UnresolvedTy(_
) => write
!(f
, "unconstrained type"),
560 UnresolvedConst(_
) => write
!(f
, "unconstrained const value"),
565 /// Used to configure inference contexts before their creation
566 pub struct InferCtxtBuilder
<'tcx
> {
568 defining_use_anchor
: DefiningAnchor
,
569 considering_regions
: bool
,
570 /// Whether we are in coherence mode.
574 pub trait TyCtxtInferExt
<'tcx
> {
575 fn infer_ctxt(self) -> InferCtxtBuilder
<'tcx
>;
578 impl<'tcx
> TyCtxtInferExt
<'tcx
> for TyCtxt
<'tcx
> {
579 fn infer_ctxt(self) -> InferCtxtBuilder
<'tcx
> {
582 defining_use_anchor
: DefiningAnchor
::Error
,
583 considering_regions
: true,
589 impl<'tcx
> InferCtxtBuilder
<'tcx
> {
590 /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
591 /// you need to call this function. Otherwise the opaque type will be treated opaquely.
593 /// It is only meant to be called in two places, for typeck
594 /// (via `Inherited::build`) and for the inference context used
596 pub fn with_opaque_type_inference(mut self, defining_use_anchor
: DefiningAnchor
) -> Self {
597 self.defining_use_anchor
= defining_use_anchor
;
601 pub fn intercrate(mut self) -> Self {
602 self.intercrate
= true;
606 pub fn ignoring_regions(mut self) -> Self {
607 self.considering_regions
= false;
611 /// Given a canonical value `C` as a starting point, create an
612 /// inference context that contains each of the bound values
613 /// within instantiated as a fresh variable. The `f` closure is
614 /// invoked with the new infcx, along with the instantiated value
615 /// `V` and a substitution `S`. This substitution `S` maps from
616 /// the bound values in `C` to their instantiated values in `V`
617 /// (in other words, `S(C) = V`).
618 pub fn build_with_canonical
<T
>(
621 canonical
: &Canonical
<'tcx
, T
>,
622 ) -> (InferCtxt
<'tcx
>, T
, CanonicalVarValues
<'tcx
>)
624 T
: TypeFoldable
<'tcx
>,
626 let infcx
= self.build();
627 let (value
, subst
) = infcx
.instantiate_canonical_with_fresh_inference_vars(span
, canonical
);
628 (infcx
, value
, subst
)
631 pub fn build(&mut self) -> InferCtxt
<'tcx
> {
632 let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate }
= *self;
637 inner
: RefCell
::new(InferCtxtInner
::new()),
638 lexical_region_resolutions
: RefCell
::new(None
),
639 selection_cache
: Default
::default(),
640 evaluation_cache
: Default
::default(),
641 reported_trait_errors
: Default
::default(),
642 reported_closure_mismatch
: Default
::default(),
643 tainted_by_errors
: Cell
::new(None
),
644 err_count_on_creation
: tcx
.sess
.err_count(),
645 in_snapshot
: Cell
::new(false),
646 skip_leak_check
: Cell
::new(false),
647 universe
: Cell
::new(ty
::UniverseIndex
::ROOT
),
653 impl<'tcx
, T
> InferOk
<'tcx
, T
> {
654 pub fn unit(self) -> InferOk
<'tcx
, ()> {
655 InferOk { value: (), obligations: self.obligations }
658 /// Extracts `value`, registering any obligations into `fulfill_cx`.
659 pub fn into_value_registering_obligations(
661 infcx
: &InferCtxt
<'tcx
>,
662 fulfill_cx
: &mut dyn TraitEngine
<'tcx
>,
664 let InferOk { value, obligations }
= self;
665 fulfill_cx
.register_predicate_obligations(infcx
, obligations
);
670 impl<'tcx
> InferOk
<'tcx
, ()> {
671 pub fn into_obligations(self) -> PredicateObligations
<'tcx
> {
676 #[must_use = "once you start a snapshot, you should always consume it"]
677 pub struct CombinedSnapshot
<'tcx
> {
678 undo_snapshot
: Snapshot
<'tcx
>,
679 region_constraints_snapshot
: RegionSnapshot
,
680 universe
: ty
::UniverseIndex
,
681 was_in_snapshot
: bool
,
684 impl<'tcx
> InferCtxt
<'tcx
> {
685 /// Creates a `TypeErrCtxt` for emitting various inference errors.
686 /// During typeck, use `FnCtxt::err_ctxt` instead.
687 pub fn err_ctxt(&self) -> TypeErrCtxt
<'_
, 'tcx
> {
690 typeck_results
: None
,
691 fallback_has_occurred
: false,
692 normalize_fn_sig
: Box
::new(|fn_sig
| fn_sig
),
696 pub fn is_in_snapshot(&self) -> bool
{
697 self.in_snapshot
.get()
700 pub fn freshen
<T
: TypeFoldable
<'tcx
>>(&self, t
: T
) -> T
{
701 t
.fold_with(&mut self.freshener())
704 /// Returns the origin of the type variable identified by `vid`, or `None`
705 /// if this is not a type variable.
707 /// No attempt is made to resolve `ty`.
708 pub fn type_var_origin(&self, ty
: Ty
<'tcx
>) -> Option
<TypeVariableOrigin
> {
710 ty
::Infer(ty
::TyVar(vid
)) => {
711 Some(*self.inner
.borrow_mut().type_variables().var_origin(vid
))
717 pub fn freshener
<'b
>(&'b
self) -> TypeFreshener
<'b
, 'tcx
> {
718 freshen
::TypeFreshener
::new(self, false)
721 /// Like `freshener`, but does not replace `'static` regions.
722 pub fn freshener_keep_static
<'b
>(&'b
self) -> TypeFreshener
<'b
, 'tcx
> {
723 freshen
::TypeFreshener
::new(self, true)
726 pub fn unsolved_variables(&self) -> Vec
<Ty
<'tcx
>> {
727 let mut inner
= self.inner
.borrow_mut();
728 let mut vars
: Vec
<Ty
<'_
>> = inner
730 .unsolved_variables()
732 .map(|t
| self.tcx
.mk_ty_var(t
))
735 (0..inner
.int_unification_table().len())
736 .map(|i
| ty
::IntVid { index: i as u32 }
)
737 .filter(|&vid
| inner
.int_unification_table().probe_value(vid
).is_none())
738 .map(|v
| self.tcx
.mk_int_var(v
)),
741 (0..inner
.float_unification_table().len())
742 .map(|i
| ty
::FloatVid { index: i as u32 }
)
743 .filter(|&vid
| inner
.float_unification_table().probe_value(vid
).is_none())
744 .map(|v
| self.tcx
.mk_float_var(v
)),
749 fn combine_fields
<'a
>(
751 trace
: TypeTrace
<'tcx
>,
752 param_env
: ty
::ParamEnv
<'tcx
>,
753 define_opaque_types
: bool
,
754 ) -> CombineFields
<'a
, 'tcx
> {
760 obligations
: PredicateObligations
::new(),
765 fn start_snapshot(&self) -> CombinedSnapshot
<'tcx
> {
766 debug
!("start_snapshot()");
768 let in_snapshot
= self.in_snapshot
.replace(true);
770 let mut inner
= self.inner
.borrow_mut();
773 undo_snapshot
: inner
.undo_log
.start_snapshot(),
774 region_constraints_snapshot
: inner
.unwrap_region_constraints().start_snapshot(),
775 universe
: self.universe(),
776 was_in_snapshot
: in_snapshot
,
780 #[instrument(skip(self, snapshot), level = "debug")]
781 fn rollback_to(&self, cause
: &str, snapshot
: CombinedSnapshot
<'tcx
>) {
782 let CombinedSnapshot
{
784 region_constraints_snapshot
,
789 self.in_snapshot
.set(was_in_snapshot
);
790 self.universe
.set(universe
);
792 let mut inner
= self.inner
.borrow_mut();
793 inner
.rollback_to(undo_snapshot
);
794 inner
.unwrap_region_constraints().rollback_to(region_constraints_snapshot
);
797 #[instrument(skip(self, snapshot), level = "debug")]
798 fn commit_from(&self, snapshot
: CombinedSnapshot
<'tcx
>) {
799 let CombinedSnapshot
{
801 region_constraints_snapshot
: _
,
806 self.in_snapshot
.set(was_in_snapshot
);
808 self.inner
.borrow_mut().commit(undo_snapshot
);
811 /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`.
812 #[instrument(skip(self, f), level = "debug")]
813 pub fn commit_if_ok
<T
, E
, F
>(&self, f
: F
) -> Result
<T
, E
>
815 F
: FnOnce(&CombinedSnapshot
<'tcx
>) -> Result
<T
, E
>,
817 let snapshot
= self.start_snapshot();
818 let r
= f(&snapshot
);
819 debug
!("commit_if_ok() -- r.is_ok() = {}", r
.is_ok());
822 self.commit_from(snapshot
);
825 self.rollback_to("commit_if_ok -- error", snapshot
);
831 /// Execute `f` then unroll any bindings it creates.
832 #[instrument(skip(self, f), level = "debug")]
833 pub fn probe
<R
, F
>(&self, f
: F
) -> R
835 F
: FnOnce(&CombinedSnapshot
<'tcx
>) -> R
,
837 let snapshot
= self.start_snapshot();
838 let r
= f(&snapshot
);
839 self.rollback_to("probe", snapshot
);
843 /// If `should_skip` is true, then execute `f` then unroll any bindings it creates.
844 #[instrument(skip(self, f), level = "debug")]
845 pub fn probe_maybe_skip_leak_check
<R
, F
>(&self, should_skip
: bool
, f
: F
) -> R
847 F
: FnOnce(&CombinedSnapshot
<'tcx
>) -> R
,
849 let snapshot
= self.start_snapshot();
850 let was_skip_leak_check
= self.skip_leak_check
.get();
852 self.skip_leak_check
.set(true);
854 let r
= f(&snapshot
);
855 self.rollback_to("probe", snapshot
);
856 self.skip_leak_check
.set(was_skip_leak_check
);
860 /// Scan the constraints produced since `snapshot` began and returns:
862 /// - `None` -- if none of them involve "region outlives" constraints
863 /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder
864 /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders
865 pub fn region_constraints_added_in_snapshot(
867 snapshot
: &CombinedSnapshot
<'tcx
>,
871 .unwrap_region_constraints()
872 .region_constraints_added_in_snapshot(&snapshot
.undo_snapshot
)
875 pub fn opaque_types_added_in_snapshot(&self, snapshot
: &CombinedSnapshot
<'tcx
>) -> bool
{
876 self.inner
.borrow().undo_log
.opaque_types_in_snapshot(&snapshot
.undo_snapshot
)
879 pub fn add_given(&self, sub
: ty
::Region
<'tcx
>, sup
: ty
::RegionVid
) {
880 self.inner
.borrow_mut().unwrap_region_constraints().add_given(sub
, sup
);
883 pub fn can_sub
<T
>(&self, param_env
: ty
::ParamEnv
<'tcx
>, a
: T
, b
: T
) -> UnitResult
<'tcx
>
885 T
: at
::ToTrace
<'tcx
>,
887 let origin
= &ObligationCause
::dummy();
889 self.at(origin
, param_env
).sub(a
, b
).map(|InferOk { obligations: _, .. }
| {
890 // Ignore obligations, since we are unrolling
891 // everything anyway.
896 pub fn can_eq
<T
>(&self, param_env
: ty
::ParamEnv
<'tcx
>, a
: T
, b
: T
) -> UnitResult
<'tcx
>
898 T
: at
::ToTrace
<'tcx
>,
900 let origin
= &ObligationCause
::dummy();
902 self.at(origin
, param_env
).eq(a
, b
).map(|InferOk { obligations: _, .. }
| {
903 // Ignore obligations, since we are unrolling
904 // everything anyway.
909 #[instrument(skip(self), level = "debug")]
912 origin
: SubregionOrigin
<'tcx
>,
916 self.inner
.borrow_mut().unwrap_region_constraints().make_subregion(origin
, a
, b
);
919 /// Require that the region `r` be equal to one of the regions in
920 /// the set `regions`.
921 #[instrument(skip(self), level = "debug")]
922 pub fn member_constraint(
924 key
: ty
::OpaqueTypeKey
<'tcx
>,
925 definition_span
: Span
,
927 region
: ty
::Region
<'tcx
>,
928 in_regions
: &Lrc
<Vec
<ty
::Region
<'tcx
>>>,
930 self.inner
.borrow_mut().unwrap_region_constraints().member_constraint(
939 /// Processes a `Coerce` predicate from the fulfillment context.
940 /// This is NOT the preferred way to handle coercion, which is to
941 /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
943 /// This method here is actually a fallback that winds up being
944 /// invoked when `FnCtxt::coerce` encounters unresolved type variables
945 /// and records a coercion predicate. Presently, this method is equivalent
946 /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
947 /// actually requiring `a <: b`. This is of course a valid coercion,
948 /// but it's not as flexible as `FnCtxt::coerce` would be.
950 /// (We may refactor this in the future, but there are a number of
951 /// practical obstacles. Among other things, `FnCtxt::coerce` presently
952 /// records adjustments that are required on the HIR in order to perform
953 /// the coercion, and we don't currently have a way to manage that.)
954 pub fn coerce_predicate(
956 cause
: &ObligationCause
<'tcx
>,
957 param_env
: ty
::ParamEnv
<'tcx
>,
958 predicate
: ty
::PolyCoercePredicate
<'tcx
>,
959 ) -> Result
<InferResult
<'tcx
, ()>, (TyVid
, TyVid
)> {
960 let subtype_predicate
= predicate
.map_bound(|p
| ty
::SubtypePredicate
{
961 a_is_expected
: false, // when coercing from `a` to `b`, `b` is expected
965 self.subtype_predicate(cause
, param_env
, subtype_predicate
)
968 pub fn subtype_predicate(
970 cause
: &ObligationCause
<'tcx
>,
971 param_env
: ty
::ParamEnv
<'tcx
>,
972 predicate
: ty
::PolySubtypePredicate
<'tcx
>,
973 ) -> Result
<InferResult
<'tcx
, ()>, (TyVid
, TyVid
)> {
974 // Check for two unresolved inference variables, in which case we can
975 // make no progress. This is partly a micro-optimization, but it's
976 // also an opportunity to "sub-unify" the variables. This isn't
977 // *necessary* to prevent cycles, because they would eventually be sub-unified
978 // anyhow during generalization, but it helps with diagnostics (we can detect
979 // earlier that they are sub-unified).
981 // Note that we can just skip the binders here because
982 // type variables can't (at present, at
983 // least) capture any of the things bound by this binder.
985 // Note that this sub here is not just for diagnostics - it has semantic
987 let r_a
= self.shallow_resolve(predicate
.skip_binder().a
);
988 let r_b
= self.shallow_resolve(predicate
.skip_binder().b
);
989 match (r_a
.kind(), r_b
.kind()) {
990 (&ty
::Infer(ty
::TyVar(a_vid
)), &ty
::Infer(ty
::TyVar(b_vid
))) => {
991 self.inner
.borrow_mut().type_variables().sub(a_vid
, b_vid
);
992 return Err((a_vid
, b_vid
));
997 Ok(self.commit_if_ok(|_snapshot
| {
998 let ty
::SubtypePredicate { a_is_expected, a, b }
=
999 self.replace_bound_vars_with_placeholders(predicate
);
1001 let ok
= self.at(cause
, param_env
).sub_exp(a_is_expected
, a
, b
)?
;
1007 pub fn region_outlives_predicate(
1009 cause
: &traits
::ObligationCause
<'tcx
>,
1010 predicate
: ty
::PolyRegionOutlivesPredicate
<'tcx
>,
1012 let ty
::OutlivesPredicate(r_a
, r_b
) = self.replace_bound_vars_with_placeholders(predicate
);
1014 SubregionOrigin
::from_obligation_cause(cause
, || RelateRegionParamBound(cause
.span
));
1015 self.sub_regions(origin
, r_b
, r_a
); // `b : a` ==> `a <= b`
1018 /// Number of type variables created so far.
1019 pub fn num_ty_vars(&self) -> usize {
1020 self.inner
.borrow_mut().type_variables().num_vars()
1023 pub fn next_ty_var_id(&self, origin
: TypeVariableOrigin
) -> TyVid
{
1024 self.inner
.borrow_mut().type_variables().new_var(self.universe(), origin
)
1027 pub fn next_ty_var(&self, origin
: TypeVariableOrigin
) -> Ty
<'tcx
> {
1028 self.tcx
.mk_ty_var(self.next_ty_var_id(origin
))
1031 pub fn next_ty_var_id_in_universe(
1033 origin
: TypeVariableOrigin
,
1034 universe
: ty
::UniverseIndex
,
1036 self.inner
.borrow_mut().type_variables().new_var(universe
, origin
)
1039 pub fn next_ty_var_in_universe(
1041 origin
: TypeVariableOrigin
,
1042 universe
: ty
::UniverseIndex
,
1044 let vid
= self.next_ty_var_id_in_universe(origin
, universe
);
1045 self.tcx
.mk_ty_var(vid
)
1048 pub fn next_const_var(&self, ty
: Ty
<'tcx
>, origin
: ConstVariableOrigin
) -> ty
::Const
<'tcx
> {
1049 self.tcx
.mk_const(self.next_const_var_id(origin
), ty
)
1052 pub fn next_const_var_in_universe(
1055 origin
: ConstVariableOrigin
,
1056 universe
: ty
::UniverseIndex
,
1057 ) -> ty
::Const
<'tcx
> {
1061 .const_unification_table()
1062 .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe }
});
1063 self.tcx
.mk_const(vid
, ty
)
1066 pub fn next_const_var_id(&self, origin
: ConstVariableOrigin
) -> ConstVid
<'tcx
> {
1067 self.inner
.borrow_mut().const_unification_table().new_key(ConstVarValue
{
1069 val
: ConstVariableValue
::Unknown { universe: self.universe() }
,
1073 fn next_int_var_id(&self) -> IntVid
{
1074 self.inner
.borrow_mut().int_unification_table().new_key(None
)
1077 pub fn next_int_var(&self) -> Ty
<'tcx
> {
1078 self.tcx
.mk_int_var(self.next_int_var_id())
1081 fn next_float_var_id(&self) -> FloatVid
{
1082 self.inner
.borrow_mut().float_unification_table().new_key(None
)
1085 pub fn next_float_var(&self) -> Ty
<'tcx
> {
1086 self.tcx
.mk_float_var(self.next_float_var_id())
1089 /// Creates a fresh region variable with the next available index.
1090 /// The variable will be created in the maximum universe created
1091 /// thus far, allowing it to name any region created thus far.
1092 pub fn next_region_var(&self, origin
: RegionVariableOrigin
) -> ty
::Region
<'tcx
> {
1093 self.next_region_var_in_universe(origin
, self.universe())
1096 /// Creates a fresh region variable with the next available index
1097 /// in the given universe; typically, you can use
1098 /// `next_region_var` and just use the maximal universe.
1099 pub fn next_region_var_in_universe(
1101 origin
: RegionVariableOrigin
,
1102 universe
: ty
::UniverseIndex
,
1103 ) -> ty
::Region
<'tcx
> {
1105 self.inner
.borrow_mut().unwrap_region_constraints().new_region_var(universe
, origin
);
1106 self.tcx
.mk_region(ty
::ReVar(region_var
))
1109 /// Return the universe that the region `r` was created in. For
1110 /// most regions (e.g., `'static`, named regions from the user,
1111 /// etc) this is the root universe U0. For inference variables or
1112 /// placeholders, however, it will return the universe which they
1114 pub fn universe_of_region(&self, r
: ty
::Region
<'tcx
>) -> ty
::UniverseIndex
{
1115 self.inner
.borrow_mut().unwrap_region_constraints().universe(r
)
1118 /// Number of region variables created so far.
1119 pub fn num_region_vars(&self) -> usize {
1120 self.inner
.borrow_mut().unwrap_region_constraints().num_region_vars()
1123 /// Just a convenient wrapper of `next_region_var` for using during NLL.
1124 pub fn next_nll_region_var(&self, origin
: NllRegionVariableOrigin
) -> ty
::Region
<'tcx
> {
1125 self.next_region_var(RegionVariableOrigin
::Nll(origin
))
1128 /// Just a convenient wrapper of `next_region_var` for using during NLL.
1129 pub fn next_nll_region_var_in_universe(
1131 origin
: NllRegionVariableOrigin
,
1132 universe
: ty
::UniverseIndex
,
1133 ) -> ty
::Region
<'tcx
> {
1134 self.next_region_var_in_universe(RegionVariableOrigin
::Nll(origin
), universe
)
1137 pub fn var_for_def(&self, span
: Span
, param
: &ty
::GenericParamDef
) -> GenericArg
<'tcx
> {
1139 GenericParamDefKind
::Lifetime
=> {
1140 // Create a region inference variable for the given
1141 // region parameter definition.
1142 self.next_region_var(EarlyBoundRegion(span
, param
.name
)).into()
1144 GenericParamDefKind
::Type { .. }
=> {
1145 // Create a type inference variable for the given
1146 // type parameter definition. The substitutions are
1147 // for actual parameters that may be referred to by
1148 // the default of this type parameter, if it exists.
1149 // e.g., `struct Foo<A, B, C = (A, B)>(...);` when
1150 // used in a path such as `Foo::<T, U>::new()` will
1151 // use an inference variable for `C` with `[T, U]`
1152 // as the substitutions for the default, `(T, U)`.
1153 let ty_var_id
= self.inner
.borrow_mut().type_variables().new_var(
1155 TypeVariableOrigin
{
1156 kind
: TypeVariableOriginKind
::TypeParameterDefinition(
1164 self.tcx
.mk_ty_var(ty_var_id
).into()
1166 GenericParamDefKind
::Const { .. }
=> {
1167 let origin
= ConstVariableOrigin
{
1168 kind
: ConstVariableOriginKind
::ConstParameterDefinition(
1175 self.inner
.borrow_mut().const_unification_table().new_key(ConstVarValue
{
1177 val
: ConstVariableValue
::Unknown { universe: self.universe() }
,
1179 self.tcx
.mk_const(const_var_id
, self.tcx
.type_of(param
.def_id
)).into()
1184 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
1185 /// type/region parameter to a fresh inference variable.
1186 pub fn fresh_substs_for_item(&self, span
: Span
, def_id
: DefId
) -> SubstsRef
<'tcx
> {
1187 InternalSubsts
::for_item(self.tcx
, def_id
, |param
, _
| self.var_for_def(span
, param
))
1190 /// Returns `true` if errors have been reported since this infcx was
1191 /// created. This is sometimes used as a heuristic to skip
1192 /// reporting errors that often occur as a result of earlier
1193 /// errors, but where it's hard to be 100% sure (e.g., unresolved
1194 /// inference variables, regionck errors).
1195 #[must_use = "this method does not have any side effects"]
1196 pub fn tainted_by_errors(&self) -> Option
<ErrorGuaranteed
> {
1198 "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
1199 tainted_by_errors={})",
1200 self.tcx
.sess
.err_count(),
1201 self.err_count_on_creation
,
1202 self.tainted_by_errors
.get().is_some()
1205 if let Some(e
) = self.tainted_by_errors
.get() {
1209 if self.tcx
.sess
.err_count() > self.err_count_on_creation
{
1210 // errors reported since this infcx was made
1211 let e
= self.tcx
.sess
.has_errors().unwrap();
1212 self.set_tainted_by_errors(e
);
1219 /// Set the "tainted by errors" flag to true. We call this when we
1220 /// observe an error from a prior pass.
1221 pub fn set_tainted_by_errors(&self, e
: ErrorGuaranteed
) {
1222 debug
!("set_tainted_by_errors(ErrorGuaranteed)");
1223 self.tainted_by_errors
.set(Some(e
));
1226 pub fn skip_region_resolution(&self) {
1227 let (var_infos
, _
) = {
1228 let mut inner
= self.inner
.borrow_mut();
1229 let inner
= &mut *inner
;
1230 // Note: `inner.region_obligations` may not be empty, because we
1231 // didn't necessarily call `process_registered_region_obligations`.
1232 // This is okay, because that doesn't introduce new vars.
1234 .region_constraint_storage
1236 .expect("regions already resolved")
1237 .with_log(&mut inner
.undo_log
)
1238 .into_infos_and_data()
1241 let lexical_region_resolutions
= LexicalRegionResolutions
{
1242 values
: rustc_index
::vec
::IndexVec
::from_elem_n(
1243 crate::infer
::lexical_region_resolve
::VarValue
::Value(self.tcx
.lifetimes
.re_erased
),
1248 let old_value
= self.lexical_region_resolutions
.replace(Some(lexical_region_resolutions
));
1249 assert
!(old_value
.is_none());
1252 /// Process the region constraints and return any errors that
1253 /// result. After this, no more unification operations should be
1254 /// done -- or the compiler will panic -- but it is legal to use
1255 /// `resolve_vars_if_possible` as well as `fully_resolve`.
1256 pub fn resolve_regions(
1258 outlives_env
: &OutlivesEnvironment
<'tcx
>,
1259 ) -> Vec
<RegionResolutionError
<'tcx
>> {
1260 let (var_infos
, data
) = {
1261 let mut inner
= self.inner
.borrow_mut();
1262 let inner
= &mut *inner
;
1264 self.tainted_by_errors().is_some() || inner
.region_obligations
.is_empty(),
1265 "region_obligations not empty: {:#?}",
1266 inner
.region_obligations
1269 .region_constraint_storage
1271 .expect("regions already resolved")
1272 .with_log(&mut inner
.undo_log
)
1273 .into_infos_and_data()
1276 let region_rels
= &RegionRelations
::new(self.tcx
, outlives_env
.free_region_map());
1278 let (lexical_region_resolutions
, errors
) =
1279 lexical_region_resolve
::resolve(outlives_env
.param_env
, region_rels
, var_infos
, data
);
1281 let old_value
= self.lexical_region_resolutions
.replace(Some(lexical_region_resolutions
));
1282 assert
!(old_value
.is_none());
1286 /// Obtains (and clears) the current set of region
1287 /// constraints. The inference context is still usable: further
1288 /// unifications will simply add new constraints.
1290 /// This method is not meant to be used with normal lexical region
1291 /// resolution. Rather, it is used in the NLL mode as a kind of
1292 /// interim hack: basically we run normal type-check and generate
1293 /// region constraints as normal, but then we take them and
1294 /// translate them into the form that the NLL solver
1295 /// understands. See the NLL module for mode details.
1296 pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData
<'tcx
> {
1298 self.inner
.borrow().region_obligations
.is_empty(),
1299 "region_obligations not empty: {:#?}",
1300 self.inner
.borrow().region_obligations
1303 self.inner
.borrow_mut().unwrap_region_constraints().take_and_reset_data()
1306 /// Gives temporary access to the region constraint data.
1307 pub fn with_region_constraints
<R
>(
1309 op
: impl FnOnce(&RegionConstraintData
<'tcx
>) -> R
,
1311 let mut inner
= self.inner
.borrow_mut();
1312 op(inner
.unwrap_region_constraints().data())
1315 pub fn region_var_origin(&self, vid
: ty
::RegionVid
) -> RegionVariableOrigin
{
1316 let mut inner
= self.inner
.borrow_mut();
1317 let inner
= &mut *inner
;
1319 .region_constraint_storage
1321 .expect("regions already resolved")
1322 .with_log(&mut inner
.undo_log
)
1326 /// Takes ownership of the list of variable regions. This implies
1327 /// that all the region constraints have already been taken, and
1328 /// hence that `resolve_regions_and_report_errors` can never be
1329 /// called. This is used only during NLL processing to "hand off" ownership
1330 /// of the set of region variables into the NLL region context.
1331 pub fn take_region_var_origins(&self) -> VarInfos
{
1332 let mut inner
= self.inner
.borrow_mut();
1333 let (var_infos
, data
) = inner
1334 .region_constraint_storage
1336 .expect("regions already resolved")
1337 .with_log(&mut inner
.undo_log
)
1338 .into_infos_and_data();
1339 assert
!(data
.is_empty());
1343 pub fn ty_to_string(&self, t
: Ty
<'tcx
>) -> String
{
1344 self.resolve_vars_if_possible(t
).to_string()
1347 /// If `TyVar(vid)` resolves to a type, return that type. Else, return the
1348 /// universe index of `TyVar(vid)`.
1349 pub fn probe_ty_var(&self, vid
: TyVid
) -> Result
<Ty
<'tcx
>, ty
::UniverseIndex
> {
1350 use self::type_variable
::TypeVariableValue
;
1352 match self.inner
.borrow_mut().type_variables().probe(vid
) {
1353 TypeVariableValue
::Known { value }
=> Ok(value
),
1354 TypeVariableValue
::Unknown { universe }
=> Err(universe
),
1358 /// Resolve any type variables found in `value` -- but only one
1359 /// level. So, if the variable `?X` is bound to some type
1360 /// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
1361 /// itself be bound to a type).
1363 /// Useful when you only need to inspect the outermost level of
1364 /// the type and don't care about nested types (or perhaps you
1365 /// will be resolving them as well, e.g. in a loop).
1366 pub fn shallow_resolve
<T
>(&self, value
: T
) -> T
1368 T
: TypeFoldable
<'tcx
>,
1370 value
.fold_with(&mut ShallowResolver { infcx: self }
)
1373 pub fn root_var(&self, var
: ty
::TyVid
) -> ty
::TyVid
{
1374 self.inner
.borrow_mut().type_variables().root_var(var
)
1377 /// Where possible, replaces type/const variables in
1378 /// `value` with their final value. Note that region variables
1379 /// are unaffected. If a type/const variable has not been unified, it
1380 /// is left as is. This is an idempotent operation that does
1381 /// not affect inference state in any way and so you can do it
1383 pub fn resolve_vars_if_possible
<T
>(&self, value
: T
) -> T
1385 T
: TypeFoldable
<'tcx
>,
1387 if !value
.needs_infer() {
1388 return value
; // Avoid duplicated subst-folding.
1390 let mut r
= resolve
::OpportunisticVarResolver
::new(self);
1391 value
.fold_with(&mut r
)
1394 pub fn resolve_numeric_literals_with_default
<T
>(&self, value
: T
) -> T
1396 T
: TypeFoldable
<'tcx
>,
1398 if !value
.needs_infer() {
1399 return value
; // Avoid duplicated subst-folding.
1401 let mut r
= InferenceLiteralEraser { tcx: self.tcx }
;
1402 value
.fold_with(&mut r
)
1405 /// Returns the first unresolved type or const variable contained in `T`.
1406 pub fn first_unresolved_const_or_ty_var
<T
>(
1409 ) -> Option
<(ty
::Term
<'tcx
>, Option
<Span
>)>
1411 T
: TypeVisitable
<'tcx
>,
1413 value
.visit_with(&mut resolve
::UnresolvedTypeOrConstFinder
::new(self)).break_value()
1416 pub fn probe_const_var(
1418 vid
: ty
::ConstVid
<'tcx
>,
1419 ) -> Result
<ty
::Const
<'tcx
>, ty
::UniverseIndex
> {
1420 match self.inner
.borrow_mut().const_unification_table().probe_value(vid
).val
{
1421 ConstVariableValue
::Known { value }
=> Ok(value
),
1422 ConstVariableValue
::Unknown { universe }
=> Err(universe
),
1426 pub fn fully_resolve
<T
: TypeFoldable
<'tcx
>>(&self, value
: T
) -> FixupResult
<'tcx
, T
> {
1428 * Attempts to resolve all type/region/const variables in
1429 * `value`. Region inference must have been run already (e.g.,
1430 * by calling `resolve_regions_and_report_errors`). If some
1431 * variable was never unified, an `Err` results.
1433 * This method is idempotent, but it not typically not invoked
1434 * except during the writeback phase.
1437 let value
= resolve
::fully_resolve(self, value
);
1439 value
.as_ref().map_or(true, |value
| !value
.needs_infer()),
1440 "`{value:?}` is not fully resolved"
1445 pub fn replace_bound_vars_with_fresh_vars
<T
>(
1448 lbrct
: LateBoundRegionConversionTime
,
1449 value
: ty
::Binder
<'tcx
, T
>,
1452 T
: TypeFoldable
<'tcx
> + Copy
,
1454 if let Some(inner
) = value
.no_bound_vars() {
1458 struct ToFreshVars
<'a
, 'tcx
> {
1459 infcx
: &'a InferCtxt
<'tcx
>,
1461 lbrct
: LateBoundRegionConversionTime
,
1462 map
: FxHashMap
<ty
::BoundVar
, ty
::GenericArg
<'tcx
>>,
1465 impl<'tcx
> BoundVarReplacerDelegate
<'tcx
> for ToFreshVars
<'_
, 'tcx
> {
1466 fn replace_region(&mut self, br
: ty
::BoundRegion
) -> ty
::Region
<'tcx
> {
1469 .or_insert_with(|| {
1471 .next_region_var(LateBoundRegion(self.span
, br
.kind
, self.lbrct
))
1476 fn replace_ty(&mut self, bt
: ty
::BoundTy
) -> Ty
<'tcx
> {
1479 .or_insert_with(|| {
1481 .next_ty_var(TypeVariableOrigin
{
1482 kind
: TypeVariableOriginKind
::MiscVariable
,
1489 fn replace_const(&mut self, bv
: ty
::BoundVar
, ty
: Ty
<'tcx
>) -> ty
::Const
<'tcx
> {
1492 .or_insert_with(|| {
1496 ConstVariableOrigin
{
1497 kind
: ConstVariableOriginKind
::MiscVariable
,
1506 let delegate
= ToFreshVars { infcx: self, span, lbrct, map: Default::default() }
;
1507 self.tcx
.replace_bound_vars_uncached(value
, delegate
)
1510 /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method.
1511 pub fn verify_generic_bound(
1513 origin
: SubregionOrigin
<'tcx
>,
1514 kind
: GenericKind
<'tcx
>,
1515 a
: ty
::Region
<'tcx
>,
1516 bound
: VerifyBound
<'tcx
>,
1518 debug
!("verify_generic_bound({:?}, {:?} <: {:?})", kind
, a
, bound
);
1522 .unwrap_region_constraints()
1523 .verify_generic_bound(origin
, kind
, a
, bound
);
1526 /// Obtains the latest type of the given closure; this may be a
1527 /// closure in the current function, in which case its
1528 /// `ClosureKind` may not yet be known.
1529 pub fn closure_kind(&self, closure_substs
: SubstsRef
<'tcx
>) -> Option
<ty
::ClosureKind
> {
1530 let closure_kind_ty
= closure_substs
.as_closure().kind_ty();
1531 let closure_kind_ty
= self.shallow_resolve(closure_kind_ty
);
1532 closure_kind_ty
.to_opt_closure_kind()
1535 /// Clears the selection, evaluation, and projection caches. This is useful when
1536 /// repeatedly attempting to select an `Obligation` while changing only
1537 /// its `ParamEnv`, since `FulfillmentContext` doesn't use probing.
1538 pub fn clear_caches(&self) {
1539 self.selection_cache
.clear();
1540 self.evaluation_cache
.clear();
1541 self.inner
.borrow_mut().projection_cache().clear();
1544 pub fn universe(&self) -> ty
::UniverseIndex
{
1548 /// Creates and return a fresh universe that extends all previous
1549 /// universes. Updates `self.universe` to that new universe.
1550 pub fn create_next_universe(&self) -> ty
::UniverseIndex
{
1551 let u
= self.universe
.get().next_universe();
1552 self.universe
.set(u
);
1556 pub fn try_const_eval_resolve(
1558 param_env
: ty
::ParamEnv
<'tcx
>,
1559 unevaluated
: ty
::UnevaluatedConst
<'tcx
>,
1562 ) -> Result
<ty
::Const
<'tcx
>, ErrorHandled
> {
1563 match self.const_eval_resolve(param_env
, unevaluated
, span
) {
1564 Ok(Some(val
)) => Ok(self.tcx
.mk_const(val
, ty
)),
1567 let def_id
= unevaluated
.def
.did
;
1569 tcx
.def_span(def_id
),
1570 "unable to construct a constant value for the unevaluated constant {:?}",
1574 Err(err
) => Err(err
),
1578 /// Resolves and evaluates a constant.
1580 /// The constant can be located on a trait like `<A as B>::C`, in which case the given
1581 /// substitutions and environment are used to resolve the constant. Alternatively if the
1582 /// constant has generic parameters in scope the substitutions are used to evaluate the value of
1583 /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1584 /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
1585 /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1588 /// This handles inferences variables within both `param_env` and `substs` by
1589 /// performing the operation on their respective canonical forms.
1590 #[instrument(skip(self), level = "debug")]
1591 pub fn const_eval_resolve(
1593 mut param_env
: ty
::ParamEnv
<'tcx
>,
1594 unevaluated
: ty
::UnevaluatedConst
<'tcx
>,
1596 ) -> EvalToValTreeResult
<'tcx
> {
1597 let mut substs
= self.resolve_vars_if_possible(unevaluated
.substs
);
1600 // Postpone the evaluation of constants whose substs depend on inference
1603 if substs
.has_non_region_infer() {
1604 if let Some(ct
) = tcx
.bound_abstract_const(unevaluated
.def
)?
{
1605 let ct
= tcx
.expand_abstract_consts(ct
.subst(tcx
, substs
));
1606 if let Err(e
) = ct
.error_reported() {
1607 return Err(ErrorHandled
::Reported(e
));
1608 } else if ct
.has_non_region_infer() || ct
.has_non_region_param() {
1609 return Err(ErrorHandled
::TooGeneric
);
1611 substs
= replace_param_and_infer_substs_with_placeholder(tcx
, substs
);
1614 substs
= InternalSubsts
::identity_for_item(tcx
, unevaluated
.def
.did
);
1615 param_env
= tcx
.param_env(unevaluated
.def
.did
);
1619 let param_env_erased
= tcx
.erase_regions(param_env
);
1620 let substs_erased
= tcx
.erase_regions(substs
);
1621 debug
!(?param_env_erased
);
1622 debug
!(?substs_erased
);
1624 let unevaluated
= ty
::UnevaluatedConst { def: unevaluated.def, substs: substs_erased }
;
1626 // The return value is the evaluated value which doesn't contain any reference to inference
1627 // variables, thus we don't need to substitute back the original values.
1628 tcx
.const_eval_resolve_for_typeck(param_env_erased
, unevaluated
, span
)
1631 /// `ty_or_const_infer_var_changed` is equivalent to one of these two:
1632 /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
1633 /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
1635 /// However, `ty_or_const_infer_var_changed` is more efficient. It's always
1636 /// inlined, despite being large, because it has only two call sites that
1637 /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on`
1638 /// inference variables), and it handles both `Ty` and `ty::Const` without
1639 /// having to resort to storing full `GenericArg`s in `stalled_on`.
1641 pub fn ty_or_const_infer_var_changed(&self, infer_var
: TyOrConstInferVar
<'tcx
>) -> bool
{
1643 TyOrConstInferVar
::Ty(v
) => {
1644 use self::type_variable
::TypeVariableValue
;
1646 // If `inlined_probe` returns a `Known` value, it never equals
1647 // `ty::Infer(ty::TyVar(v))`.
1648 match self.inner
.borrow_mut().type_variables().inlined_probe(v
) {
1649 TypeVariableValue
::Unknown { .. }
=> false,
1650 TypeVariableValue
::Known { .. }
=> true,
1654 TyOrConstInferVar
::TyInt(v
) => {
1655 // If `inlined_probe_value` returns a value it's always a
1656 // `ty::Int(_)` or `ty::UInt(_)`, which never matches a
1658 self.inner
.borrow_mut().int_unification_table().inlined_probe_value(v
).is_some()
1661 TyOrConstInferVar
::TyFloat(v
) => {
1662 // If `probe_value` returns a value it's always a
1663 // `ty::Float(_)`, which never matches a `ty::Infer(_)`.
1665 // Not `inlined_probe_value(v)` because this call site is colder.
1666 self.inner
.borrow_mut().float_unification_table().probe_value(v
).is_some()
1669 TyOrConstInferVar
::Const(v
) => {
1670 // If `probe_value` returns a `Known` value, it never equals
1671 // `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
1673 // Not `inlined_probe_value(v)` because this call site is colder.
1674 match self.inner
.borrow_mut().const_unification_table().probe_value(v
).val
{
1675 ConstVariableValue
::Unknown { .. }
=> false,
1676 ConstVariableValue
::Known { .. }
=> true,
1683 impl<'tcx
> TypeErrCtxt
<'_
, 'tcx
> {
1684 /// Process the region constraints and report any errors that
1685 /// result. After this, no more unification operations should be
1686 /// done -- or the compiler will panic -- but it is legal to use
1687 /// `resolve_vars_if_possible` as well as `fully_resolve`.
1689 /// Make sure to call [`InferCtxt::process_registered_region_obligations`]
1690 /// first, or preferably use [`InferCtxt::check_region_obligations_and_report_errors`]
1691 /// to do both of these operations together.
1692 pub fn resolve_regions_and_report_errors(
1694 generic_param_scope
: LocalDefId
,
1695 outlives_env
: &OutlivesEnvironment
<'tcx
>,
1696 ) -> Option
<ErrorGuaranteed
> {
1697 let errors
= self.resolve_regions(outlives_env
);
1699 if let None
= self.tainted_by_errors() {
1700 // As a heuristic, just skip reporting region errors
1701 // altogether if other errors have been reported while
1702 // this infcx was in use. This is totally hokey but
1703 // otherwise we have a hard time separating legit region
1704 // errors from silly ones.
1705 self.report_region_errors(generic_param_scope
, &errors
);
1708 (!errors
.is_empty()).then(|| {
1709 self.tcx
.sess
.delay_span_bug(rustc_span
::DUMMY_SP
, "error should have been emitted")
1713 // [Note-Type-error-reporting]
1714 // An invariant is that anytime the expected or actual type is Error (the special
1715 // error type, meaning that an error occurred when typechecking this expression),
1716 // this is a derived error. The error cascaded from another error (that was already
1717 // reported), so it's not useful to display it to the user.
1718 // The following methods implement this logic.
1719 // They check if either the actual or expected type is Error, and don't print the error
1720 // in this case. The typechecker should only ever report type errors involving mismatched
1721 // types using one of these methods, and should not call span_err directly for such
1724 pub fn type_error_struct_with_diag
<M
>(
1728 actual_ty
: Ty
<'tcx
>,
1729 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
>
1731 M
: FnOnce(String
) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
>,
1733 let actual_ty
= self.resolve_vars_if_possible(actual_ty
);
1734 debug
!("type_error_struct_with_diag({:?}, {:?})", sp
, actual_ty
);
1736 let mut err
= mk_diag(self.ty_to_string(actual_ty
));
1738 // Don't report an error if actual type is `Error`.
1739 if actual_ty
.references_error() {
1740 err
.downgrade_to_delayed_bug();
1746 pub fn report_mismatched_types(
1748 cause
: &ObligationCause
<'tcx
>,
1751 err
: TypeError
<'tcx
>,
1752 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
1753 self.report_and_explain_type_error(TypeTrace
::types(cause
, true, expected
, actual
), err
)
1756 pub fn report_mismatched_consts(
1758 cause
: &ObligationCause
<'tcx
>,
1759 expected
: ty
::Const
<'tcx
>,
1760 actual
: ty
::Const
<'tcx
>,
1761 err
: TypeError
<'tcx
>,
1762 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
1763 self.report_and_explain_type_error(TypeTrace
::consts(cause
, true, expected
, actual
), err
)
1767 /// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently
1768 /// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
1769 #[derive(Copy, Clone, Debug)]
1770 pub enum TyOrConstInferVar
<'tcx
> {
1771 /// Equivalent to `ty::Infer(ty::TyVar(_))`.
1773 /// Equivalent to `ty::Infer(ty::IntVar(_))`.
1775 /// Equivalent to `ty::Infer(ty::FloatVar(_))`.
1778 /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
1779 Const(ConstVid
<'tcx
>),
1782 impl<'tcx
> TyOrConstInferVar
<'tcx
> {
1783 /// Tries to extract an inference variable from a type or a constant, returns `None`
1784 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
1785 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
1786 pub fn maybe_from_generic_arg(arg
: GenericArg
<'tcx
>) -> Option
<Self> {
1787 match arg
.unpack() {
1788 GenericArgKind
::Type(ty
) => Self::maybe_from_ty(ty
),
1789 GenericArgKind
::Const(ct
) => Self::maybe_from_const(ct
),
1790 GenericArgKind
::Lifetime(_
) => None
,
1794 /// Tries to extract an inference variable from a type, returns `None`
1795 /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`).
1796 fn maybe_from_ty(ty
: Ty
<'tcx
>) -> Option
<Self> {
1798 ty
::Infer(ty
::TyVar(v
)) => Some(TyOrConstInferVar
::Ty(v
)),
1799 ty
::Infer(ty
::IntVar(v
)) => Some(TyOrConstInferVar
::TyInt(v
)),
1800 ty
::Infer(ty
::FloatVar(v
)) => Some(TyOrConstInferVar
::TyFloat(v
)),
1805 /// Tries to extract an inference variable from a constant, returns `None`
1806 /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
1807 fn maybe_from_const(ct
: ty
::Const
<'tcx
>) -> Option
<Self> {
1809 ty
::ConstKind
::Infer(InferConst
::Var(v
)) => Some(TyOrConstInferVar
::Const(v
)),
1815 /// Replace `{integer}` with `i32` and `{float}` with `f64`.
1816 /// Used only for diagnostics.
1817 struct InferenceLiteralEraser
<'tcx
> {
1821 impl<'tcx
> TypeFolder
<'tcx
> for InferenceLiteralEraser
<'tcx
> {
1822 fn tcx(&self) -> TyCtxt
<'tcx
> {
1826 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1828 ty
::Infer(ty
::IntVar(_
) | ty
::FreshIntTy(_
)) => self.tcx
.types
.i32,
1829 ty
::Infer(ty
::FloatVar(_
) | ty
::FreshFloatTy(_
)) => self.tcx
.types
.f64,
1830 _
=> ty
.super_fold_with(self),
1835 struct ShallowResolver
<'a
, 'tcx
> {
1836 infcx
: &'a InferCtxt
<'tcx
>,
1839 impl<'a
, 'tcx
> TypeFolder
<'tcx
> for ShallowResolver
<'a
, 'tcx
> {
1840 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'tcx
> {
1844 /// If `ty` is a type variable of some kind, resolve it one level
1845 /// (but do not resolve types found in the result). If `typ` is
1846 /// not a type variable, just return it unmodified.
1847 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1849 ty
::Infer(ty
::TyVar(v
)) => {
1850 // Not entirely obvious: if `typ` is a type variable,
1851 // it can be resolved to an int/float variable, which
1852 // can then be recursively resolved, hence the
1853 // recursion. Note though that we prevent type
1854 // variables from unifying to other type variables
1855 // directly (though they may be embedded
1856 // structurally), and we prevent cycles in any case,
1857 // so this recursion should always be of very limited
1860 // Note: if these two lines are combined into one we get
1861 // dynamic borrow errors on `self.inner`.
1862 let known
= self.infcx
.inner
.borrow_mut().type_variables().probe(v
).known();
1863 known
.map_or(ty
, |t
| self.fold_ty(t
))
1866 ty
::Infer(ty
::IntVar(v
)) => self
1870 .int_unification_table()
1872 .map_or(ty
, |v
| v
.to_type(self.infcx
.tcx
)),
1874 ty
::Infer(ty
::FloatVar(v
)) => self
1878 .float_unification_table()
1880 .map_or(ty
, |v
| v
.to_type(self.infcx
.tcx
)),
1886 fn fold_const(&mut self, ct
: ty
::Const
<'tcx
>) -> ty
::Const
<'tcx
> {
1887 if let ty
::ConstKind
::Infer(InferConst
::Var(vid
)) = ct
.kind() {
1891 .const_unification_table()
1902 impl<'tcx
> TypeTrace
<'tcx
> {
1903 pub fn span(&self) -> Span
{
1908 cause
: &ObligationCause
<'tcx
>,
1909 a_is_expected
: bool
,
1912 ) -> TypeTrace
<'tcx
> {
1914 cause
: cause
.clone(),
1915 values
: Terms(ExpectedFound
::new(a_is_expected
, a
.into(), b
.into())),
1919 pub fn poly_trait_refs(
1920 cause
: &ObligationCause
<'tcx
>,
1921 a_is_expected
: bool
,
1922 a
: ty
::PolyTraitRef
<'tcx
>,
1923 b
: ty
::PolyTraitRef
<'tcx
>,
1924 ) -> TypeTrace
<'tcx
> {
1926 cause
: cause
.clone(),
1927 values
: PolyTraitRefs(ExpectedFound
::new(a_is_expected
, a
.into(), b
.into())),
1932 cause
: &ObligationCause
<'tcx
>,
1933 a_is_expected
: bool
,
1936 ) -> TypeTrace
<'tcx
> {
1938 cause
: cause
.clone(),
1939 values
: Terms(ExpectedFound
::new(a_is_expected
, a
.into(), b
.into())),
1944 impl<'tcx
> SubregionOrigin
<'tcx
> {
1945 pub fn span(&self) -> Span
{
1947 Subtype(ref a
) => a
.span(),
1948 RelateObjectBound(a
) => a
,
1949 RelateParamBound(a
, ..) => a
,
1950 RelateRegionParamBound(a
) => a
,
1952 ReborrowUpvar(a
, _
) => a
,
1953 DataBorrowed(_
, a
) => a
,
1954 ReferenceOutlivesReferent(_
, a
) => a
,
1955 CompareImplItemObligation { span, .. }
=> span
,
1956 AscribeUserTypeProvePredicate(span
) => span
,
1957 CheckAssociatedTypeBounds { ref parent, .. }
=> parent
.span(),
1961 pub fn from_obligation_cause
<F
>(cause
: &traits
::ObligationCause
<'tcx
>, default: F
) -> Self
1963 F
: FnOnce() -> Self,
1965 match *cause
.code() {
1966 traits
::ObligationCauseCode
::ReferenceOutlivesReferent(ref_type
) => {
1967 SubregionOrigin
::ReferenceOutlivesReferent(ref_type
, cause
.span
)
1970 traits
::ObligationCauseCode
::CompareImplItemObligation
{
1974 } => SubregionOrigin
::CompareImplItemObligation
{
1980 traits
::ObligationCauseCode
::CheckAssociatedTypeBounds
{
1983 } => SubregionOrigin
::CheckAssociatedTypeBounds
{
1986 parent
: Box
::new(default()),
1989 traits
::ObligationCauseCode
::AscribeUserTypeProvePredicate(span
) => {
1990 SubregionOrigin
::AscribeUserTypeProvePredicate(span
)
1998 impl RegionVariableOrigin
{
1999 pub fn span(&self) -> Span
{
2006 | EarlyBoundRegion(a
, ..)
2007 | LateBoundRegion(a
, ..)
2008 | UpvarRegion(_
, a
) => a
,
2009 Nll(..) => bug
!("NLL variable used with `span`"),
2014 /// Replaces substs that reference param or infer variables with suitable
2015 /// placeholders. This function is meant to remove these param and infer
2016 /// substs when they're not actually needed to evaluate a constant.
2017 fn replace_param_and_infer_substs_with_placeholder
<'tcx
>(
2019 substs
: SubstsRef
<'tcx
>,
2020 ) -> SubstsRef
<'tcx
> {
2021 tcx
.mk_substs(substs
.iter().enumerate().map(|(idx
, arg
)| {
2022 match arg
.unpack() {
2023 GenericArgKind
::Type(_
) if arg
.has_non_region_param() || arg
.has_non_region_infer() => {
2024 tcx
.mk_ty(ty
::Placeholder(ty
::PlaceholderType
{
2025 universe
: ty
::UniverseIndex
::ROOT
,
2026 name
: ty
::BoundVar
::from_usize(idx
),
2030 GenericArgKind
::Const(ct
) if ct
.has_non_region_infer() || ct
.has_non_region_param() => {
2032 // If the type references param or infer, replace that too...
2033 if ty
.has_non_region_param() || ty
.has_non_region_infer() {
2034 bug
!("const `{ct}`'s type should not reference params or types");
2037 ty
::PlaceholderConst
{
2038 universe
: ty
::UniverseIndex
::ROOT
,
2039 name
: ty
::BoundVar
::from_usize(idx
),