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