hir_ty/next_solver/infer/
mod.rs

1//! Infer context the next-trait-solver.
2
3use std::cell::{Cell, RefCell};
4use std::fmt;
5use std::sync::Arc;
6
7pub use BoundRegionConversionTime::*;
8pub use at::DefineOpaqueTypes;
9use ena::undo_log::UndoLogs;
10use ena::unify as ut;
11use hir_def::GenericParamId;
12use intern::Symbol;
13use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage};
14use region_constraints::{
15    GenericKind, RegionConstraintCollector, RegionConstraintStorage, UndoLog, VarInfos, VerifyBound,
16};
17pub use relate::StructurallyRelateAliases;
18pub use relate::combine::PredicateEmittingRelation;
19use rustc_hash::{FxHashMap, FxHashSet};
20use rustc_pattern_analysis::Captures;
21use rustc_type_ir::error::{ExpectedFound, TypeError};
22use rustc_type_ir::inherent::{
23    Const as _, GenericArg as _, GenericArgs as _, IntoKind, ParamEnv as _, SliceLike, Term as _,
24    Ty as _,
25};
26use rustc_type_ir::{
27    BoundVar, ClosureKind, ConstVid, FloatTy, FloatVarValue, FloatVid, GenericArgKind, InferConst,
28    InferTy, IntTy, IntVarValue, IntVid, OutlivesPredicate, RegionVid, TyVid, UniverseIndex,
29};
30use rustc_type_ir::{TermKind, TypeVisitableExt};
31use rustc_type_ir::{TypeFoldable, TypeFolder, TypeSuperFoldable};
32use snapshot::undo_log::InferCtxtUndoLogs;
33use tracing::{debug, instrument};
34use traits::{ObligationCause, PredicateObligations};
35use type_variable::TypeVariableOrigin;
36use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
37
38use crate::next_solver::fold::BoundVarReplacerDelegate;
39use crate::next_solver::infer::opaque_types::table::OpaqueTypeStorageEntries;
40use crate::next_solver::{BoundRegion, BoundTy, BoundVarKind};
41
42use super::generics::GenericParamDef;
43use super::{
44    AliasTerm, Binder, BoundRegionKind, CanonicalQueryInput, CanonicalVarValues, Const, ConstKind,
45    DbInterner, ErrorGuaranteed, FxIndexMap, GenericArg, GenericArgs, OpaqueTypeKey, ParamEnv,
46    PlaceholderRegion, PolyCoercePredicate, PolyExistentialProjection, PolyExistentialTraitRef,
47    PolyFnSig, PolyRegionOutlivesPredicate, PolySubtypePredicate, Predicate, Region, SolverDefId,
48    SubtypePredicate, Term, TraitPredicate, TraitRef, Ty, TyKind, TypingMode,
49};
50
51pub mod at;
52pub mod canonical;
53mod context;
54mod opaque_types;
55pub mod region_constraints;
56pub mod relate;
57pub mod resolve;
58pub(crate) mod snapshot;
59pub(crate) mod traits;
60mod type_variable;
61mod unify_key;
62
63/// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper
64/// around `PredicateObligations`, but it has one important property:
65/// because `InferOk` is marked with `#[must_use]`, if you have a method
66/// `InferCtxt::f` that returns `InferResult<()>` and you call it with
67/// `infcx.f()?;` you'll get a warning about the obligations being discarded
68/// without use, which is probably unintentional and has been a source of bugs
69/// in the past.
70#[must_use]
71#[derive(Debug)]
72pub struct InferOk<'db, T> {
73    pub value: T,
74    pub obligations: PredicateObligations<'db>,
75}
76pub type InferResult<'db, T> = Result<InferOk<'db, T>, TypeError<DbInterner<'db>>>;
77
78pub(crate) type FixupResult<T> = Result<T, FixupError>; // "fixup result"
79
80pub(crate) type UnificationTable<'a, 'db, T> = ut::UnificationTable<
81    ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'a mut InferCtxtUndoLogs<'db>>,
82>;
83
84/// This type contains all the things within `InferCtxt` that sit within a
85/// `RefCell` and are involved with taking/rolling back snapshots. Snapshot
86/// operations are hot enough that we want only one call to `borrow_mut` per
87/// call to `start_snapshot` and `rollback_to`.
88#[derive(Clone)]
89pub struct InferCtxtInner<'db> {
90    pub(crate) undo_log: InferCtxtUndoLogs<'db>,
91
92    /// We instantiate `UnificationTable` with `bounds<Ty>` because the types
93    /// that might instantiate a general type variable have an order,
94    /// represented by its upper and lower bounds.
95    pub(crate) type_variable_storage: type_variable::TypeVariableStorage<'db>,
96
97    /// Map from const parameter variable to the kind of const it represents.
98    pub(crate) const_unification_storage: ut::UnificationTableStorage<ConstVidKey<'db>>,
99
100    /// Map from integral variable to the kind of integer it represents.
101    pub(crate) int_unification_storage: ut::UnificationTableStorage<IntVid>,
102
103    /// Map from floating variable to the kind of float it represents.
104    pub(crate) float_unification_storage: ut::UnificationTableStorage<FloatVid>,
105
106    /// Tracks the set of region variables and the constraints between them.
107    ///
108    /// This is initially `Some(_)` but when
109    /// `resolve_regions_and_report_errors` is invoked, this gets set to `None`
110    /// -- further attempts to perform unification, etc., may fail if new
111    /// region constraints would've been added.
112    pub(crate) region_constraint_storage: Option<RegionConstraintStorage<'db>>,
113
114    /// A set of constraints that regionck must validate.
115    ///
116    /// Each constraint has the form `T:'a`, meaning "some type `T` must
117    /// outlive the lifetime 'a". These constraints derive from
118    /// instantiated type parameters. So if you had a struct defined
119    /// like the following:
120    /// ```ignore (illustrative)
121    /// struct Foo<T: 'static> { ... }
122    /// ```
123    /// In some expression `let x = Foo { ... }`, it will
124    /// instantiate the type parameter `T` with a fresh type `$0`. At
125    /// the same time, it will record a region obligation of
126    /// `$0: 'static`. This will get checked later by regionck. (We
127    /// can't generally check these things right away because we have
128    /// to wait until types are resolved.)
129    ///
130    /// These are stored in a map keyed to the id of the innermost
131    /// enclosing fn body / static initializer expression. This is
132    /// because the location where the obligation was incurred can be
133    /// relevant with respect to which sublifetime assumptions are in
134    /// place. The reason that we store under the fn-id, and not
135    /// something more fine-grained, is so that it is easier for
136    /// regionck to be sure that it has found *all* the region
137    /// obligations (otherwise, it's easy to fail to walk to a
138    /// particular node-id).
139    ///
140    /// Before running `resolve_regions_and_report_errors`, the creator
141    /// of the inference context is expected to invoke
142    /// [`InferCtxt::process_registered_region_obligations`]
143    /// for each body-id in this map, which will process the
144    /// obligations within. This is expected to be done 'late enough'
145    /// that all type inference variables have been bound and so forth.
146    pub(crate) region_obligations: Vec<RegionObligation<'db>>,
147
148    /// Caches for opaque type inference.
149    pub(crate) opaque_type_storage: OpaqueTypeStorage<'db>,
150}
151
152impl<'db> InferCtxtInner<'db> {
153    fn new() -> InferCtxtInner<'db> {
154        InferCtxtInner {
155            undo_log: InferCtxtUndoLogs::default(),
156
157            type_variable_storage: Default::default(),
158            const_unification_storage: Default::default(),
159            int_unification_storage: Default::default(),
160            float_unification_storage: Default::default(),
161            region_constraint_storage: Some(Default::default()),
162            region_obligations: vec![],
163            opaque_type_storage: Default::default(),
164        }
165    }
166
167    #[inline]
168    pub fn region_obligations(&self) -> &[RegionObligation<'db>] {
169        &self.region_obligations
170    }
171
172    #[inline]
173    fn try_type_variables_probe_ref(
174        &self,
175        vid: TyVid,
176    ) -> Option<&type_variable::TypeVariableValue<'db>> {
177        // Uses a read-only view of the unification table, this way we don't
178        // need an undo log.
179        self.type_variable_storage.eq_relations_ref().try_probe_value(vid)
180    }
181
182    #[inline]
183    fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'db> {
184        self.type_variable_storage.with_log(&mut self.undo_log)
185    }
186
187    #[inline]
188    pub(crate) fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'db> {
189        self.opaque_type_storage.with_log(&mut self.undo_log)
190    }
191
192    #[inline]
193    fn int_unification_table(&mut self) -> UnificationTable<'_, 'db, IntVid> {
194        self.int_unification_storage.with_log(&mut self.undo_log)
195    }
196
197    #[inline]
198    fn float_unification_table(&mut self) -> UnificationTable<'_, 'db, FloatVid> {
199        self.float_unification_storage.with_log(&mut self.undo_log)
200    }
201
202    #[inline]
203    fn const_unification_table(&mut self) -> UnificationTable<'_, 'db, ConstVidKey<'db>> {
204        self.const_unification_storage.with_log(&mut self.undo_log)
205    }
206
207    #[inline]
208    pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'db, '_> {
209        self.region_constraint_storage
210            .as_mut()
211            .expect("region constraints already solved")
212            .with_log(&mut self.undo_log)
213    }
214}
215
216pub struct InferCtxt<'db> {
217    pub interner: DbInterner<'db>,
218
219    /// The mode of this inference context, see the struct documentation
220    /// for more details.
221    typing_mode: TypingMode<'db>,
222
223    pub inner: RefCell<InferCtxtInner<'db>>,
224
225    /// When an error occurs, we want to avoid reporting "derived"
226    /// errors that are due to this original failure. We have this
227    /// flag that one can set whenever one creates a type-error that
228    /// is due to an error in a prior pass.
229    ///
230    /// Don't read this flag directly, call `is_tainted_by_errors()`
231    /// and `set_tainted_by_errors()`.
232    tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
233
234    /// What is the innermost universe we have created? Starts out as
235    /// `UniverseIndex::root()` but grows from there as we enter
236    /// universal quantifiers.
237    ///
238    /// N.B., at present, we exclude the universal quantifiers on the
239    /// item we are type-checking, and just consider those names as
240    /// part of the root universe. So this would only get incremented
241    /// when we enter into a higher-ranked (`for<..>`) type or trait
242    /// bound.
243    universe: Cell<UniverseIndex>,
244}
245
246/// See the `error_reporting` module for more details.
247#[derive(Clone, Debug, PartialEq, Eq)]
248pub enum ValuePairs<'db> {
249    Regions(ExpectedFound<Region<'db>>),
250    Terms(ExpectedFound<Term<'db>>),
251    Aliases(ExpectedFound<AliasTerm<'db>>),
252    TraitRefs(ExpectedFound<TraitRef<'db>>),
253    PolySigs(ExpectedFound<PolyFnSig<'db>>),
254    ExistentialTraitRef(ExpectedFound<PolyExistentialTraitRef<'db>>),
255    ExistentialProjection(ExpectedFound<PolyExistentialProjection<'db>>),
256}
257
258impl<'db> ValuePairs<'db> {
259    pub fn ty(&self) -> Option<(Ty<'db>, Ty<'db>)> {
260        if let ValuePairs::Terms(ExpectedFound { expected, found }) = self
261            && let Some(expected) = expected.as_type()
262            && let Some(found) = found.as_type()
263        {
264            return Some((expected, found));
265        }
266        None
267    }
268}
269
270/// The trace designates the path through inference that we took to
271/// encounter an error or subtyping constraint.
272///
273/// See the `error_reporting` module for more details.
274#[derive(Clone, Debug)]
275pub struct TypeTrace<'db> {
276    pub cause: ObligationCause,
277    pub values: ValuePairs<'db>,
278}
279
280/// Times when we replace bound regions with existentials:
281#[derive(Clone, Copy, Debug)]
282pub enum BoundRegionConversionTime {
283    /// when a fn is called
284    FnCall,
285
286    /// when two higher-ranked types are compared
287    HigherRankedType,
288
289    /// when projecting an associated type
290    AssocTypeProjection(SolverDefId),
291}
292
293#[derive(Copy, Clone, Debug)]
294pub struct FixupError {
295    unresolved: TyOrConstInferVar,
296}
297
298impl fmt::Display for FixupError {
299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300        use TyOrConstInferVar::*;
301
302        match self.unresolved {
303            TyInt(_) => write!(
304                f,
305                "cannot determine the type of this integer; \
306                 add a suffix to specify the type explicitly"
307            ),
308            TyFloat(_) => write!(
309                f,
310                "cannot determine the type of this number; \
311                 add a suffix to specify the type explicitly"
312            ),
313            Ty(_) => write!(f, "unconstrained type"),
314            Const(_) => write!(f, "unconstrained const value"),
315        }
316    }
317}
318
319/// See the `region_obligations` field for more information.
320#[derive(Clone, Debug)]
321pub struct RegionObligation<'db> {
322    pub sub_region: Region<'db>,
323    pub sup_type: Ty<'db>,
324}
325
326/// Used to configure inference contexts before their creation.
327pub struct InferCtxtBuilder<'db> {
328    interner: DbInterner<'db>,
329}
330
331pub trait DbInternerInferExt<'db> {
332    fn infer_ctxt(self) -> InferCtxtBuilder<'db>;
333}
334
335impl<'db> DbInternerInferExt<'db> for DbInterner<'db> {
336    fn infer_ctxt(self) -> InferCtxtBuilder<'db> {
337        InferCtxtBuilder { interner: self }
338    }
339}
340
341impl<'db> InferCtxtBuilder<'db> {
342    /// Given a canonical value `C` as a starting point, create an
343    /// inference context that contains each of the bound values
344    /// within instantiated as a fresh variable. The `f` closure is
345    /// invoked with the new infcx, along with the instantiated value
346    /// `V` and a instantiation `S`. This instantiation `S` maps from
347    /// the bound values in `C` to their instantiated values in `V`
348    /// (in other words, `S(C) = V`).
349    pub fn build_with_canonical<T>(
350        mut self,
351        input: &CanonicalQueryInput<'db, T>,
352    ) -> (InferCtxt<'db>, T, CanonicalVarValues<'db>)
353    where
354        T: TypeFoldable<DbInterner<'db>>,
355    {
356        let infcx = self.build(input.typing_mode);
357        let (value, args) = infcx.instantiate_canonical(&input.canonical);
358        (infcx, value, args)
359    }
360
361    pub fn build(&mut self, typing_mode: TypingMode<'db>) -> InferCtxt<'db> {
362        let InferCtxtBuilder { interner } = *self;
363        InferCtxt {
364            interner,
365            typing_mode,
366            inner: RefCell::new(InferCtxtInner::new()),
367            tainted_by_errors: Cell::new(None),
368            universe: Cell::new(UniverseIndex::ROOT),
369        }
370    }
371}
372
373impl<'db> InferOk<'db, ()> {
374    pub fn into_obligations(self) -> PredicateObligations<'db> {
375        self.obligations
376    }
377}
378
379impl<'db> InferCtxt<'db> {
380    #[inline(always)]
381    pub fn typing_mode(&self) -> TypingMode<'db> {
382        self.typing_mode
383    }
384
385    #[inline(always)]
386    pub fn typing_mode_unchecked(&self) -> TypingMode<'db> {
387        self.typing_mode
388    }
389
390    pub fn unresolved_variables(&self) -> Vec<Ty<'db>> {
391        let mut inner = self.inner.borrow_mut();
392        let mut vars: Vec<Ty<'db>> = inner
393            .type_variables()
394            .unresolved_variables()
395            .into_iter()
396            .map(|t| Ty::new_var(self.interner, t))
397            .collect();
398        vars.extend(
399            (0..inner.int_unification_table().len())
400                .map(IntVid::from_usize)
401                .filter(|&vid| inner.int_unification_table().probe_value(vid).is_unknown())
402                .map(|v| Ty::new_int_var(self.interner, v)),
403        );
404        vars.extend(
405            (0..inner.float_unification_table().len())
406                .map(FloatVid::from_usize)
407                .filter(|&vid| inner.float_unification_table().probe_value(vid).is_unknown())
408                .map(|v| Ty::new_float_var(self.interner, v)),
409        );
410        vars
411    }
412
413    #[instrument(skip(self), level = "debug")]
414    pub fn sub_regions(&self, a: Region<'db>, b: Region<'db>) {
415        self.inner.borrow_mut().unwrap_region_constraints().make_subregion(a, b);
416    }
417
418    /// Processes a `Coerce` predicate from the fulfillment context.
419    /// This is NOT the preferred way to handle coercion, which is to
420    /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
421    ///
422    /// This method here is actually a fallback that winds up being
423    /// invoked when `FnCtxt::coerce` encounters unresolved type variables
424    /// and records a coercion predicate. Presently, this method is equivalent
425    /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
426    /// actually requiring `a <: b`. This is of course a valid coercion,
427    /// but it's not as flexible as `FnCtxt::coerce` would be.
428    ///
429    /// (We may refactor this in the future, but there are a number of
430    /// practical obstacles. Among other things, `FnCtxt::coerce` presently
431    /// records adjustments that are required on the HIR in order to perform
432    /// the coercion, and we don't currently have a way to manage that.)
433    pub fn coerce_predicate(
434        &self,
435        cause: &ObligationCause,
436        param_env: ParamEnv<'db>,
437        predicate: PolyCoercePredicate<'db>,
438    ) -> Result<InferResult<'db, ()>, (TyVid, TyVid)> {
439        let subtype_predicate = predicate.map_bound(|p| SubtypePredicate {
440            a_is_expected: false, // when coercing from `a` to `b`, `b` is expected
441            a: p.a,
442            b: p.b,
443        });
444        self.subtype_predicate(cause, param_env, subtype_predicate)
445    }
446
447    pub fn subtype_predicate(
448        &self,
449        cause: &ObligationCause,
450        param_env: ParamEnv<'db>,
451        predicate: PolySubtypePredicate<'db>,
452    ) -> Result<InferResult<'db, ()>, (TyVid, TyVid)> {
453        // Check for two unresolved inference variables, in which case we can
454        // make no progress. This is partly a micro-optimization, but it's
455        // also an opportunity to "sub-unify" the variables. This isn't
456        // *necessary* to prevent cycles, because they would eventually be sub-unified
457        // anyhow during generalization, but it helps with diagnostics (we can detect
458        // earlier that they are sub-unified).
459        //
460        // Note that we can just skip the binders here because
461        // type variables can't (at present, at
462        // least) capture any of the things bound by this binder.
463        //
464        // Note that this sub here is not just for diagnostics - it has semantic
465        // effects as well.
466        let r_a = self.shallow_resolve(predicate.skip_binder().a);
467        let r_b = self.shallow_resolve(predicate.skip_binder().b);
468        match (r_a.kind(), r_b.kind()) {
469            (TyKind::Infer(InferTy::TyVar(a_vid)), TyKind::Infer(InferTy::TyVar(b_vid))) => {
470                return Err((a_vid, b_vid));
471            }
472            _ => {}
473        }
474
475        self.enter_forall(predicate, |SubtypePredicate { a_is_expected, a, b }| {
476            if a_is_expected {
477                Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
478            } else {
479                Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
480            }
481        })
482    }
483
484    pub fn region_outlives_predicate(
485        &self,
486        cause: &traits::ObligationCause,
487        predicate: PolyRegionOutlivesPredicate<'db>,
488    ) {
489        self.enter_forall(predicate, |OutlivesPredicate(r_a, r_b)| {
490            self.sub_regions(r_b, r_a); // `b : a` ==> `a <= b`
491        })
492    }
493
494    /// Number of type variables created so far.
495    pub fn num_ty_vars(&self) -> usize {
496        self.inner.borrow_mut().type_variables().num_vars()
497    }
498
499    pub fn next_ty_var(&self) -> Ty<'db> {
500        self.next_ty_var_with_origin(TypeVariableOrigin { param_def_id: None })
501    }
502
503    pub fn next_ty_var_with_origin(&self, origin: TypeVariableOrigin) -> Ty<'db> {
504        let vid = self.inner.borrow_mut().type_variables().new_var(self.universe(), origin);
505        Ty::new_var(self.interner, vid)
506    }
507
508    pub fn next_ty_var_id_in_universe(&self, universe: UniverseIndex) -> TyVid {
509        let origin = TypeVariableOrigin { param_def_id: None };
510        self.inner.borrow_mut().type_variables().new_var(universe, origin)
511    }
512
513    pub fn next_ty_var_in_universe(&self, universe: UniverseIndex) -> Ty<'db> {
514        let vid = self.next_ty_var_id_in_universe(universe);
515        Ty::new_var(self.interner, vid)
516    }
517
518    pub fn next_const_var(&self) -> Const<'db> {
519        self.next_const_var_with_origin(ConstVariableOrigin { param_def_id: None })
520    }
521
522    pub fn next_const_var_with_origin(&self, origin: ConstVariableOrigin) -> Const<'db> {
523        let vid = self
524            .inner
525            .borrow_mut()
526            .const_unification_table()
527            .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
528            .vid;
529        Const::new_var(self.interner, vid)
530    }
531
532    pub fn next_const_var_in_universe(&self, universe: UniverseIndex) -> Const<'db> {
533        let origin = ConstVariableOrigin { param_def_id: None };
534        let vid = self
535            .inner
536            .borrow_mut()
537            .const_unification_table()
538            .new_key(ConstVariableValue::Unknown { origin, universe })
539            .vid;
540        Const::new_var(self.interner, vid)
541    }
542
543    pub fn next_int_var(&self) -> Ty<'db> {
544        let next_int_var_id =
545            self.inner.borrow_mut().int_unification_table().new_key(IntVarValue::Unknown);
546        Ty::new_int_var(self.interner, next_int_var_id)
547    }
548
549    pub fn next_float_var(&self) -> Ty<'db> {
550        let next_float_var_id =
551            self.inner.borrow_mut().float_unification_table().new_key(FloatVarValue::Unknown);
552        Ty::new_float_var(self.interner, next_float_var_id)
553    }
554
555    /// Creates a fresh region variable with the next available index.
556    /// The variable will be created in the maximum universe created
557    /// thus far, allowing it to name any region created thus far.
558    pub fn next_region_var(&self) -> Region<'db> {
559        self.next_region_var_in_universe(self.universe())
560    }
561
562    /// Creates a fresh region variable with the next available index
563    /// in the given universe; typically, you can use
564    /// `next_region_var` and just use the maximal universe.
565    pub fn next_region_var_in_universe(&self, universe: UniverseIndex) -> Region<'db> {
566        let region_var =
567            self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe);
568        Region::new_var(self.interner, region_var)
569    }
570
571    pub fn next_term_var_of_kind(&self, term: Term<'db>) -> Term<'db> {
572        match term.kind() {
573            TermKind::Ty(_) => self.next_ty_var().into(),
574            TermKind::Const(_) => self.next_const_var().into(),
575        }
576    }
577
578    /// Return the universe that the region `r` was created in. For
579    /// most regions (e.g., `'static`, named regions from the user,
580    /// etc) this is the root universe U0. For inference variables or
581    /// placeholders, however, it will return the universe which they
582    /// are associated.
583    pub fn universe_of_region(&self, r: Region<'db>) -> UniverseIndex {
584        self.inner.borrow_mut().unwrap_region_constraints().universe(r)
585    }
586
587    /// Number of region variables created so far.
588    pub fn num_region_vars(&self) -> usize {
589        self.inner.borrow_mut().unwrap_region_constraints().num_region_vars()
590    }
591
592    /// Just a convenient wrapper of `next_region_var` for using during NLL.
593    #[instrument(skip(self), level = "debug")]
594    pub fn next_nll_region_var(&self) -> Region<'db> {
595        self.next_region_var()
596    }
597
598    /// Just a convenient wrapper of `next_region_var` for using during NLL.
599    #[instrument(skip(self), level = "debug")]
600    pub fn next_nll_region_var_in_universe(&self, universe: UniverseIndex) -> Region<'db> {
601        self.next_region_var_in_universe(universe)
602    }
603
604    fn var_for_def(&self, id: GenericParamId, name: &Symbol) -> GenericArg<'db> {
605        match id {
606            GenericParamId::LifetimeParamId(_) => {
607                // Create a region inference variable for the given
608                // region parameter definition.
609                self.next_region_var().into()
610            }
611            GenericParamId::TypeParamId(_) => {
612                // Create a type inference variable for the given
613                // type parameter definition. The generic parameters are
614                // for actual parameters that may be referred to by
615                // the default of this type parameter, if it exists.
616                // e.g., `struct Foo<A, B, C = (A, B)>(...);` when
617                // used in a path such as `Foo::<T, U>::new()` will
618                // use an inference variable for `C` with `[T, U]`
619                // as the generic parameters for the default, `(T, U)`.
620                let ty_var_id = self
621                    .inner
622                    .borrow_mut()
623                    .type_variables()
624                    .new_var(self.universe(), TypeVariableOrigin { param_def_id: None });
625
626                Ty::new_var(self.interner, ty_var_id).into()
627            }
628            GenericParamId::ConstParamId(_) => {
629                let origin = ConstVariableOrigin { param_def_id: None };
630                let const_var_id = self
631                    .inner
632                    .borrow_mut()
633                    .const_unification_table()
634                    .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
635                    .vid;
636                Const::new_var(self.interner, const_var_id).into()
637            }
638        }
639    }
640
641    /// Given a set of generics defined on a type or impl, returns the generic parameters mapping
642    /// each type/region parameter to a fresh inference variable.
643    pub fn fresh_args_for_item(&self, def_id: SolverDefId) -> GenericArgs<'db> {
644        GenericArgs::for_item(self.interner, def_id, |name, index, kind, _| {
645            self.var_for_def(kind, name)
646        })
647    }
648
649    /// Returns `true` if errors have been reported since this infcx was
650    /// created. This is sometimes used as a heuristic to skip
651    /// reporting errors that often occur as a result of earlier
652    /// errors, but where it's hard to be 100% sure (e.g., unresolved
653    /// inference variables, regionck errors).
654    #[must_use = "this method does not have any side effects"]
655    pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
656        self.tainted_by_errors.get()
657    }
658
659    /// Set the "tainted by errors" flag to true. We call this when we
660    /// observe an error from a prior pass.
661    pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
662        debug!("set_tainted_by_errors(ErrorGuaranteed)");
663        self.tainted_by_errors.set(Some(e));
664    }
665
666    #[instrument(level = "debug", skip(self), ret)]
667    pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
668        self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect()
669    }
670
671    #[instrument(level = "debug", skip(self), ret)]
672    pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
673        self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect()
674    }
675
676    #[inline(always)]
677    pub fn can_define_opaque_ty(&self, id: impl Into<SolverDefId>) -> bool {
678        match self.typing_mode_unchecked() {
679            TypingMode::Analysis { defining_opaque_types_and_generators } => {
680                defining_opaque_types_and_generators.contains(&id.into())
681            }
682            TypingMode::Coherence | TypingMode::PostAnalysis => false,
683            TypingMode::Borrowck { defining_opaque_types } => unimplemented!(),
684            TypingMode::PostBorrowckAnalysis { defined_opaque_types } => unimplemented!(),
685        }
686    }
687
688    /// If `TyVar(vid)` resolves to a type, return that type. Else, return the
689    /// universe index of `TyVar(vid)`.
690    pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'db>, UniverseIndex> {
691        use self::type_variable::TypeVariableValue;
692
693        match self.inner.borrow_mut().type_variables().probe(vid) {
694            TypeVariableValue::Known { value } => Ok(value),
695            TypeVariableValue::Unknown { universe } => Err(universe),
696        }
697    }
698
699    pub fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
700        if let TyKind::Infer(v) = ty.kind() {
701            match v {
702                InferTy::TyVar(v) => {
703                    // Not entirely obvious: if `typ` is a type variable,
704                    // it can be resolved to an int/float variable, which
705                    // can then be recursively resolved, hence the
706                    // recursion. Note though that we prevent type
707                    // variables from unifying to other type variables
708                    // directly (though they may be embedded
709                    // structurally), and we prevent cycles in any case,
710                    // so this recursion should always be of very limited
711                    // depth.
712                    //
713                    // Note: if these two lines are combined into one we get
714                    // dynamic borrow errors on `self.inner`.
715                    let known = self.inner.borrow_mut().type_variables().probe(v).known();
716                    known.map_or(ty, |t| self.shallow_resolve(t))
717                }
718
719                InferTy::IntVar(v) => {
720                    match self.inner.borrow_mut().int_unification_table().probe_value(v) {
721                        IntVarValue::IntType(ty) => Ty::new_int(self.interner, ty),
722                        IntVarValue::UintType(ty) => Ty::new_uint(self.interner, ty),
723                        IntVarValue::Unknown => ty,
724                    }
725                }
726
727                InferTy::FloatVar(v) => {
728                    match self.inner.borrow_mut().float_unification_table().probe_value(v) {
729                        FloatVarValue::Known(ty) => Ty::new_float(self.interner, ty),
730                        FloatVarValue::Unknown => ty,
731                    }
732                }
733
734                InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_) => ty,
735            }
736        } else {
737            ty
738        }
739    }
740
741    pub fn shallow_resolve_const(&self, ct: Const<'db>) -> Const<'db> {
742        match ct.kind() {
743            ConstKind::Infer(infer_ct) => match infer_ct {
744                InferConst::Var(vid) => self
745                    .inner
746                    .borrow_mut()
747                    .const_unification_table()
748                    .probe_value(vid)
749                    .known()
750                    .unwrap_or(ct),
751                InferConst::Fresh(_) => ct,
752            },
753            ConstKind::Param(_)
754            | ConstKind::Bound(_, _)
755            | ConstKind::Placeholder(_)
756            | ConstKind::Unevaluated(_)
757            | ConstKind::Value(_)
758            | ConstKind::Error(_)
759            | ConstKind::Expr(_) => ct,
760        }
761    }
762
763    pub fn root_var(&self, var: TyVid) -> TyVid {
764        self.inner.borrow_mut().type_variables().root_var(var)
765    }
766
767    pub fn root_const_var(&self, var: ConstVid) -> ConstVid {
768        self.inner.borrow_mut().const_unification_table().find(var).vid
769    }
770
771    /// Resolves an int var to a rigid int type, if it was constrained to one,
772    /// or else the root int var in the unification table.
773    pub fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'db> {
774        let mut inner = self.inner.borrow_mut();
775        let value = inner.int_unification_table().probe_value(vid);
776        match value {
777            IntVarValue::IntType(ty) => Ty::new_int(self.interner, ty),
778            IntVarValue::UintType(ty) => Ty::new_uint(self.interner, ty),
779            IntVarValue::Unknown => {
780                Ty::new_int_var(self.interner, inner.int_unification_table().find(vid))
781            }
782        }
783    }
784
785    /// Resolves a float var to a rigid int type, if it was constrained to one,
786    /// or else the root float var in the unification table.
787    pub fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'db> {
788        let mut inner = self.inner.borrow_mut();
789        let value = inner.float_unification_table().probe_value(vid);
790        match value {
791            FloatVarValue::Known(ty) => Ty::new_float(self.interner, ty),
792            FloatVarValue::Unknown => {
793                Ty::new_float_var(self.interner, inner.float_unification_table().find(vid))
794            }
795        }
796    }
797
798    /// Where possible, replaces type/const variables in
799    /// `value` with their final value. Note that region variables
800    /// are unaffected. If a type/const variable has not been unified, it
801    /// is left as is. This is an idempotent operation that does
802    /// not affect inference state in any way and so you can do it
803    /// at will.
804    pub fn resolve_vars_if_possible<T>(&self, value: T) -> T
805    where
806        T: TypeFoldable<DbInterner<'db>>,
807    {
808        if let Err(guar) = value.error_reported() {
809            self.set_tainted_by_errors(guar);
810        }
811        if !value.has_non_region_infer() {
812            return value;
813        }
814        let mut r = resolve::OpportunisticVarResolver::new(self);
815        value.fold_with(&mut r)
816    }
817
818    pub fn probe_const_var(&self, vid: ConstVid) -> Result<Const<'db>, UniverseIndex> {
819        match self.inner.borrow_mut().const_unification_table().probe_value(vid) {
820            ConstVariableValue::Known { value } => Ok(value),
821            ConstVariableValue::Unknown { origin: _, universe } => Err(universe),
822        }
823    }
824
825    // Instantiates the bound variables in a given binder with fresh inference
826    // variables in the current universe.
827    //
828    // Use this method if you'd like to find some generic parameters of the binder's
829    // variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`]
830    // that corresponds to your use case, consider whether or not you should
831    // use [`InferCtxt::enter_forall`] instead.
832    pub fn instantiate_binder_with_fresh_vars<T>(
833        &self,
834        lbrct: BoundRegionConversionTime,
835        value: Binder<'db, T>,
836    ) -> T
837    where
838        T: TypeFoldable<DbInterner<'db>> + Clone,
839    {
840        if let Some(inner) = value.clone().no_bound_vars() {
841            return inner;
842        }
843
844        let bound_vars = value.clone().bound_vars();
845        let mut args = Vec::with_capacity(bound_vars.len());
846
847        for bound_var_kind in bound_vars {
848            let arg: GenericArg<'db> = match bound_var_kind {
849                BoundVarKind::Ty(_) => self.next_ty_var().into(),
850                BoundVarKind::Region(br) => self.next_region_var().into(),
851                BoundVarKind::Const => self.next_const_var().into(),
852            };
853            args.push(arg);
854        }
855
856        struct ToFreshVars<'db> {
857            args: Vec<GenericArg<'db>>,
858        }
859
860        impl<'db> BoundVarReplacerDelegate<'db> for ToFreshVars<'db> {
861            fn replace_region(&mut self, br: BoundRegion) -> Region<'db> {
862                self.args[br.var.index()].expect_region()
863            }
864            fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db> {
865                self.args[bt.var.index()].expect_ty()
866            }
867            fn replace_const(&mut self, bv: BoundVar) -> Const<'db> {
868                self.args[bv.index()].expect_const()
869            }
870        }
871        let delegate = ToFreshVars { args };
872        self.interner.replace_bound_vars_uncached(value, delegate)
873    }
874
875    /// Obtains the latest type of the given closure; this may be a
876    /// closure in the current function, in which case its
877    /// `ClosureKind` may not yet be known.
878    pub fn closure_kind(&self, closure_ty: Ty<'db>) -> Option<ClosureKind> {
879        let unresolved_kind_ty = match closure_ty.kind() {
880            TyKind::Closure(_, args) => args.as_closure().kind_ty(),
881            TyKind::CoroutineClosure(_, args) => args.as_coroutine_closure().kind_ty(),
882            _ => panic!("unexpected type {closure_ty:?}"),
883        };
884        let closure_kind_ty = self.shallow_resolve(unresolved_kind_ty);
885        closure_kind_ty.to_opt_closure_kind()
886    }
887
888    pub fn universe(&self) -> UniverseIndex {
889        self.universe.get()
890    }
891
892    /// Creates and return a fresh universe that extends all previous
893    /// universes. Updates `self.universe` to that new universe.
894    pub fn create_next_universe(&self) -> UniverseIndex {
895        let u = self.universe.get().next_universe();
896        debug!("create_next_universe {u:?}");
897        self.universe.set(u);
898        u
899    }
900
901    /// The returned function is used in a fast path. If it returns `true` the variable is
902    /// unchanged, `false` indicates that the status is unknown.
903    #[inline]
904    pub fn is_ty_infer_var_definitely_unchanged<'a>(
905        &'a self,
906    ) -> (impl Fn(TyOrConstInferVar) -> bool + Captures<'db> + 'a) {
907        // This hoists the borrow/release out of the loop body.
908        let inner = self.inner.try_borrow();
909
910        move |infer_var: TyOrConstInferVar| match (infer_var, &inner) {
911            (TyOrConstInferVar::Ty(ty_var), Ok(inner)) => {
912                use self::type_variable::TypeVariableValue;
913
914                matches!(
915                    inner.try_type_variables_probe_ref(ty_var),
916                    Some(TypeVariableValue::Unknown { .. })
917                )
918            }
919            _ => false,
920        }
921    }
922
923    /// `ty_or_const_infer_var_changed` is equivalent to one of these two:
924    ///   * `shallow_resolve(ty) != ty` (where `ty.kind = Infer(_)`)
925    ///   * `shallow_resolve(ct) != ct` (where `ct.kind = ConstKind::Infer(_)`)
926    ///
927    /// However, `ty_or_const_infer_var_changed` is more efficient. It's always
928    /// inlined, despite being large, because it has only two call sites that
929    /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on`
930    /// inference variables), and it handles both `Ty` and `Const` without
931    /// having to resort to storing full `GenericArg`s in `stalled_on`.
932    #[inline(always)]
933    pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar) -> bool {
934        match infer_var {
935            TyOrConstInferVar::Ty(v) => {
936                use self::type_variable::TypeVariableValue;
937
938                // If `inlined_probe` returns a `Known` value, it never equals
939                // `Infer(TyVar(v))`.
940                match self.inner.borrow_mut().type_variables().inlined_probe(v) {
941                    TypeVariableValue::Unknown { .. } => false,
942                    TypeVariableValue::Known { .. } => true,
943                }
944            }
945
946            TyOrConstInferVar::TyInt(v) => {
947                // If `inlined_probe_value` returns a value it's always a
948                // `Int(_)` or `UInt(_)`, which never matches a
949                // `Infer(_)`.
950                self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_known()
951            }
952
953            TyOrConstInferVar::TyFloat(v) => {
954                // If `probe_value` returns a value it's always a
955                // `Float(_)`, which never matches a `Infer(_)`.
956                //
957                // Not `inlined_probe_value(v)` because this call site is colder.
958                self.inner.borrow_mut().float_unification_table().probe_value(v).is_known()
959            }
960
961            TyOrConstInferVar::Const(v) => {
962                // If `probe_value` returns a `Known` value, it never equals
963                // `ConstKind::Infer(InferConst::Var(v))`.
964                //
965                // Not `inlined_probe_value(v)` because this call site is colder.
966                match self.inner.borrow_mut().const_unification_table().probe_value(v) {
967                    ConstVariableValue::Unknown { .. } => false,
968                    ConstVariableValue::Known { .. } => true,
969                }
970            }
971        }
972    }
973}
974
975/// Helper for [InferCtxt::ty_or_const_infer_var_changed] (see comment on that), currently
976/// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
977#[derive(Copy, Clone, Debug)]
978pub enum TyOrConstInferVar {
979    /// Equivalent to `Infer(TyVar(_))`.
980    Ty(TyVid),
981    /// Equivalent to `Infer(IntVar(_))`.
982    TyInt(IntVid),
983    /// Equivalent to `Infer(FloatVar(_))`.
984    TyFloat(FloatVid),
985
986    /// Equivalent to `ConstKind::Infer(InferConst::Var(_))`.
987    Const(ConstVid),
988}
989
990impl TyOrConstInferVar {
991    /// Tries to extract an inference variable from a type or a constant, returns `None`
992    /// for types other than `Infer(_)` (or `InferTy::Fresh*`) and
993    /// for constants other than `ConstKind::Infer(_)` (or `InferConst::Fresh`).
994    pub fn maybe_from_generic_arg<'db>(arg: GenericArg<'db>) -> Option<Self> {
995        match arg.kind() {
996            GenericArgKind::Type(ty) => Self::maybe_from_ty(ty),
997            GenericArgKind::Const(ct) => Self::maybe_from_const(ct),
998            GenericArgKind::Lifetime(_) => None,
999        }
1000    }
1001
1002    /// Tries to extract an inference variable from a type, returns `None`
1003    /// for types other than `Infer(_)` (or `InferTy::Fresh*`).
1004    fn maybe_from_ty<'db>(ty: Ty<'db>) -> Option<Self> {
1005        match ty.kind() {
1006            TyKind::Infer(InferTy::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)),
1007            TyKind::Infer(InferTy::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)),
1008            TyKind::Infer(InferTy::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)),
1009            _ => None,
1010        }
1011    }
1012
1013    /// Tries to extract an inference variable from a constant, returns `None`
1014    /// for constants other than `ConstKind::Infer(_)` (or `InferConst::Fresh`).
1015    fn maybe_from_const<'db>(ct: Const<'db>) -> Option<Self> {
1016        match ct.kind() {
1017            ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
1018            _ => None,
1019        }
1020    }
1021}
1022
1023impl<'db> TypeTrace<'db> {
1024    pub fn types(cause: &ObligationCause, a: Ty<'db>, b: Ty<'db>) -> TypeTrace<'db> {
1025        TypeTrace {
1026            cause: cause.clone(),
1027            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
1028        }
1029    }
1030
1031    pub fn trait_refs(
1032        cause: &ObligationCause,
1033        a: TraitRef<'db>,
1034        b: TraitRef<'db>,
1035    ) -> TypeTrace<'db> {
1036        TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
1037    }
1038
1039    pub fn consts(cause: &ObligationCause, a: Const<'db>, b: Const<'db>) -> TypeTrace<'db> {
1040        TypeTrace {
1041            cause: cause.clone(),
1042            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
1043        }
1044    }
1045}
1046
1047/// Requires that `region` must be equal to one of the regions in `choice_regions`.
1048/// We often denote this using the syntax:
1049///
1050/// ```text
1051/// R0 member of [O1..On]
1052/// ```
1053#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1054pub struct MemberConstraint<'db> {
1055    /// The `DefId` and args of the opaque type causing this constraint.
1056    /// Used for error reporting.
1057    pub key: OpaqueTypeKey<'db>,
1058
1059    /// The hidden type in which `member_region` appears: used for error reporting.
1060    pub hidden_ty: Ty<'db>,
1061
1062    /// The region `R0`.
1063    pub member_region: Region<'db>,
1064
1065    /// The options `O1..On`.
1066    pub choice_regions: Arc<Vec<Region<'db>>>,
1067}