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