hir_ty/
infer.rs

1//! Type inference, i.e. the process of walking through the code and determining
2//! the type of each expression and pattern.
3//!
4//! For type inference, compare the implementations in rustc (the various
5//! check_* methods in rustc_hir_analysis/check/mod.rs are a good entry point) and
6//! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for
7//! inference here is the `infer` function, which infers the types of all
8//! expressions in a given function.
9//!
10//! During inference, types (i.e. the `Ty` struct) can contain type 'variables'
11//! which represent currently unknown types; as we walk through the expressions,
12//! we might determine that certain variables need to be equal to each other, or
13//! to certain types. To record this, we use the union-find implementation from
14//! the `ena` crate, which is extracted from rustc.
15
16pub(crate) mod cast;
17pub(crate) mod closure;
18mod coerce;
19pub(crate) mod diagnostics;
20mod expr;
21mod mutability;
22mod pat;
23mod path;
24pub(crate) mod unify;
25
26use std::{cell::OnceCell, convert::identity, iter, ops::Index};
27
28use chalk_ir::{
29    DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance,
30    cast::Cast,
31    fold::TypeFoldable,
32    interner::HasInterner,
33    visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
34};
35use either::Either;
36use hir_def::{
37    AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
38    ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId,
39    VariantId,
40    builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
41    expr_store::{Body, ExpressionStore, HygieneId, path::Path},
42    hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
43    lang_item::{LangItem, LangItemTarget, lang_item},
44    layout::Integer,
45    resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
46    signatures::{ConstSignature, StaticSignature},
47    type_ref::{ConstRef, LifetimeRefId, TypeRefId},
48};
49use hir_expand::{mod_path::ModPath, name::Name};
50use indexmap::IndexSet;
51use intern::sym;
52use la_arena::{ArenaMap, Entry};
53use rustc_hash::{FxHashMap, FxHashSet};
54use stdx::{always, never};
55use triomphe::Arc;
56
57use crate::{
58    AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
59    ImplTraitIdx, InEnvironment, IncorrectGenericsLenKind, Interner, Lifetime, OpaqueTyId,
60    ParamLoweringMode, PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty,
61    TyBuilder, TyExt,
62    db::HirDatabase,
63    fold_tys,
64    generics::Generics,
65    infer::{
66        coerce::CoerceMany,
67        diagnostics::{Diagnostics, InferenceTyLoweringContext as TyLoweringContext},
68        expr::ExprIsRead,
69        unify::InferenceTable,
70    },
71    lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic},
72    mir::MirSpan,
73    static_lifetime, to_assoc_type_id,
74    traits::FnTrait,
75    utils::UnevaluatedConstEvaluatorFolder,
76};
77
78// This lint has a false positive here. See the link below for details.
79//
80// https://github.com/rust-lang/rust/issues/57411
81#[allow(unreachable_pub)]
82pub use coerce::could_coerce;
83#[allow(unreachable_pub)]
84pub use unify::{could_unify, could_unify_deeply};
85
86use cast::{CastCheck, CastError};
87pub(crate) use closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
88
89/// The entry point of type inference.
90pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
91    let _p = tracing::info_span!("infer_query").entered();
92    let resolver = def.resolver(db);
93    let body = db.body(def);
94    let mut ctx = InferenceContext::new(db, def, &body, resolver);
95
96    match def {
97        DefWithBodyId::FunctionId(f) => {
98            ctx.collect_fn(f);
99        }
100        DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
101        DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
102        DefWithBodyId::VariantId(v) => {
103            ctx.return_ty = TyBuilder::builtin(
104                match db.enum_signature(v.lookup(db).parent).variant_body_type() {
105                    hir_def::layout::IntegerType::Pointer(signed) => match signed {
106                        true => BuiltinType::Int(BuiltinInt::Isize),
107                        false => BuiltinType::Uint(BuiltinUint::Usize),
108                    },
109                    hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
110                        true => BuiltinType::Int(match size {
111                            Integer::I8 => BuiltinInt::I8,
112                            Integer::I16 => BuiltinInt::I16,
113                            Integer::I32 => BuiltinInt::I32,
114                            Integer::I64 => BuiltinInt::I64,
115                            Integer::I128 => BuiltinInt::I128,
116                        }),
117                        false => BuiltinType::Uint(match size {
118                            Integer::I8 => BuiltinUint::U8,
119                            Integer::I16 => BuiltinUint::U16,
120                            Integer::I32 => BuiltinUint::U32,
121                            Integer::I64 => BuiltinUint::U64,
122                            Integer::I128 => BuiltinUint::U128,
123                        }),
124                    },
125                },
126            );
127        }
128    }
129
130    ctx.infer_body();
131
132    ctx.infer_mut_body();
133
134    ctx.infer_closures();
135
136    Arc::new(ctx.resolve_all())
137}
138
139pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
140    Arc::new(InferenceResult { has_errors: true, ..Default::default() })
141}
142
143/// Fully normalize all the types found within `ty` in context of `owner` body definition.
144///
145/// This is appropriate to use only after type-check: it assumes
146/// that normalization will succeed, for example.
147#[tracing::instrument(level = "debug", skip(db))]
148pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment>, ty: Ty) -> Ty {
149    // FIXME: TypeFlags::HAS_CT_PROJECTION is not implemented in chalk, so TypeFlags::HAS_PROJECTION only
150    // works for the type case, so we check array unconditionally. Remove the array part
151    // when the bug in chalk becomes fixed.
152    if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION)
153        && !matches!(ty.kind(Interner), TyKind::Array(..))
154    {
155        return ty;
156    }
157    let mut table = unify::InferenceTable::new(db, trait_env);
158
159    let ty_with_vars = table.normalize_associated_types_in(ty);
160    table.resolve_obligations_as_possible();
161    table.propagate_diverging_flag();
162    table.resolve_completely(ty_with_vars)
163}
164
165/// Binding modes inferred for patterns.
166/// <https://doc.rust-lang.org/reference/patterns.html#binding-modes>
167#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
168pub enum BindingMode {
169    #[default]
170    Move,
171    Ref(Mutability),
172}
173
174impl BindingMode {
175    fn convert(annotation: BindingAnnotation) -> BindingMode {
176        match annotation {
177            BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
178            BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
179            BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
180        }
181    }
182}
183
184#[derive(Debug)]
185pub(crate) struct InferOk<T> {
186    value: T,
187    goals: Vec<InEnvironment<Goal>>,
188}
189
190impl<T> InferOk<T> {
191    fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
192        InferOk { value: f(self.value), goals: self.goals }
193    }
194}
195
196#[derive(Debug, PartialEq, Eq, Clone, Copy)]
197pub enum InferenceTyDiagnosticSource {
198    /// Diagnostics that come from types in the body.
199    Body,
200    /// Diagnostics that come from types in fn parameters/return type, or static & const types.
201    Signature,
202}
203
204#[derive(Debug)]
205pub(crate) struct TypeError;
206pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
207
208#[derive(Debug, PartialEq, Eq, Clone)]
209pub enum InferenceDiagnostic {
210    NoSuchField {
211        field: ExprOrPatId,
212        private: Option<LocalFieldId>,
213        variant: VariantId,
214    },
215    PrivateField {
216        expr: ExprId,
217        field: FieldId,
218    },
219    PrivateAssocItem {
220        id: ExprOrPatId,
221        item: AssocItemId,
222    },
223    UnresolvedField {
224        expr: ExprId,
225        receiver: Ty,
226        name: Name,
227        method_with_same_name_exists: bool,
228    },
229    UnresolvedMethodCall {
230        expr: ExprId,
231        receiver: Ty,
232        name: Name,
233        /// Contains the type the field resolves to
234        field_with_same_name: Option<Ty>,
235        assoc_func_with_same_name: Option<FunctionId>,
236    },
237    UnresolvedAssocItem {
238        id: ExprOrPatId,
239    },
240    UnresolvedIdent {
241        id: ExprOrPatId,
242    },
243    // FIXME: This should be emitted in body lowering
244    BreakOutsideOfLoop {
245        expr: ExprId,
246        is_break: bool,
247        bad_value_break: bool,
248    },
249    MismatchedArgCount {
250        call_expr: ExprId,
251        expected: usize,
252        found: usize,
253    },
254    MismatchedTupleStructPatArgCount {
255        pat: ExprOrPatId,
256        expected: usize,
257        found: usize,
258    },
259    ExpectedFunction {
260        call_expr: ExprId,
261        found: Ty,
262    },
263    TypedHole {
264        expr: ExprId,
265        expected: Ty,
266    },
267    CastToUnsized {
268        expr: ExprId,
269        cast_ty: Ty,
270    },
271    InvalidCast {
272        expr: ExprId,
273        error: CastError,
274        expr_ty: Ty,
275        cast_ty: Ty,
276    },
277    TyDiagnostic {
278        source: InferenceTyDiagnosticSource,
279        diag: TyLoweringDiagnostic,
280    },
281    PathDiagnostic {
282        node: ExprOrPatId,
283        diag: PathLoweringDiagnostic,
284    },
285    MethodCallIncorrectGenericsLen {
286        expr: ExprId,
287        provided_count: u32,
288        expected_count: u32,
289        kind: IncorrectGenericsLenKind,
290        def: GenericDefId,
291    },
292    MethodCallIncorrectGenericsOrder {
293        expr: ExprId,
294        param_id: GenericParamId,
295        arg_idx: u32,
296        /// Whether the `GenericArgs` contains a `Self` arg.
297        has_self_arg: bool,
298    },
299}
300
301/// A mismatch between an expected and an inferred type.
302#[derive(Clone, PartialEq, Eq, Debug, Hash)]
303pub struct TypeMismatch {
304    pub expected: Ty,
305    pub actual: Ty,
306}
307
308#[derive(Clone, PartialEq, Eq, Debug)]
309struct InternedStandardTypes {
310    unknown: Ty,
311    bool_: Ty,
312    unit: Ty,
313    never: Ty,
314}
315
316impl Default for InternedStandardTypes {
317    fn default() -> Self {
318        InternedStandardTypes {
319            unknown: TyKind::Error.intern(Interner),
320            bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
321            unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
322            never: TyKind::Never.intern(Interner),
323        }
324    }
325}
326/// Represents coercing a value to a different type of value.
327///
328/// We transform values by following a number of `Adjust` steps in order.
329/// See the documentation on variants of `Adjust` for more details.
330///
331/// Here are some common scenarios:
332///
333/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
334///    Here the pointer will be dereferenced N times (where a dereference can
335///    happen to raw or borrowed pointers or any smart pointer which implements
336///    Deref, including Box<_>). The types of dereferences is given by
337///    `autoderefs`. It can then be auto-referenced zero or one times, indicated
338///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
339///    `false`.
340///
341/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
342///    with a thin pointer, deref a number of times, unsize the underlying data,
343///    then autoref. The 'unsize' phase may change a fixed length array to a
344///    dynamically sized one, a concrete object to a trait object, or statically
345///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
346///    represented by:
347///
348///    ```ignore
349///    Deref(None) -> [i32; 4],
350///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
351///    Unsize -> &[i32],
352///    ```
353///
354///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.
355///    E.g., `struct Foo<T> { it: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
356///    The autoderef and -ref are the same as in the above example, but the type
357///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
358///    the underlying conversions from `[i32; 4]` to `[i32]`.
359///
360/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
361///    that case, we have the pointer we need coming in, so there are no
362///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
363///    At some point, of course, `Box` should move out of the compiler, in which
364///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
365///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
366#[derive(Clone, Debug, PartialEq, Eq, Hash)]
367pub struct Adjustment {
368    pub kind: Adjust,
369    pub target: Ty,
370}
371
372impl Adjustment {
373    pub fn borrow(m: Mutability, ty: Ty, lt: Lifetime) -> Self {
374        let ty = TyKind::Ref(m, lt.clone(), ty).intern(Interner);
375        Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt, m)), target: ty }
376    }
377}
378
379#[derive(Clone, Debug, PartialEq, Eq, Hash)]
380pub enum Adjust {
381    /// Go from ! to any type.
382    NeverToAny,
383    /// Dereference once, producing a place.
384    Deref(Option<OverloadedDeref>),
385    /// Take the address and produce either a `&` or `*` pointer.
386    Borrow(AutoBorrow),
387    Pointer(PointerCast),
388}
389
390/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
391/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
392/// The target type is `U` in both cases, with the region and mutability
393/// being those shared by both the receiver and the returned reference.
394///
395/// Mutability is `None` when we are not sure.
396#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
397pub struct OverloadedDeref(pub Option<Mutability>);
398
399#[derive(Clone, Debug, PartialEq, Eq, Hash)]
400pub enum AutoBorrow {
401    /// Converts from T to &T.
402    Ref(Lifetime, Mutability),
403    /// Converts from T to *T.
404    RawPtr(Mutability),
405}
406
407impl AutoBorrow {
408    fn mutability(&self) -> Mutability {
409        let (AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) = self;
410        *m
411    }
412}
413
414#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
415pub enum PointerCast {
416    /// Go from a fn-item type to a fn-pointer type.
417    ReifyFnPointer,
418
419    /// Go from a safe fn pointer to an unsafe fn pointer.
420    UnsafeFnPointer,
421
422    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
423    /// It cannot convert a closure that requires unsafe.
424    ClosureFnPointer(Safety),
425
426    /// Go from a mut raw pointer to a const raw pointer.
427    MutToConstPointer,
428
429    #[allow(dead_code)]
430    /// Go from `*const [T; N]` to `*const T`
431    ArrayToPointer,
432
433    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
434    /// `&[T]`. Note that the source could be a thin or fat pointer.
435    /// This will do things like convert thin pointers to fat
436    /// pointers, or convert structs containing thin pointers to
437    /// structs containing fat pointers, or convert between fat
438    /// pointers. We don't store the details of how the transform is
439    /// done (in fact, we don't know that, because it might depend on
440    /// the precise type parameters). We just store the target
441    /// type. Codegen backends and miri figure out what has to be done
442    /// based on the precise source/target type at hand.
443    Unsize,
444}
445
446/// The result of type inference: A mapping from expressions and patterns to types.
447///
448/// When you add a field that stores types (including `Substitution` and the like), don't forget
449/// `resolve_completely()`'ing  them in `InferenceContext::resolve_all()`. Inference variables must
450/// not appear in the final inference result.
451#[derive(Clone, PartialEq, Eq, Debug, Default)]
452pub struct InferenceResult {
453    /// For each method call expr, records the function it resolves to.
454    method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
455    /// For each field access expr, records the field it resolves to.
456    field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
457    /// For each struct literal or pattern, records the variant it resolves to.
458    variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
459    /// For each associated item record what it resolves to
460    assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
461    /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in
462    /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of
463    /// that which allows us to resolve a [`TupleFieldId`]s type.
464    tuple_field_access_types: FxHashMap<TupleId, Substitution>,
465    /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.
466    diagnostics: Vec<InferenceDiagnostic>,
467    pub(crate) type_of_expr: ArenaMap<ExprId, Ty>,
468    /// For each pattern record the type it resolves to.
469    ///
470    /// **Note**: When a pattern type is resolved it may still contain
471    /// unresolved or missing subpatterns or subpatterns of mismatched types.
472    pub(crate) type_of_pat: ArenaMap<PatId, Ty>,
473    pub(crate) type_of_binding: ArenaMap<BindingId, Ty>,
474    pub(crate) type_of_rpit: ArenaMap<ImplTraitIdx, Ty>,
475    type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
476    /// Whether there are any type-mismatching errors in the result.
477    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to
478    // `TyKind::Error`.
479    // Which will then mark this field.
480    pub(crate) has_errors: bool,
481    /// Interned common types to return references to.
482    // FIXME: Move this into `InferenceContext`
483    standard_types: InternedStandardTypes,
484    /// Stores the types which were implicitly dereferenced in pattern binding modes.
485    pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
486    /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.
487    ///
488    /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an
489    /// or pattern can have multiple binding modes. For example:
490    /// ```
491    /// fn foo(mut slice: &[u32]) -> usize {
492    ///     slice = match slice {
493    ///         [0, rest @ ..] | rest => rest,
494    ///     };
495    ///     0
496    /// }
497    /// ```
498    /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
499    pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,
500    pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
501    pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
502    // FIXME: remove this field
503    pub mutated_bindings_in_closure: FxHashSet<BindingId>,
504    pub(crate) coercion_casts: FxHashSet<ExprId>,
505}
506
507impl InferenceResult {
508    pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
509        self.method_resolutions.get(&expr).cloned()
510    }
511    pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
512        self.field_resolutions.get(&expr).copied()
513    }
514    pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
515        self.variant_resolutions.get(&id.into()).copied()
516    }
517    pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
518        self.variant_resolutions.get(&id.into()).copied()
519    }
520    pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
521        match id {
522            ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
523            ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
524        }
525    }
526    pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
527        self.assoc_resolutions.get(&id.into()).cloned()
528    }
529    pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
530        self.assoc_resolutions.get(&id.into()).cloned()
531    }
532    pub fn assoc_resolutions_for_expr_or_pat(
533        &self,
534        id: ExprOrPatId,
535    ) -> Option<(AssocItemId, Substitution)> {
536        match id {
537            ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
538            ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
539        }
540    }
541    pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
542        self.type_mismatches.get(&expr.into())
543    }
544    pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
545        self.type_mismatches.get(&pat.into())
546    }
547    pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch)> {
548        self.type_mismatches.iter().map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch))
549    }
550    pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
551        self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
552            ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
553            _ => None,
554        })
555    }
556    pub fn closure_info(&self, closure: &ClosureId) -> &(Vec<CapturedItem>, FnTrait) {
557        self.closure_info.get(closure).unwrap()
558    }
559    pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option<&Ty> {
560        match id {
561            ExprOrPatId::ExprId(id) => self.type_of_expr.get(id),
562            ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
563        }
564    }
565    pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<&Ty> {
566        match self.expr_adjustments.get(&id).and_then(|adjustments| {
567            adjustments
568                .iter()
569                .filter(|adj| {
570                    // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140
571                    !matches!(
572                        adj,
573                        Adjustment {
574                            kind: Adjust::NeverToAny,
575                            target,
576                        } if target.is_never()
577                    )
578                })
579                .next_back()
580        }) {
581            Some(adjustment) => Some(&adjustment.target),
582            None => self.type_of_expr.get(id),
583        }
584    }
585    pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option<&Ty> {
586        match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
587            adjusted @ Some(_) => adjusted,
588            None => self.type_of_pat.get(id),
589        }
590    }
591    pub fn is_erroneous(&self) -> bool {
592        self.has_errors && self.type_of_expr.iter().count() == 0
593    }
594
595    pub fn diagnostics(&self) -> &[InferenceDiagnostic] {
596        &self.diagnostics
597    }
598
599    pub fn tuple_field_access_type(&self, id: TupleId) -> &Substitution {
600        &self.tuple_field_access_types[&id]
601    }
602
603    pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty]> {
604        self.pat_adjustments.get(&id).map(|it| &**it)
605    }
606
607    pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {
608        self.expr_adjustments.get(&id).map(|it| &**it)
609    }
610
611    pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {
612        self.binding_modes.get(id).copied()
613    }
614}
615
616impl Index<ExprId> for InferenceResult {
617    type Output = Ty;
618
619    fn index(&self, expr: ExprId) -> &Ty {
620        self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
621    }
622}
623
624impl Index<PatId> for InferenceResult {
625    type Output = Ty;
626
627    fn index(&self, pat: PatId) -> &Ty {
628        self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
629    }
630}
631
632impl Index<ExprOrPatId> for InferenceResult {
633    type Output = Ty;
634
635    fn index(&self, id: ExprOrPatId) -> &Ty {
636        self.type_of_expr_or_pat(id).unwrap_or(&self.standard_types.unknown)
637    }
638}
639
640impl Index<BindingId> for InferenceResult {
641    type Output = Ty;
642
643    fn index(&self, b: BindingId) -> &Ty {
644        self.type_of_binding.get(b).unwrap_or(&self.standard_types.unknown)
645    }
646}
647
648/// The inference context contains all information needed during type inference.
649#[derive(Clone, Debug)]
650pub(crate) struct InferenceContext<'db> {
651    pub(crate) db: &'db dyn HirDatabase,
652    pub(crate) owner: DefWithBodyId,
653    pub(crate) body: &'db Body,
654    /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
655    /// and resolve the path via its methods. This will ensure proper error reporting.
656    pub(crate) resolver: Resolver<'db>,
657    generic_def: GenericDefId,
658    generics: OnceCell<Generics>,
659    table: unify::InferenceTable<'db>,
660    /// The traits in scope, disregarding block modules. This is used for caching purposes.
661    traits_in_scope: FxHashSet<TraitId>,
662    pub(crate) result: InferenceResult,
663    tuple_field_accesses_rev:
664        IndexSet<Substitution, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
665    /// The return type of the function being inferred, the closure or async block if we're
666    /// currently within one.
667    ///
668    /// We might consider using a nested inference context for checking
669    /// closures so we can swap all shared things out at once.
670    return_ty: Ty,
671    /// If `Some`, this stores coercion information for returned
672    /// expressions. If `None`, this is in a context where return is
673    /// inappropriate, such as a const expression.
674    return_coercion: Option<CoerceMany>,
675    /// The resume type and the yield type, respectively, of the coroutine being inferred.
676    resume_yield_tys: Option<(Ty, Ty)>,
677    diverges: Diverges,
678    breakables: Vec<BreakableContext>,
679
680    /// Whether we are inside the pattern of a destructuring assignment.
681    inside_assignment: bool,
682
683    deferred_cast_checks: Vec<CastCheck>,
684
685    // fields related to closure capture
686    current_captures: Vec<CapturedItemWithoutTy>,
687    /// A stack that has an entry for each projection in the current capture.
688    ///
689    /// For example, in `a.b.c`, we capture the spans of `a`, `a.b`, and `a.b.c`.
690    /// We do that because sometimes we truncate projections (when a closure captures
691    /// both `a.b` and `a.b.c`), and we want to provide accurate spans in this case.
692    current_capture_span_stack: Vec<MirSpan>,
693    current_closure: Option<ClosureId>,
694    /// Stores the list of closure ids that need to be analyzed before this closure. See the
695    /// comment on `InferenceContext::sort_closures`
696    closure_dependencies: FxHashMap<ClosureId, Vec<ClosureId>>,
697    deferred_closures: FxHashMap<ClosureId, Vec<(Ty, Ty, Vec<Ty>, ExprId)>>,
698
699    diagnostics: Diagnostics,
700}
701
702#[derive(Clone, Debug)]
703struct BreakableContext {
704    /// Whether this context contains at least one break expression.
705    may_break: bool,
706    /// The coercion target of the context.
707    coerce: Option<CoerceMany>,
708    /// The optional label of the context.
709    label: Option<LabelId>,
710    kind: BreakableKind,
711}
712
713#[derive(Clone, Debug)]
714enum BreakableKind {
715    Block,
716    Loop,
717    /// A border is something like an async block, closure etc. Anything that prevents
718    /// breaking/continuing through
719    Border,
720}
721
722fn find_breakable(
723    ctxs: &mut [BreakableContext],
724    label: Option<LabelId>,
725) -> Option<&mut BreakableContext> {
726    let mut ctxs = ctxs
727        .iter_mut()
728        .rev()
729        .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
730    match label {
731        Some(_) => ctxs.find(|ctx| ctx.label == label),
732        None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
733    }
734}
735
736fn find_continuable(
737    ctxs: &mut [BreakableContext],
738    label: Option<LabelId>,
739) -> Option<&mut BreakableContext> {
740    match label {
741        Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
742        None => find_breakable(ctxs, label),
743    }
744}
745
746enum ImplTraitReplacingMode {
747    ReturnPosition(FxHashSet<Ty>),
748    TypeAlias,
749}
750
751impl<'db> InferenceContext<'db> {
752    fn new(
753        db: &'db dyn HirDatabase,
754        owner: DefWithBodyId,
755        body: &'db Body,
756        resolver: Resolver<'db>,
757    ) -> Self {
758        let trait_env = db.trait_environment_for_body(owner);
759        InferenceContext {
760            generics: OnceCell::new(),
761            result: InferenceResult::default(),
762            table: unify::InferenceTable::new(db, trait_env),
763            tuple_field_accesses_rev: Default::default(),
764            return_ty: TyKind::Error.intern(Interner), // set in collect_* calls
765            resume_yield_tys: None,
766            return_coercion: None,
767            db,
768            owner,
769            generic_def: match owner {
770                DefWithBodyId::FunctionId(it) => it.into(),
771                DefWithBodyId::StaticId(it) => it.into(),
772                DefWithBodyId::ConstId(it) => it.into(),
773                DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
774            },
775            body,
776            traits_in_scope: resolver.traits_in_scope(db),
777            resolver,
778            diverges: Diverges::Maybe,
779            breakables: Vec::new(),
780            deferred_cast_checks: Vec::new(),
781            current_captures: Vec::new(),
782            current_capture_span_stack: Vec::new(),
783            current_closure: None,
784            deferred_closures: FxHashMap::default(),
785            closure_dependencies: FxHashMap::default(),
786            inside_assignment: false,
787            diagnostics: Diagnostics::default(),
788        }
789    }
790
791    pub(crate) fn generics(&self) -> &Generics {
792        self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
793    }
794
795    // FIXME: This function should be private in module. It is currently only used in the consteval, since we need
796    // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you
797    // used this function for another workaround, mention it here. If you really need this function and believe that
798    // there is no problem in it being `pub(crate)`, remove this comment.
799    pub(crate) fn resolve_all(self) -> InferenceResult {
800        let InferenceContext {
801            mut table,
802            mut result,
803            mut deferred_cast_checks,
804            tuple_field_accesses_rev,
805            diagnostics,
806            ..
807        } = self;
808        let mut diagnostics = diagnostics.finish();
809        // Destructure every single field so whenever new fields are added to `InferenceResult` we
810        // don't forget to handle them here.
811        let InferenceResult {
812            method_resolutions,
813            field_resolutions: _,
814            variant_resolutions: _,
815            assoc_resolutions,
816            type_of_expr,
817            type_of_pat,
818            type_of_binding,
819            type_of_rpit,
820            type_mismatches,
821            has_errors,
822            standard_types: _,
823            pat_adjustments,
824            binding_modes: _,
825            expr_adjustments,
826            // Types in `closure_info` have already been `resolve_completely()`'d during
827            // `InferenceContext::infer_closures()` (in `HirPlace::ty()` specifically), so no need
828            // to resolve them here.
829            closure_info: _,
830            mutated_bindings_in_closure: _,
831            tuple_field_access_types: _,
832            coercion_casts,
833            diagnostics: _,
834        } = &mut result;
835        table.fallback_if_possible();
836
837        // Comment from rustc:
838        // Even though coercion casts provide type hints, we check casts after fallback for
839        // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
840        let mut apply_adjustments = |expr, adj: Vec<_>| {
841            expr_adjustments.insert(expr, adj.into_boxed_slice());
842        };
843        let mut set_coercion_cast = |expr| {
844            coercion_casts.insert(expr);
845        };
846        for cast in deferred_cast_checks.iter_mut() {
847            if let Err(diag) =
848                cast.check(&mut table, &mut apply_adjustments, &mut set_coercion_cast)
849            {
850                diagnostics.push(diag);
851            }
852        }
853
854        // FIXME resolve obligations as well (use Guidance if necessary)
855        table.resolve_obligations_as_possible();
856
857        // make sure diverging type variables are marked as such
858        table.propagate_diverging_flag();
859        for ty in type_of_expr.values_mut() {
860            *ty = table.resolve_completely(ty.clone());
861            *has_errors = *has_errors || ty.contains_unknown();
862        }
863        type_of_expr.shrink_to_fit();
864        for ty in type_of_pat.values_mut() {
865            *ty = table.resolve_completely(ty.clone());
866            *has_errors = *has_errors || ty.contains_unknown();
867        }
868        type_of_pat.shrink_to_fit();
869        for ty in type_of_binding.values_mut() {
870            *ty = table.resolve_completely(ty.clone());
871            *has_errors = *has_errors || ty.contains_unknown();
872        }
873        type_of_binding.shrink_to_fit();
874        for ty in type_of_rpit.values_mut() {
875            *ty = table.resolve_completely(ty.clone());
876            *has_errors = *has_errors || ty.contains_unknown();
877        }
878        type_of_rpit.shrink_to_fit();
879
880        *has_errors |= !type_mismatches.is_empty();
881
882        type_mismatches.retain(|_, mismatch| {
883            mismatch.expected = table.resolve_completely(mismatch.expected.clone());
884            mismatch.actual = table.resolve_completely(mismatch.actual.clone());
885            chalk_ir::zip::Zip::zip_with(
886                &mut UnknownMismatch(self.db),
887                Variance::Invariant,
888                &mismatch.expected,
889                &mismatch.actual,
890            )
891            .is_ok()
892        });
893        type_mismatches.shrink_to_fit();
894        diagnostics.retain_mut(|diagnostic| {
895            use InferenceDiagnostic::*;
896            match diagnostic {
897                ExpectedFunction { found: ty, .. }
898                | UnresolvedField { receiver: ty, .. }
899                | UnresolvedMethodCall { receiver: ty, .. } => {
900                    *ty = table.resolve_completely(ty.clone());
901                    // FIXME: Remove this when we are on par with rustc in terms of inference
902                    if ty.contains_unknown() {
903                        return false;
904                    }
905
906                    if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic
907                        && let Some(ty) = field_with_same_name
908                    {
909                        *ty = table.resolve_completely(ty.clone());
910                        if ty.contains_unknown() {
911                            *field_with_same_name = None;
912                        }
913                    }
914                }
915                TypedHole { expected: ty, .. } => {
916                    *ty = table.resolve_completely(ty.clone());
917                }
918                _ => (),
919            }
920            true
921        });
922        diagnostics.shrink_to_fit();
923        for (_, subst) in method_resolutions.values_mut() {
924            *subst = table.resolve_completely(subst.clone());
925            *has_errors =
926                *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
927        }
928        method_resolutions.shrink_to_fit();
929        for (_, subst) in assoc_resolutions.values_mut() {
930            *subst = table.resolve_completely(subst.clone());
931            *has_errors =
932                *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
933        }
934        assoc_resolutions.shrink_to_fit();
935        for adjustment in expr_adjustments.values_mut().flatten() {
936            adjustment.target = table.resolve_completely(adjustment.target.clone());
937            *has_errors = *has_errors || adjustment.target.contains_unknown();
938        }
939        expr_adjustments.shrink_to_fit();
940        for adjustment in pat_adjustments.values_mut().flatten() {
941            *adjustment = table.resolve_completely(adjustment.clone());
942            *has_errors = *has_errors || adjustment.contains_unknown();
943        }
944        pat_adjustments.shrink_to_fit();
945        result.tuple_field_access_types = tuple_field_accesses_rev
946            .into_iter()
947            .enumerate()
948            .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
949            .inspect(|(_, subst)| {
950                *has_errors =
951                    *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
952            })
953            .collect();
954        result.tuple_field_access_types.shrink_to_fit();
955
956        result.diagnostics = diagnostics;
957
958        result
959    }
960
961    fn collect_const(&mut self, id: ConstId, data: &ConstSignature) {
962        let return_ty = self.make_ty(
963            data.type_ref,
964            &data.store,
965            InferenceTyDiagnosticSource::Signature,
966            LifetimeElisionKind::for_const(id.loc(self.db).container),
967        );
968
969        // Constants might be defining usage sites of TAITs.
970        self.make_tait_coercion_table(iter::once(&return_ty));
971
972        self.return_ty = return_ty;
973    }
974
975    fn collect_static(&mut self, data: &StaticSignature) {
976        let return_ty = self.make_ty(
977            data.type_ref,
978            &data.store,
979            InferenceTyDiagnosticSource::Signature,
980            LifetimeElisionKind::Elided(static_lifetime()),
981        );
982
983        // Statics might be defining usage sites of TAITs.
984        self.make_tait_coercion_table(iter::once(&return_ty));
985
986        self.return_ty = return_ty;
987    }
988
989    fn collect_fn(&mut self, func: FunctionId) {
990        let data = self.db.function_signature(func);
991        let mut param_tys = self.with_ty_lowering(
992            &data.store,
993            InferenceTyDiagnosticSource::Signature,
994            LifetimeElisionKind::for_fn_params(&data),
995            |ctx| {
996                ctx.type_param_mode(ParamLoweringMode::Placeholder);
997                data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>()
998            },
999        );
1000
1001        // Check if function contains a va_list, if it does then we append it to the parameter types
1002        // that are collected from the function data
1003        if data.is_varargs() {
1004            let va_list_ty = match self.resolve_va_list() {
1005                Some(va_list) => TyBuilder::adt(self.db, va_list)
1006                    .fill_with_defaults(self.db, || self.table.new_type_var())
1007                    .build(),
1008                None => self.err_ty(),
1009            };
1010
1011            param_tys.push(va_list_ty);
1012        }
1013        let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
1014        if let Some(self_param) = self.body.self_param
1015            && let Some(ty) = param_tys.next()
1016        {
1017            let ty = self.insert_type_vars(ty);
1018            let ty = self.normalize_associated_types_in(ty);
1019            self.write_binding_ty(self_param, ty);
1020        }
1021        let mut tait_candidates = FxHashSet::default();
1022        for (ty, pat) in param_tys.zip(&*self.body.params) {
1023            let ty = self.insert_type_vars(ty);
1024            let ty = self.normalize_associated_types_in(ty);
1025
1026            self.infer_top_pat(*pat, &ty, None);
1027            if ty
1028                .data(Interner)
1029                .flags
1030                .intersects(TypeFlags::HAS_TY_OPAQUE.union(TypeFlags::HAS_TY_INFER))
1031            {
1032                tait_candidates.insert(ty);
1033            }
1034        }
1035        let return_ty = match data.ret_type {
1036            Some(return_ty) => {
1037                let return_ty = self.with_ty_lowering(
1038                    &data.store,
1039                    InferenceTyDiagnosticSource::Signature,
1040                    LifetimeElisionKind::for_fn_ret(),
1041                    |ctx| {
1042                        ctx.type_param_mode(ParamLoweringMode::Placeholder)
1043                            .impl_trait_mode(ImplTraitLoweringMode::Opaque);
1044                        ctx.lower_ty(return_ty)
1045                    },
1046                );
1047                let return_ty = self.insert_type_vars(return_ty);
1048                if let Some(rpits) = self.db.return_type_impl_traits(func) {
1049                    // RPIT opaque types use substitution of their parent function.
1050                    let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
1051                    let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
1052                    let result = self.insert_inference_vars_for_impl_trait(
1053                        return_ty,
1054                        fn_placeholders,
1055                        &mut mode,
1056                    );
1057                    if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1058                        tait_candidates.extend(taits);
1059                    }
1060                    let rpits = rpits.skip_binders();
1061                    for (id, _) in rpits.impl_traits.iter() {
1062                        if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
1063                            never!("Missed RPIT in `insert_inference_vars_for_rpit`");
1064                            e.insert(TyKind::Error.intern(Interner));
1065                        }
1066                    }
1067                    result
1068                } else {
1069                    return_ty
1070                }
1071            }
1072            None => self.result.standard_types.unit.clone(),
1073        };
1074
1075        self.return_ty = self.normalize_associated_types_in(return_ty);
1076        self.return_coercion = Some(CoerceMany::new(self.return_ty.clone()));
1077
1078        // Functions might be defining usage sites of TAITs.
1079        // To define an TAITs, that TAIT must appear in the function's signatures.
1080        // So, it suffices to check for params and return types.
1081        fold_tys(
1082            self.return_ty.clone(),
1083            |ty, _| {
1084                match ty.kind(Interner) {
1085                    TyKind::OpaqueType(..)
1086                    | TyKind::Alias(AliasTy::Opaque(..))
1087                    | TyKind::InferenceVar(..) => {
1088                        tait_candidates.insert(self.return_ty.clone());
1089                    }
1090                    _ => {}
1091                }
1092                ty
1093            },
1094            DebruijnIndex::INNERMOST,
1095        );
1096
1097        self.make_tait_coercion_table(tait_candidates.iter());
1098    }
1099
1100    fn insert_inference_vars_for_impl_trait<T>(
1101        &mut self,
1102        t: T,
1103        placeholders: Substitution,
1104        mode: &mut ImplTraitReplacingMode,
1105    ) -> T
1106    where
1107        T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,
1108    {
1109        fold_tys(
1110            t,
1111            |ty, _| {
1112                let opaque_ty_id = match ty.kind(Interner) {
1113                    TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
1114                    _ => return ty,
1115                };
1116                let (impl_traits, idx) =
1117                    match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
1118                        // We don't replace opaque types from other kind with inference vars
1119                        // because `insert_inference_vars_for_impl_traits` for each kinds
1120                        // and unreplaced opaque types of other kind are resolved while
1121                        // inferencing because of `tait_coercion_table`.
1122                        // Moreover, calling `insert_inference_vars_for_impl_traits` with same
1123                        // `placeholders` for other kind may cause trouble because
1124                        // the substs for the bounds of each impl traits do not match
1125                        ImplTraitId::ReturnTypeImplTrait(def, idx) => {
1126                            if matches!(mode, ImplTraitReplacingMode::TypeAlias) {
1127                                // RPITs don't have `tait_coercion_table`, so use inserted inference
1128                                // vars for them.
1129                                if let Some(ty) = self.result.type_of_rpit.get(idx) {
1130                                    return ty.clone();
1131                                }
1132                                return ty;
1133                            }
1134                            (self.db.return_type_impl_traits(def), idx)
1135                        }
1136                        ImplTraitId::TypeAliasImplTrait(def, idx) => {
1137                            if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1138                                // Gather TAITs while replacing RPITs because TAITs inside RPITs
1139                                // may not visited while replacing TAITs
1140                                taits.insert(ty.clone());
1141                                return ty;
1142                            }
1143                            (self.db.type_alias_impl_traits(def), idx)
1144                        }
1145                        _ => unreachable!(),
1146                    };
1147                let Some(impl_traits) = impl_traits else {
1148                    return ty;
1149                };
1150                let bounds = (*impl_traits)
1151                    .map_ref(|its| its.impl_traits[idx].bounds.map_ref(|it| it.iter()));
1152                let var = self.table.new_type_var();
1153                let var_subst = Substitution::from1(Interner, var.clone());
1154                for bound in bounds {
1155                    let predicate = bound.map(|it| it.cloned());
1156                    let predicate = predicate.substitute(Interner, &placeholders);
1157                    let (var_predicate, binders) =
1158                        predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders();
1159                    always!(binders.is_empty(Interner)); // quantified where clauses not yet handled
1160                    let var_predicate = self.insert_inference_vars_for_impl_trait(
1161                        var_predicate,
1162                        placeholders.clone(),
1163                        mode,
1164                    );
1165                    self.push_obligation(var_predicate.cast(Interner));
1166                }
1167                self.result.type_of_rpit.insert(idx, var.clone());
1168                var
1169            },
1170            DebruijnIndex::INNERMOST,
1171        )
1172    }
1173
1174    /// The coercion of a non-inference var into an opaque type should fail,
1175    /// but not in the defining sites of the TAITs.
1176    /// In such cases, we insert an proxy inference var for each TAIT,
1177    /// and coerce into it instead of TAIT itself.
1178    ///
1179    /// The inference var stretagy is effective because;
1180    ///
1181    /// - It can still unify types that coerced into TAITs
1182    /// - We are pushing `impl Trait` bounds into it
1183    ///
1184    /// This function inserts a map that maps the opaque type to that proxy inference var.
1185    fn make_tait_coercion_table<'b>(&mut self, tait_candidates: impl Iterator<Item = &'b Ty>) {
1186        struct TypeAliasImplTraitCollector<'a, 'b> {
1187            db: &'b dyn HirDatabase,
1188            table: &'b mut InferenceTable<'a>,
1189            assocs: FxHashMap<OpaqueTyId, (ImplId, Ty)>,
1190            non_assocs: FxHashMap<OpaqueTyId, Ty>,
1191        }
1192
1193        impl TypeVisitor<Interner> for TypeAliasImplTraitCollector<'_, '_> {
1194            type BreakTy = ();
1195
1196            fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
1197                self
1198            }
1199
1200            fn interner(&self) -> Interner {
1201                Interner
1202            }
1203
1204            fn visit_ty(
1205                &mut self,
1206                ty: &chalk_ir::Ty<Interner>,
1207                outer_binder: DebruijnIndex,
1208            ) -> std::ops::ControlFlow<Self::BreakTy> {
1209                let ty = self.table.resolve_ty_shallow(ty);
1210
1211                if let TyKind::OpaqueType(id, _) = ty.kind(Interner)
1212                    && let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1213                        self.db.lookup_intern_impl_trait_id((*id).into())
1214                {
1215                    let loc = self.db.lookup_intern_type_alias(alias_id);
1216                    match loc.container {
1217                        ItemContainerId::ImplId(impl_id) => {
1218                            self.assocs.insert(*id, (impl_id, ty.clone()));
1219                        }
1220                        ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => {
1221                            self.non_assocs.insert(*id, ty.clone());
1222                        }
1223                        _ => {}
1224                    }
1225                }
1226
1227                ty.super_visit_with(self, outer_binder)
1228            }
1229        }
1230
1231        let mut collector = TypeAliasImplTraitCollector {
1232            db: self.db,
1233            table: &mut self.table,
1234            assocs: FxHashMap::default(),
1235            non_assocs: FxHashMap::default(),
1236        };
1237        for ty in tait_candidates {
1238            _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST);
1239        }
1240
1241        // Non-assoc TAITs can be define-used everywhere as long as they are
1242        // in function signatures or const types, etc
1243        let mut taits = collector.non_assocs;
1244
1245        // assoc TAITs(ATPITs) can be only define-used inside their impl block.
1246        // They cannot be define-used in inner items like in the following;
1247        //
1248        // ```
1249        // impl Trait for Struct {
1250        //     type Assoc = impl Default;
1251        //
1252        //     fn assoc_fn() -> Self::Assoc {
1253        //         let foo: Self::Assoc = true; // Allowed here
1254        //
1255        //         fn inner() -> Self::Assoc {
1256        //              false                   // Not allowed here
1257        //         }
1258        //
1259        //         foo
1260        //     }
1261        // }
1262        // ```
1263        let impl_id = match self.owner {
1264            DefWithBodyId::FunctionId(it) => {
1265                let loc = self.db.lookup_intern_function(it);
1266                if let ItemContainerId::ImplId(impl_id) = loc.container {
1267                    Some(impl_id)
1268                } else {
1269                    None
1270                }
1271            }
1272            DefWithBodyId::ConstId(it) => {
1273                let loc = self.db.lookup_intern_const(it);
1274                if let ItemContainerId::ImplId(impl_id) = loc.container {
1275                    Some(impl_id)
1276                } else {
1277                    None
1278                }
1279            }
1280            _ => None,
1281        };
1282
1283        if let Some(impl_id) = impl_id {
1284            taits.extend(collector.assocs.into_iter().filter_map(|(id, (impl_, ty))| {
1285                if impl_ == impl_id { Some((id, ty)) } else { None }
1286            }));
1287        }
1288
1289        let tait_coercion_table: FxHashMap<_, _> = taits
1290            .into_iter()
1291            .filter_map(|(id, ty)| {
1292                if let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1293                    self.db.lookup_intern_impl_trait_id(id.into())
1294                {
1295                    let subst = TyBuilder::placeholder_subst(self.db, alias_id);
1296                    let ty = self.insert_inference_vars_for_impl_trait(
1297                        ty,
1298                        subst,
1299                        &mut ImplTraitReplacingMode::TypeAlias,
1300                    );
1301                    Some((id, ty))
1302                } else {
1303                    None
1304                }
1305            })
1306            .collect();
1307
1308        if !tait_coercion_table.is_empty() {
1309            self.table.tait_coercion_table = Some(tait_coercion_table);
1310        }
1311    }
1312
1313    fn infer_body(&mut self) {
1314        match self.return_coercion {
1315            Some(_) => self.infer_return(self.body.body_expr),
1316            None => {
1317                _ = self.infer_expr_coerce(
1318                    self.body.body_expr,
1319                    &Expectation::has_type(self.return_ty.clone()),
1320                    ExprIsRead::Yes,
1321                )
1322            }
1323        }
1324    }
1325
1326    fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
1327        self.result.type_of_expr.insert(expr, ty);
1328    }
1329
1330    fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1331        if adjustments.is_empty() {
1332            return;
1333        }
1334        match self.result.expr_adjustments.entry(expr) {
1335            std::collections::hash_map::Entry::Occupied(mut entry) => {
1336                match (&mut entry.get_mut()[..], &adjustments[..]) {
1337                    (
1338                        [Adjustment { kind: Adjust::NeverToAny, target }],
1339                        [.., Adjustment { target: new_target, .. }],
1340                    ) => {
1341                        // NeverToAny coercion can target any type, so instead of adding a new
1342                        // adjustment on top we can change the target.
1343                        *target = new_target.clone();
1344                    }
1345                    _ => {
1346                        *entry.get_mut() = adjustments;
1347                    }
1348                }
1349            }
1350            std::collections::hash_map::Entry::Vacant(entry) => {
1351                entry.insert(adjustments);
1352            }
1353        }
1354    }
1355
1356    fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
1357        self.result.method_resolutions.insert(expr, (func, subst));
1358    }
1359
1360    fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
1361        self.result.variant_resolutions.insert(id, variant);
1362    }
1363
1364    fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
1365        self.result.assoc_resolutions.insert(id, (item, subs));
1366    }
1367
1368    fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
1369        self.result.type_of_pat.insert(pat, ty);
1370    }
1371
1372    fn write_binding_ty(&mut self, id: BindingId, ty: Ty) {
1373        self.result.type_of_binding.insert(id, ty);
1374    }
1375
1376    fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1377        self.diagnostics.push(diagnostic);
1378    }
1379
1380    fn with_ty_lowering<R>(
1381        &mut self,
1382        store: &ExpressionStore,
1383        types_source: InferenceTyDiagnosticSource,
1384        lifetime_elision: LifetimeElisionKind,
1385        f: impl FnOnce(&mut TyLoweringContext<'_>) -> R,
1386    ) -> R {
1387        let mut ctx = TyLoweringContext::new(
1388            self.db,
1389            &self.resolver,
1390            store,
1391            &self.diagnostics,
1392            types_source,
1393            self.generic_def,
1394            lifetime_elision,
1395        );
1396        f(&mut ctx)
1397    }
1398
1399    fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R {
1400        self.with_ty_lowering(
1401            self.body,
1402            InferenceTyDiagnosticSource::Body,
1403            LifetimeElisionKind::Infer,
1404            f,
1405        )
1406    }
1407
1408    fn make_ty(
1409        &mut self,
1410        type_ref: TypeRefId,
1411        store: &ExpressionStore,
1412        type_source: InferenceTyDiagnosticSource,
1413        lifetime_elision: LifetimeElisionKind,
1414    ) -> Ty {
1415        let ty = self
1416            .with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
1417        let ty = self.insert_type_vars(ty);
1418        self.normalize_associated_types_in(ty)
1419    }
1420
1421    fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
1422        self.make_ty(
1423            type_ref,
1424            self.body,
1425            InferenceTyDiagnosticSource::Body,
1426            LifetimeElisionKind::Infer,
1427        )
1428    }
1429
1430    fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const {
1431        let const_ = self.with_ty_lowering(
1432            self.body,
1433            InferenceTyDiagnosticSource::Body,
1434            LifetimeElisionKind::Infer,
1435            |ctx| {
1436                ctx.type_param_mode = ParamLoweringMode::Placeholder;
1437                ctx.lower_const(&const_ref, ty)
1438            },
1439        );
1440        self.insert_type_vars(const_)
1441    }
1442
1443    fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const {
1444        let const_ = self.with_ty_lowering(
1445            self.body,
1446            InferenceTyDiagnosticSource::Body,
1447            LifetimeElisionKind::Infer,
1448            |ctx| {
1449                ctx.type_param_mode = ParamLoweringMode::Placeholder;
1450                ctx.lower_path_as_const(path, ty)
1451            },
1452        );
1453        self.insert_type_vars(const_)
1454    }
1455
1456    fn err_ty(&self) -> Ty {
1457        self.result.standard_types.unknown.clone()
1458    }
1459
1460    fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime {
1461        let lt = self.with_ty_lowering(
1462            self.body,
1463            InferenceTyDiagnosticSource::Body,
1464            LifetimeElisionKind::Infer,
1465            |ctx| ctx.lower_lifetime(lifetime_ref),
1466        );
1467        self.insert_type_vars(lt)
1468    }
1469
1470    /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
1471    fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
1472        self.table.insert_type_vars_shallow(ty)
1473    }
1474
1475    fn insert_type_vars<T>(&mut self, ty: T) -> T
1476    where
1477        T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1478    {
1479        self.table.insert_type_vars(ty)
1480    }
1481
1482    fn push_obligation(&mut self, o: DomainGoal) {
1483        self.table.register_obligation(o.cast(Interner));
1484    }
1485
1486    fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
1487        let ty1 = ty1
1488            .clone()
1489            .try_fold_with(
1490                &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1491                DebruijnIndex::INNERMOST,
1492            )
1493            .unwrap();
1494        let ty2 = ty2
1495            .clone()
1496            .try_fold_with(
1497                &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1498                DebruijnIndex::INNERMOST,
1499            )
1500            .unwrap();
1501        self.table.unify(&ty1, &ty2)
1502    }
1503
1504    /// Attempts to returns the deeply last field of nested structures, but
1505    /// does not apply any normalization in its search. Returns the same type
1506    /// if input `ty` is not a structure at all.
1507    fn struct_tail_without_normalization(&mut self, ty: Ty) -> Ty {
1508        self.struct_tail_with_normalize(ty, identity)
1509    }
1510
1511    /// Returns the deeply last field of nested structures, or the same type if
1512    /// not a structure at all. Corresponds to the only possible unsized field,
1513    /// and its type can be used to determine unsizing strategy.
1514    ///
1515    /// This is parameterized over the normalization strategy (i.e. how to
1516    /// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
1517    /// function to indicate no normalization should take place.
1518    fn struct_tail_with_normalize(
1519        &mut self,
1520        mut ty: Ty,
1521        mut normalize: impl FnMut(Ty) -> Ty,
1522    ) -> Ty {
1523        // FIXME: fetch the limit properly
1524        let recursion_limit = 10;
1525        for iteration in 0.. {
1526            if iteration > recursion_limit {
1527                return self.err_ty();
1528            }
1529            match ty.kind(Interner) {
1530                TyKind::Adt(chalk_ir::AdtId(hir_def::AdtId::StructId(struct_id)), substs) => {
1531                    match self.db.field_types((*struct_id).into()).values().next_back().cloned() {
1532                        Some(field) => {
1533                            ty = field.substitute(Interner, substs);
1534                        }
1535                        None => break,
1536                    }
1537                }
1538                TyKind::Adt(..) => break,
1539                TyKind::Tuple(_, substs) => {
1540                    match substs
1541                        .as_slice(Interner)
1542                        .split_last()
1543                        .and_then(|(last_ty, _)| last_ty.ty(Interner))
1544                    {
1545                        Some(last_ty) => ty = last_ty.clone(),
1546                        None => break,
1547                    }
1548                }
1549                TyKind::Alias(..) => {
1550                    let normalized = normalize(ty.clone());
1551                    if ty == normalized {
1552                        return ty;
1553                    } else {
1554                        ty = normalized;
1555                    }
1556                }
1557                _ => break,
1558            }
1559        }
1560        ty
1561    }
1562
1563    /// Recurses through the given type, normalizing associated types mentioned
1564    /// in it by replacing them by type variables and registering obligations to
1565    /// resolve later. This should be done once for every type we get from some
1566    /// type annotation (e.g. from a let type annotation, field type or function
1567    /// call). `make_ty` handles this already, but e.g. for field types we need
1568    /// to do it as well.
1569    fn normalize_associated_types_in<T>(&mut self, ty: T) -> T
1570    where
1571        T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1572    {
1573        self.table.normalize_associated_types_in(ty)
1574    }
1575
1576    fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
1577        self.table.resolve_ty_shallow(ty)
1578    }
1579
1580    fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
1581        self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
1582    }
1583
1584    fn resolve_associated_type_with_params(
1585        &mut self,
1586        inner_ty: Ty,
1587        assoc_ty: Option<TypeAliasId>,
1588        // FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
1589        // handled when we support them.
1590        params: &[GenericArg],
1591    ) -> Ty {
1592        match assoc_ty {
1593            Some(res_assoc_ty) => {
1594                let trait_ = match res_assoc_ty.lookup(self.db).container {
1595                    hir_def::ItemContainerId::TraitId(trait_) => trait_,
1596                    _ => panic!("resolve_associated_type called with non-associated type"),
1597                };
1598                let ty = self.table.new_type_var();
1599                let mut param_iter = params.iter().cloned();
1600                let trait_ref = TyBuilder::trait_ref(self.db, trait_)
1601                    .push(inner_ty)
1602                    .fill(|_| param_iter.next().unwrap())
1603                    .build();
1604                let alias_eq = AliasEq {
1605                    alias: AliasTy::Projection(ProjectionTy {
1606                        associated_ty_id: to_assoc_type_id(res_assoc_ty),
1607                        substitution: trait_ref.substitution.clone(),
1608                    }),
1609                    ty: ty.clone(),
1610                };
1611                self.push_obligation(trait_ref.cast(Interner));
1612                self.push_obligation(alias_eq.cast(Interner));
1613                ty
1614            }
1615            None => self.err_ty(),
1616        }
1617    }
1618
1619    fn resolve_variant(
1620        &mut self,
1621        node: ExprOrPatId,
1622        path: Option<&Path>,
1623        value_ns: bool,
1624    ) -> (Ty, Option<VariantId>) {
1625        let path = match path {
1626            Some(path) => path,
1627            None => return (self.err_ty(), None),
1628        };
1629        let mut ctx = TyLoweringContext::new(
1630            self.db,
1631            &self.resolver,
1632            &self.body.store,
1633            &self.diagnostics,
1634            InferenceTyDiagnosticSource::Body,
1635            self.generic_def,
1636            LifetimeElisionKind::Infer,
1637        );
1638        let mut path_ctx = ctx.at_path(path, node);
1639        let (resolution, unresolved) = if value_ns {
1640            let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
1641                return (self.err_ty(), None);
1642            };
1643            match res {
1644                ResolveValueResult::ValueNs(value, _) => match value {
1645                    ValueNs::EnumVariantId(var) => {
1646                        let substs = path_ctx.substs_from_path(var.into(), true, false);
1647                        drop(ctx);
1648                        let ty = self.db.ty(var.lookup(self.db).parent.into());
1649                        let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1650                        return (ty, Some(var.into()));
1651                    }
1652                    ValueNs::StructId(strukt) => {
1653                        let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1654                        drop(ctx);
1655                        let ty = self.db.ty(strukt.into());
1656                        let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1657                        return (ty, Some(strukt.into()));
1658                    }
1659                    ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
1660                    _ => {
1661                        drop(ctx);
1662                        return (self.err_ty(), None);
1663                    }
1664                },
1665                ResolveValueResult::Partial(typens, unresolved, _) => (typens, Some(unresolved)),
1666            }
1667        } else {
1668            match path_ctx.resolve_path_in_type_ns() {
1669                Some((it, idx)) => (it, idx),
1670                None => return (self.err_ty(), None),
1671            }
1672        };
1673        return match resolution {
1674            TypeNs::AdtId(AdtId::StructId(strukt)) => {
1675                let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1676                drop(ctx);
1677                let ty = self.db.ty(strukt.into());
1678                let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1679                forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
1680            }
1681            TypeNs::AdtId(AdtId::UnionId(u)) => {
1682                let substs = path_ctx.substs_from_path(u.into(), true, false);
1683                drop(ctx);
1684                let ty = self.db.ty(u.into());
1685                let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1686                forbid_unresolved_segments((ty, Some(u.into())), unresolved)
1687            }
1688            TypeNs::EnumVariantId(var) => {
1689                let substs = path_ctx.substs_from_path(var.into(), true, false);
1690                drop(ctx);
1691                let ty = self.db.ty(var.lookup(self.db).parent.into());
1692                let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1693                forbid_unresolved_segments((ty, Some(var.into())), unresolved)
1694            }
1695            TypeNs::SelfType(impl_id) => {
1696                let generics = crate::generics::generics(self.db, impl_id.into());
1697                let substs = generics.placeholder_subst(self.db);
1698                let mut ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
1699
1700                let Some(remaining_idx) = unresolved else {
1701                    drop(ctx);
1702                    let Some(mod_path) = path.mod_path() else {
1703                        never!("resolver should always resolve lang item paths");
1704                        return (self.err_ty(), None);
1705                    };
1706                    return self.resolve_variant_on_alias(ty, None, mod_path);
1707                };
1708
1709                let mut remaining_segments = path.segments().skip(remaining_idx);
1710
1711                if remaining_segments.len() >= 2 {
1712                    path_ctx.ignore_last_segment();
1713                }
1714
1715                // We need to try resolving unresolved segments one by one because each may resolve
1716                // to a projection, which `TyLoweringContext` cannot handle on its own.
1717                let mut tried_resolving_once = false;
1718                while let Some(current_segment) = remaining_segments.first() {
1719                    // If we can resolve to an enum variant, it takes priority over associated type
1720                    // of the same name.
1721                    if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1722                        let enum_data = id.enum_variants(self.db);
1723                        if let Some(variant) = enum_data.variant(current_segment.name) {
1724                            return if remaining_segments.len() == 1 {
1725                                (ty, Some(variant.into()))
1726                            } else {
1727                                // We still have unresolved paths, but enum variants never have
1728                                // associated types!
1729                                // FIXME: Report an error.
1730                                (self.err_ty(), None)
1731                            };
1732                        }
1733                    }
1734
1735                    if tried_resolving_once {
1736                        // FIXME: with `inherent_associated_types` this is allowed, but our `lower_partly_resolved_path()`
1737                        // will need to be updated to err at the correct segment.
1738                        break;
1739                    }
1740
1741                    // `lower_partly_resolved_path()` returns `None` as type namespace unless
1742                    // `remaining_segments` is empty, which is never the case here. We don't know
1743                    // which namespace the new `ty` is in until normalized anyway.
1744                    (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true);
1745                    tried_resolving_once = true;
1746
1747                    ty = self.table.insert_type_vars(ty);
1748                    ty = self.table.normalize_associated_types_in(ty);
1749                    ty = self.table.resolve_ty_shallow(&ty);
1750                    if ty.is_unknown() {
1751                        return (self.err_ty(), None);
1752                    }
1753
1754                    remaining_segments = remaining_segments.skip(1);
1755                }
1756                drop(ctx);
1757
1758                let variant = ty.as_adt().and_then(|(id, _)| match id {
1759                    AdtId::StructId(s) => Some(VariantId::StructId(s)),
1760                    AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1761                    AdtId::EnumId(_) => {
1762                        // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1763                        None
1764                    }
1765                });
1766                (ty, variant)
1767            }
1768            TypeNs::TypeAliasId(it) => {
1769                let Some(mod_path) = path.mod_path() else {
1770                    never!("resolver should always resolve lang item paths");
1771                    return (self.err_ty(), None);
1772                };
1773                let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false);
1774                drop(ctx);
1775                let ty = self.db.ty(it.into());
1776                let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1777
1778                self.resolve_variant_on_alias(ty, unresolved, mod_path)
1779            }
1780            TypeNs::AdtSelfType(_) => {
1781                // FIXME this could happen in array size expressions, once we're checking them
1782                (self.err_ty(), None)
1783            }
1784            TypeNs::GenericParam(_) => {
1785                // FIXME potentially resolve assoc type
1786                (self.err_ty(), None)
1787            }
1788            TypeNs::AdtId(AdtId::EnumId(_))
1789            | TypeNs::BuiltinType(_)
1790            | TypeNs::TraitId(_)
1791            | TypeNs::ModuleId(_) => {
1792                // FIXME diagnostic
1793                (self.err_ty(), None)
1794            }
1795        };
1796
1797        fn forbid_unresolved_segments(
1798            result: (Ty, Option<VariantId>),
1799            unresolved: Option<usize>,
1800        ) -> (Ty, Option<VariantId>) {
1801            if unresolved.is_none() {
1802                result
1803            } else {
1804                // FIXME diagnostic
1805                (TyKind::Error.intern(Interner), None)
1806            }
1807        }
1808    }
1809
1810    fn resolve_variant_on_alias(
1811        &mut self,
1812        ty: Ty,
1813        unresolved: Option<usize>,
1814        path: &ModPath,
1815    ) -> (Ty, Option<VariantId>) {
1816        let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
1817        let ty = match ty.kind(Interner) {
1818            TyKind::Alias(AliasTy::Projection(proj_ty)) => {
1819                let ty = self.table.normalize_projection_ty(proj_ty.clone());
1820                self.table.resolve_ty_shallow(&ty)
1821            }
1822            _ => ty,
1823        };
1824        match remaining {
1825            None => {
1826                let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
1827                    AdtId::StructId(s) => Some(VariantId::StructId(s)),
1828                    AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1829                    AdtId::EnumId(_) => {
1830                        // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1831                        None
1832                    }
1833                });
1834                (ty, variant)
1835            }
1836            Some(1) => {
1837                let segment = path.segments().last().unwrap();
1838                // this could be an enum variant or associated type
1839                if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1840                    let enum_data = enum_id.enum_variants(self.db);
1841                    if let Some(variant) = enum_data.variant(segment) {
1842                        return (ty, Some(variant.into()));
1843                    }
1844                }
1845                // FIXME potentially resolve assoc type
1846                (self.err_ty(), None)
1847            }
1848            Some(_) => {
1849                // FIXME diagnostic
1850                (self.err_ty(), None)
1851            }
1852        }
1853    }
1854
1855    fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
1856        let krate = self.resolver.krate();
1857        lang_item(self.db, krate, item)
1858    }
1859
1860    fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
1861        trait_.trait_items(self.db).associated_type_by_name(&Name::new_symbol_root(sym::Output))
1862    }
1863
1864    fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {
1865        self.resolve_lang_item(lang)?.as_trait()
1866    }
1867
1868    fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
1869        self.resolve_output_on(self.resolve_lang_trait(LangItem::Neg)?)
1870    }
1871
1872    fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
1873        self.resolve_output_on(self.resolve_lang_trait(LangItem::Not)?)
1874    }
1875
1876    fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
1877        let ItemContainerId::TraitId(trait_) = self
1878            .resolve_lang_item(LangItem::IntoFutureIntoFuture)?
1879            .as_function()?
1880            .lookup(self.db)
1881            .container
1882        else {
1883            return None;
1884        };
1885        self.resolve_output_on(trait_)
1886    }
1887
1888    fn resolve_boxed_box(&self) -> Option<AdtId> {
1889        let struct_ = self.resolve_lang_item(LangItem::OwnedBox)?.as_struct()?;
1890        Some(struct_.into())
1891    }
1892
1893    fn resolve_range_full(&self) -> Option<AdtId> {
1894        let struct_ = self.resolve_lang_item(LangItem::RangeFull)?.as_struct()?;
1895        Some(struct_.into())
1896    }
1897
1898    fn resolve_range(&self) -> Option<AdtId> {
1899        let struct_ = self.resolve_lang_item(LangItem::Range)?.as_struct()?;
1900        Some(struct_.into())
1901    }
1902
1903    fn resolve_range_inclusive(&self) -> Option<AdtId> {
1904        let struct_ = self.resolve_lang_item(LangItem::RangeInclusiveStruct)?.as_struct()?;
1905        Some(struct_.into())
1906    }
1907
1908    fn resolve_range_from(&self) -> Option<AdtId> {
1909        let struct_ = self.resolve_lang_item(LangItem::RangeFrom)?.as_struct()?;
1910        Some(struct_.into())
1911    }
1912
1913    fn resolve_range_to(&self) -> Option<AdtId> {
1914        let struct_ = self.resolve_lang_item(LangItem::RangeTo)?.as_struct()?;
1915        Some(struct_.into())
1916    }
1917
1918    fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
1919        let struct_ = self.resolve_lang_item(LangItem::RangeToInclusive)?.as_struct()?;
1920        Some(struct_.into())
1921    }
1922
1923    fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
1924        self.resolve_output_on(self.resolve_lang_trait(LangItem::Index)?)
1925    }
1926
1927    fn resolve_va_list(&self) -> Option<AdtId> {
1928        let struct_ = self.resolve_lang_item(LangItem::VaList)?.as_struct()?;
1929        Some(struct_.into())
1930    }
1931
1932    fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
1933        let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
1934        if b_traits.peek().is_some() {
1935            Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
1936        } else {
1937            Either::Right(&self.traits_in_scope)
1938        }
1939    }
1940}
1941
1942/// When inferring an expression, we propagate downward whatever type hint we
1943/// are able in the form of an `Expectation`.
1944#[derive(Clone, PartialEq, Eq, Debug)]
1945pub(crate) enum Expectation {
1946    None,
1947    HasType(Ty),
1948    #[allow(dead_code)]
1949    Castable(Ty),
1950    RValueLikeUnsized(Ty),
1951}
1952
1953impl Expectation {
1954    /// The expectation that the type of the expression needs to equal the given
1955    /// type.
1956    fn has_type(ty: Ty) -> Self {
1957        if ty.is_unknown() {
1958            // FIXME: get rid of this?
1959            Expectation::None
1960        } else {
1961            Expectation::HasType(ty)
1962        }
1963    }
1964
1965    /// The following explanation is copied straight from rustc:
1966    /// Provides an expectation for an rvalue expression given an *optional*
1967    /// hint, which is not required for type safety (the resulting type might
1968    /// be checked higher up, as is the case with `&expr` and `box expr`), but
1969    /// is useful in determining the concrete type.
1970    ///
1971    /// The primary use case is where the expected type is a fat pointer,
1972    /// like `&[isize]`. For example, consider the following statement:
1973    ///
1974    ///     let it: &[isize] = &[1, 2, 3];
1975    ///
1976    /// In this case, the expected type for the `&[1, 2, 3]` expression is
1977    /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
1978    /// expectation `ExpectHasType([isize])`, that would be too strong --
1979    /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
1980    /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
1981    /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
1982    /// which still is useful, because it informs integer literals and the like.
1983    /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
1984    /// for examples of where this comes up,.
1985    fn rvalue_hint(ctx: &mut InferenceContext<'_>, ty: Ty) -> Self {
1986        match ctx.struct_tail_without_normalization(ty.clone()).kind(Interner) {
1987            TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
1988            _ => Expectation::has_type(ty),
1989        }
1990    }
1991
1992    /// This expresses no expectation on the type.
1993    fn none() -> Self {
1994        Expectation::None
1995    }
1996
1997    fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1998        match self {
1999            Expectation::None => Expectation::None,
2000            Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
2001            Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
2002            Expectation::RValueLikeUnsized(t) => {
2003                Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
2004            }
2005        }
2006    }
2007
2008    fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2009        match self.resolve(table) {
2010            Expectation::None => None,
2011            Expectation::HasType(t)
2012            | Expectation::Castable(t)
2013            | Expectation::RValueLikeUnsized(t) => Some(t),
2014        }
2015    }
2016
2017    fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2018        match self {
2019            Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
2020            Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2021                None
2022            }
2023        }
2024    }
2025
2026    fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
2027        self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
2028    }
2029
2030    /// Comment copied from rustc:
2031    /// Disregard "castable to" expectations because they
2032    /// can lead us astray. Consider for example `if cond
2033    /// {22} else {c} as u8` -- if we propagate the
2034    /// "castable to u8" constraint to 22, it will pick the
2035    /// type 22u8, which is overly constrained (c might not
2036    /// be a u8). In effect, the problem is that the
2037    /// "castable to" expectation is not the tightest thing
2038    /// we can say, so we want to drop it in this case.
2039    /// The tightest thing we can say is "must unify with
2040    /// else branch". Note that in the case of a "has type"
2041    /// constraint, this limitation does not hold.
2042    ///
2043    /// If the expected type is just a type variable, then don't use
2044    /// an expected type. Otherwise, we might write parts of the type
2045    /// when checking the 'then' block which are incompatible with the
2046    /// 'else' branch.
2047    fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
2048        match self {
2049            Expectation::HasType(ety) => {
2050                let ety = table.resolve_ty_shallow(ety);
2051                if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2052            }
2053            Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
2054            _ => Expectation::None,
2055        }
2056    }
2057}
2058
2059#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2060enum Diverges {
2061    Maybe,
2062    Always,
2063}
2064
2065impl Diverges {
2066    fn is_always(self) -> bool {
2067        self == Diverges::Always
2068    }
2069}
2070
2071impl std::ops::BitAnd for Diverges {
2072    type Output = Self;
2073    fn bitand(self, other: Self) -> Self {
2074        std::cmp::min(self, other)
2075    }
2076}
2077
2078impl std::ops::BitOr for Diverges {
2079    type Output = Self;
2080    fn bitor(self, other: Self) -> Self {
2081        std::cmp::max(self, other)
2082    }
2083}
2084
2085impl std::ops::BitAndAssign for Diverges {
2086    fn bitand_assign(&mut self, other: Self) {
2087        *self = *self & other;
2088    }
2089}
2090
2091impl std::ops::BitOrAssign for Diverges {
2092    fn bitor_assign(&mut self, other: Self) {
2093        *self = *self | other;
2094    }
2095}
2096
2097/// A zipper that checks for unequal occurrences of `{unknown}` and unresolved projections
2098/// in the two types. Used to filter out mismatch diagnostics that only differ in
2099/// `{unknown}` and unresolved projections. These mismatches are usually not helpful.
2100/// As the cause is usually an underlying name resolution problem
2101struct UnknownMismatch<'db>(&'db dyn HirDatabase);
2102impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
2103    fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> {
2104        let zip_substs = |this: &mut Self,
2105                          variances,
2106                          sub_a: &Substitution,
2107                          sub_b: &Substitution| {
2108            this.zip_substs(variance, variances, sub_a.as_slice(Interner), sub_b.as_slice(Interner))
2109        };
2110        match (a.kind(Interner), b.kind(Interner)) {
2111            (TyKind::Adt(id_a, sub_a), TyKind::Adt(id_b, sub_b)) if id_a == id_b => zip_substs(
2112                self,
2113                Some(self.unification_database().adt_variance(*id_a)),
2114                sub_a,
2115                sub_b,
2116            )?,
2117            (
2118                TyKind::AssociatedType(assoc_ty_a, sub_a),
2119                TyKind::AssociatedType(assoc_ty_b, sub_b),
2120            ) if assoc_ty_a == assoc_ty_b => zip_substs(self, None, sub_a, sub_b)?,
2121            (TyKind::Tuple(arity_a, sub_a), TyKind::Tuple(arity_b, sub_b))
2122                if arity_a == arity_b =>
2123            {
2124                zip_substs(self, None, sub_a, sub_b)?
2125            }
2126            (TyKind::OpaqueType(opaque_ty_a, sub_a), TyKind::OpaqueType(opaque_ty_b, sub_b))
2127                if opaque_ty_a == opaque_ty_b =>
2128            {
2129                zip_substs(self, None, sub_a, sub_b)?
2130            }
2131            (TyKind::Slice(ty_a), TyKind::Slice(ty_b)) => self.zip_tys(variance, ty_a, ty_b)?,
2132            (TyKind::FnDef(fn_def_a, sub_a), TyKind::FnDef(fn_def_b, sub_b))
2133                if fn_def_a == fn_def_b =>
2134            {
2135                zip_substs(
2136                    self,
2137                    Some(self.unification_database().fn_def_variance(*fn_def_a)),
2138                    sub_a,
2139                    sub_b,
2140                )?
2141            }
2142            (TyKind::Ref(mutability_a, _, ty_a), TyKind::Ref(mutability_b, _, ty_b))
2143                if mutability_a == mutability_b =>
2144            {
2145                self.zip_tys(variance, ty_a, ty_b)?
2146            }
2147            (TyKind::Raw(mutability_a, ty_a), TyKind::Raw(mutability_b, ty_b))
2148                if mutability_a == mutability_b =>
2149            {
2150                self.zip_tys(variance, ty_a, ty_b)?
2151            }
2152            (TyKind::Array(ty_a, const_a), TyKind::Array(ty_b, const_b)) if const_a == const_b => {
2153                self.zip_tys(variance, ty_a, ty_b)?
2154            }
2155            (TyKind::Closure(id_a, sub_a), TyKind::Closure(id_b, sub_b)) if id_a == id_b => {
2156                zip_substs(self, None, sub_a, sub_b)?
2157            }
2158            (TyKind::Coroutine(coroutine_a, sub_a), TyKind::Coroutine(coroutine_b, sub_b))
2159                if coroutine_a == coroutine_b =>
2160            {
2161                zip_substs(self, None, sub_a, sub_b)?
2162            }
2163            (
2164                TyKind::CoroutineWitness(coroutine_a, sub_a),
2165                TyKind::CoroutineWitness(coroutine_b, sub_b),
2166            ) if coroutine_a == coroutine_b => zip_substs(self, None, sub_a, sub_b)?,
2167            (TyKind::Function(fn_ptr_a), TyKind::Function(fn_ptr_b))
2168                if fn_ptr_a.sig == fn_ptr_b.sig && fn_ptr_a.num_binders == fn_ptr_b.num_binders =>
2169            {
2170                zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)?
2171            }
2172            (TyKind::Error, TyKind::Error) => (),
2173            (TyKind::Error, _)
2174            | (_, TyKind::Error)
2175            | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _)
2176            | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => {
2177                return Err(chalk_ir::NoSolution);
2178            }
2179            _ => (),
2180        }
2181
2182        Ok(())
2183    }
2184
2185    fn zip_lifetimes(&mut self, _: Variance, _: &Lifetime, _: &Lifetime) -> chalk_ir::Fallible<()> {
2186        Ok(())
2187    }
2188
2189    fn zip_consts(&mut self, _: Variance, _: &Const, _: &Const) -> chalk_ir::Fallible<()> {
2190        Ok(())
2191    }
2192
2193    fn zip_binders<T>(
2194        &mut self,
2195        variance: Variance,
2196        a: &Binders<T>,
2197        b: &Binders<T>,
2198    ) -> chalk_ir::Fallible<()>
2199    where
2200        T: Clone
2201            + HasInterner<Interner = Interner>
2202            + chalk_ir::zip::Zip<Interner>
2203            + TypeFoldable<Interner>,
2204    {
2205        chalk_ir::zip::Zip::zip_with(self, variance, a.skip_binders(), b.skip_binders())
2206    }
2207
2208    fn interner(&self) -> Interner {
2209        Interner
2210    }
2211
2212    fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> {
2213        &self.0
2214    }
2215}