Skip to main content

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_typeck/check.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//!
16//! [`rustc_hir_typeck/check.rs`]: https://github.com/rust-lang/rust/blob/5503df87342a73d0c29126a7e08dc9c1255c46ad/compiler/rustc_hir_typeck/src/check.rs
17
18mod autoderef;
19mod callee;
20pub(crate) mod cast;
21pub(crate) mod closure;
22mod coerce;
23pub(crate) mod diagnostics;
24mod expr;
25mod fallback;
26mod mutability;
27mod op;
28mod opaques;
29mod pat;
30mod path;
31mod place_op;
32pub(crate) mod unify;
33
34use std::{
35    cell::{OnceCell, RefCell},
36    cmp,
37    convert::identity,
38    fmt,
39    hash::Hash,
40    ops::Deref,
41};
42
43use base_db::{Crate, FxIndexMap};
44use either::Either;
45use hir_def::{
46    AdtId, AssocItemId, AttrDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId,
47    GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId,
48    VariantId,
49    attrs::AttrFlags,
50    expr_store::{Body, ExpressionStore, HygieneId, body::Param, path::Path},
51    hir::{BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked, LabelId, PatId, UnaryOp},
52    lang_item::LangItems,
53    layout::Integer,
54    resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
55    signatures::EnumSignature,
56    type_ref::{LifetimeRefId, TypeRefId},
57    unstable_features::UnstableFeatures,
58};
59use hir_expand::{mod_path::ModPath, name::Name};
60use indexmap::IndexSet;
61use la_arena::ArenaMap;
62use macros::{TypeFoldable, TypeVisitable};
63use rustc_abi::TargetDataLayout;
64use rustc_ast_ir::Mutability;
65use rustc_hash::{FxHashMap, FxHashSet};
66use rustc_type_ir::{
67    AliasTyKind, TypeFoldable, TypeVisitableExt,
68    inherent::{GenericArgs as _, IntoKind, Ty as _},
69};
70use salsa::SalsaValue;
71use smallvec::SmallVec;
72use span::Edition;
73use stdx::never;
74use thin_vec::ThinVec;
75
76use crate::{
77    ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,
78    TargetFeatures, ValueTyDefId,
79    closure_analysis::PlaceBase,
80    consteval::{create_anon_const, path_to_const},
81    db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},
82    generics::Generics,
83    infer::{
84        callee::DeferredCallResolution,
85        closure::analysis::{
86            BorrowKind,
87            expr_use_visitor::{FakeReadCause, Place},
88        },
89        coerce::{CoerceMany, DynamicCoerceMany},
90        diagnostics::{
91            Diagnostics, InferenceTyLoweringContext as TyLoweringContext,
92            InferenceTyLoweringVarsCtx,
93        },
94        expr::ExprIsRead,
95        pat::PatOrigin,
96        unify::resolve_completely::WriteBackCtxt,
97    },
98    lower::{
99        ImplTraitIdx, LifetimeElisionKind, LifetimeLoweringMode, LoweringMode,
100        diagnostics::TyLoweringDiagnostic,
101    },
102    method_resolution::CandidateId,
103    next_solver::{
104        AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, StoredFnSig,
105        StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,
106        abi::Safety,
107        infer::{InferCtxt, ObligationInspector, traits::ObligationCause},
108    },
109    solver_errors::SolverDiagnostic,
110    utils::TargetFeatureIsSafeInTarget,
111};
112
113pub use coerce::could_coerce;
114pub use unify::{could_unify, could_unify_deeply};
115
116use cast::{CastCheck, CastError};
117
118/// The entry point of type inference.
119fn infer_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {
120    infer_query_with_inspect(db, def, None, LoweringMode::Analysis)
121}
122
123pub fn infer_query_with_inspect<'db>(
124    db: &'db dyn HirDatabase,
125    def: DefWithBodyId,
126    inspect: Option<ObligationInspector<'db>>,
127    lowering_mode: LoweringMode,
128) -> InferenceResult<'db> {
129    let _p = tracing::info_span!("infer_query").entered();
130    let resolver = def.resolver(db);
131    let body = Body::of(db, def);
132    let mut ctx = InferenceContext::new(
133        db,
134        InferBodyId::DefWithBodyId(def),
135        ExpressionStoreOwnerId::Body(def),
136        def.generic_def(db),
137        &body.store,
138        resolver,
139        true,
140        lowering_mode,
141    );
142
143    if let Some(inspect) = inspect {
144        ctx.table.infer_ctxt.attach_obligation_inspector(inspect);
145    }
146
147    match def {
148        DefWithBodyId::FunctionId(f) => {
149            ctx.collect_fn(f, body.self_param.map(|param| param.formal), &body.params)
150        }
151        DefWithBodyId::ConstId(c) => ctx.collect_const_or_static(c.into()),
152        DefWithBodyId::StaticId(s) => ctx.collect_const_or_static(s.into()),
153        DefWithBodyId::VariantId(v) => {
154            ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {
155                hir_def::layout::IntegerType::Pointer(signed) => match signed {
156                    true => ctx.types.types.isize,
157                    false => ctx.types.types.usize,
158                },
159                hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
160                    true => match size {
161                        Integer::I8 => ctx.types.types.i8,
162                        Integer::I16 => ctx.types.types.i16,
163                        Integer::I32 => ctx.types.types.i32,
164                        Integer::I64 => ctx.types.types.i64,
165                        Integer::I128 => ctx.types.types.i128,
166                    },
167                    false => match size {
168                        Integer::I8 => ctx.types.types.u8,
169                        Integer::I16 => ctx.types.types.u16,
170                        Integer::I32 => ctx.types.types.u32,
171                        Integer::I64 => ctx.types.types.u64,
172                        Integer::I128 => ctx.types.types.u128,
173                    },
174                },
175            };
176        }
177    }
178
179    ctx.infer_body(body.root_expr());
180
181    ctx.infer_mut_body(body.root_expr());
182
183    infer_finalize(ctx)
184}
185
186fn infer_cycle_result<'db>(
187    db: &'db dyn HirDatabase,
188    _: salsa::Id,
189    _: DefWithBodyId,
190) -> InferenceResult<'db> {
191    InferenceResult {
192        has_errors: true,
193        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
194    }
195}
196
197/// Infer types for an anonymous const expression.
198fn infer_anon_const_query<'db>(
199    db: &'db dyn HirDatabase,
200    def: AnonConstId<'db>,
201) -> InferenceResult<'db> {
202    let _p = tracing::info_span!("infer_anon_const_query").entered();
203    let loc = def.loc(db);
204    let store_owner = loc.owner;
205    let store = ExpressionStore::of(db, store_owner);
206
207    let resolver = store_owner.resolver(db);
208
209    let mut ctx = InferenceContext::new(
210        db,
211        InferBodyId::AnonConstId(def),
212        store_owner,
213        loc.owner.generic_def(db),
214        store,
215        resolver,
216        loc.allow_using_generic_params,
217        LoweringMode::Analysis,
218    );
219
220    ctx.infer_expr(
221        loc.expr,
222        &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),
223        ExprIsRead::Yes,
224    );
225
226    infer_finalize(ctx)
227}
228
229fn infer_anon_const_cycle_result<'db>(
230    db: &'db dyn HirDatabase,
231    _: salsa::Id,
232    _: AnonConstId<'db>,
233) -> InferenceResult<'db> {
234    InferenceResult {
235        has_errors: true,
236        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
237    }
238}
239
240fn infer_finalize<'db>(mut ctx: InferenceContext<'db>) -> InferenceResult<'db> {
241    ctx.handle_opaque_type_uses();
242
243    ctx.type_inference_fallback();
244
245    // Comment from rustc:
246    // Even though coercion casts provide type hints, we check casts after fallback for
247    // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
248    let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);
249    for mut cast in cast_checks.into_iter() {
250        if let Err(diag) = cast.check(&mut ctx) {
251            ctx.diagnostics.push(diag);
252        }
253    }
254
255    ctx.table.select_obligations_where_possible();
256
257    // Closure and coroutine analysis may run after fallback
258    // because they don't constrain other type variables.
259    ctx.closure_analyze();
260    assert!(ctx.deferred_call_resolutions.is_empty());
261
262    ctx.table.select_obligations_where_possible();
263
264    ctx.handle_opaque_type_uses();
265
266    ctx.merge_anon_consts();
267
268    ctx.resolve_all()
269}
270
271#[derive(Clone, Copy, Debug, Eq, PartialEq)]
272pub enum ByRef {
273    Yes(Mutability),
274    No,
275}
276
277/// The mode of a binding (`mut`, `ref mut`, etc).
278/// Used for both the explicit binding annotations given in the HIR for a binding
279/// and the final binding mode that we infer after type inference/match ergonomics.
280/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
281/// `.1` is the mutability of the binding.
282#[derive(Copy, Clone, Debug, Eq, PartialEq)]
283pub struct BindingMode(pub ByRef, pub Mutability);
284
285#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]
286pub enum InferenceDiagnostic {
287    NoSuchField {
288        #[type_visitable(ignore)]
289        field: ExprOrPatIdPacked,
290        #[type_visitable(ignore)]
291        private: Option<LocalFieldId>,
292        #[type_visitable(ignore)]
293        variant: VariantId,
294    },
295    MismatchedArrayPatLen {
296        #[type_visitable(ignore)]
297        pat: PatId,
298        #[type_visitable(ignore)]
299        expected: u64,
300        #[type_visitable(ignore)]
301        found: u64,
302        #[type_visitable(ignore)]
303        has_rest: bool,
304    },
305    ArrayPatternWithoutFixedLength {
306        #[type_visitable(ignore)]
307        pat: PatId,
308    },
309    ExpectedArrayOrSlicePat {
310        #[type_visitable(ignore)]
311        pat: PatId,
312        found: StoredTy,
313    },
314    InvalidRangePatType {
315        #[type_visitable(ignore)]
316        pat: PatId,
317    },
318    DuplicateField {
319        #[type_visitable(ignore)]
320        field: ExprOrPatIdPacked,
321        #[type_visitable(ignore)]
322        variant: VariantId,
323    },
324    PrivateField {
325        #[type_visitable(ignore)]
326        expr: ExprId,
327        #[type_visitable(ignore)]
328        field: FieldId,
329    },
330    PrivateAssocItem {
331        #[type_visitable(ignore)]
332        id: ExprOrPatIdPacked,
333        #[type_visitable(ignore)]
334        item: AssocItemId,
335    },
336    UnresolvedField {
337        #[type_visitable(ignore)]
338        expr: ExprId,
339        receiver: StoredTy,
340        #[type_visitable(ignore)]
341        name: Name,
342        #[type_visitable(ignore)]
343        method_with_same_name_exists: bool,
344    },
345    UnresolvedMethodCall {
346        #[type_visitable(ignore)]
347        expr: ExprId,
348        receiver: StoredTy,
349        #[type_visitable(ignore)]
350        name: Name,
351        /// Contains the type the field resolves to
352        field_with_same_name: Option<StoredTy>,
353        #[type_visitable(ignore)]
354        assoc_func_with_same_name: Option<FunctionId>,
355    },
356    UnresolvedAssocItem {
357        #[type_visitable(ignore)]
358        id: ExprOrPatIdPacked,
359    },
360    UnresolvedIdent {
361        #[type_visitable(ignore)]
362        id: ExprOrPatIdPacked,
363    },
364    // FIXME: This should be emitted in body lowering
365    BreakOutsideOfLoop {
366        #[type_visitable(ignore)]
367        expr: ExprId,
368        #[type_visitable(ignore)]
369        is_break: bool,
370        #[type_visitable(ignore)]
371        bad_value_break: bool,
372    },
373    NonExhaustiveRecordExpr {
374        #[type_visitable(ignore)]
375        expr: ExprId,
376    },
377    NonExhaustiveRecordPat {
378        #[type_visitable(ignore)]
379        pat: PatId,
380        #[type_visitable(ignore)]
381        variant: VariantId,
382    },
383    UnionPatMustHaveExactlyOneField {
384        #[type_visitable(ignore)]
385        pat: PatId,
386    },
387    UnionPatHasRest {
388        #[type_visitable(ignore)]
389        pat: PatId,
390    },
391    FunctionalRecordUpdateOnNonStruct {
392        #[type_visitable(ignore)]
393        base_expr: ExprId,
394    },
395    MismatchedArgCount {
396        #[type_visitable(ignore)]
397        call_expr: ExprId,
398        #[type_visitable(ignore)]
399        expected: usize,
400        #[type_visitable(ignore)]
401        found: usize,
402        /// True when the call goes through the `Fn`/`FnMut`/`FnOnce` trait
403        /// (i.e. arguments were bundled into a tuple). Determines whether the
404        /// diagnostic surface uses E0057 (Fn-trait call) or E0061 (regular call).
405        #[type_visitable(ignore)]
406        is_fn_trait_call: bool,
407    },
408    MismatchedTupleStructPatArgCount {
409        #[type_visitable(ignore)]
410        pat: PatId,
411        #[type_visitable(ignore)]
412        expected: usize,
413        #[type_visitable(ignore)]
414        found: usize,
415    },
416    ExpectedFunction {
417        #[type_visitable(ignore)]
418        call_expr: ExprId,
419        found: StoredTy,
420    },
421    CannotBeDereferenced {
422        #[type_visitable(ignore)]
423        expr: ExprId,
424        found: StoredTy,
425    },
426    UnaryOperatorCannotBeApplied {
427        #[type_visitable(ignore)]
428        expr: ExprId,
429        #[type_visitable(ignore)]
430        op: UnaryOp,
431        found: StoredTy,
432    },
433    MutRefInImmRefPat {
434        #[type_visitable(ignore)]
435        pat: PatId,
436    },
437    CannotImplicitlyDerefTraitObject {
438        #[type_visitable(ignore)]
439        pat: PatId,
440        found: StoredTy,
441    },
442    CannotIndexInto {
443        #[type_visitable(ignore)]
444        expr: ExprId,
445        found: StoredTy,
446    },
447    TypedHole {
448        #[type_visitable(ignore)]
449        expr: ExprId,
450        expected: StoredTy,
451    },
452    CastToUnsized {
453        #[type_visitable(ignore)]
454        expr: ExprId,
455        cast_ty: StoredTy,
456    },
457    InvalidCast {
458        #[type_visitable(ignore)]
459        expr: ExprId,
460        #[type_visitable(ignore)]
461        error: CastError,
462        expr_ty: StoredTy,
463        cast_ty: StoredTy,
464    },
465    TyDiagnostic {
466        #[type_visitable(ignore)]
467        diag: TyLoweringDiagnostic,
468    },
469    PathDiagnostic {
470        #[type_visitable(ignore)]
471        node: ExprOrPatIdPacked,
472        #[type_visitable(ignore)]
473        diag: PathLoweringDiagnostic,
474    },
475    MethodCallIncorrectGenericsLen {
476        #[type_visitable(ignore)]
477        expr: ExprId,
478        #[type_visitable(ignore)]
479        provided_count: u32,
480        #[type_visitable(ignore)]
481        expected_count: u32,
482        #[type_visitable(ignore)]
483        kind: IncorrectGenericsLenKind,
484        #[type_visitable(ignore)]
485        def: GenericDefId,
486    },
487    MethodCallIllegalSizedBound {
488        #[type_visitable(ignore)]
489        call_expr: ExprId,
490    },
491    MethodCallIncorrectGenericsOrder {
492        #[type_visitable(ignore)]
493        expr: ExprId,
494        #[type_visitable(ignore)]
495        param_id: GenericParamId,
496        #[type_visitable(ignore)]
497        arg_idx: u32,
498        /// Whether the `GenericArgs` contains a `Self` arg.
499        #[type_visitable(ignore)]
500        has_self_arg: bool,
501    },
502    InvalidLhsOfAssignment {
503        #[type_visitable(ignore)]
504        lhs: ExprId,
505    },
506    TypeMustBeKnown {
507        #[type_visitable(ignore)]
508        at_point: Span,
509        top_term: Option<StoredGenericArg>,
510    },
511    UnionExprMustHaveExactlyOneField {
512        #[type_visitable(ignore)]
513        expr: ExprId,
514    },
515    TypeMismatch {
516        #[type_visitable(ignore)]
517        node: ExprOrPatIdPacked,
518        expected: StoredTy,
519        found: StoredTy,
520    },
521    SolverDiagnostic(SolverDiagnostic),
522    ExplicitDropMethodUse {
523        #[type_visitable(ignore)]
524        kind: ExplicitDropMethodUseKind,
525    },
526    MutableRefBinding {
527        #[type_visitable(ignore)]
528        pat: PatId,
529    },
530    YieldOutsideCoroutine {
531        #[type_visitable(ignore)]
532        expr: ExprId,
533    },
534    ReturnOutsideFunction {
535        #[type_visitable(ignore)]
536        expr: ExprId,
537        #[type_visitable(ignore)]
538        kind: ReturnKind,
539    },
540    RecordMissingFields {
541        #[type_visitable(ignore)]
542        record: ExprOrPatId,
543        #[type_visitable(ignore)]
544        variant: VariantId,
545        #[type_visitable(ignore)]
546        missed_fields: Vec<LocalFieldId>,
547    },
548}
549
550#[derive(Debug, PartialEq, Eq, Clone, Copy)]
551pub enum ReturnKind {
552    ReturnExpr,
553    BecomeExpr,
554}
555
556#[derive(Debug, PartialEq, Eq, Clone)]
557pub enum ExplicitDropMethodUseKind {
558    MethodCall(ExprId),
559    Path(ExprOrPatIdPacked),
560}
561
562/// Represents coercing a value to a different type of value.
563///
564/// We transform values by following a number of `Adjust` steps in order.
565/// See the documentation on variants of `Adjust` for more details.
566///
567/// Here are some common scenarios:
568///
569/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
570///    Here the pointer will be dereferenced N times (where a dereference can
571///    happen to raw or borrowed pointers or any smart pointer which implements
572///    Deref, including Box<_>). The types of dereferences is given by
573///    `autoderefs`. It can then be auto-referenced zero or one times, indicated
574///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
575///    `false`.
576///
577/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
578///    with a thin pointer, deref a number of times, unsize the underlying data,
579///    then autoref. The 'unsize' phase may change a fixed length array to a
580///    dynamically sized one, a concrete object to a trait object, or statically
581///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
582///    represented by:
583///
584///    ```ignore
585///    Deref(None) -> [i32; 4],
586///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
587///    Unsize -> &[i32],
588///    ```
589///
590///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.
591///    E.g., `struct Foo<T> { it: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
592///    The autoderef and -ref are the same as in the above example, but the type
593///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
594///    the underlying conversions from `[i32; 4]` to `[i32]`.
595///
596/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
597///    that case, we have the pointer we need coming in, so there are no
598///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
599///    At some point, of course, `Box` should move out of the compiler, in which
600///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
601///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
602#[derive(Clone, Debug, PartialEq, Eq, Hash)]
603pub struct Adjustment {
604    pub kind: Adjust,
605    pub target: StoredTy,
606}
607
608impl Adjustment {
609    pub fn borrow<'db>(
610        interner: DbInterner<'db>,
611        m: Mutability,
612        ty: Ty<'db>,
613        lt: Region<'db>,
614    ) -> Self {
615        let ty = Ty::new_ref(interner, lt, ty, m);
616        Adjustment {
617            kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),
618            target: ty.store(),
619        }
620    }
621}
622
623/// At least for initial deployment, we want to limit two-phase borrows to
624/// only a few specific cases. Right now, those are mostly "things that desugar"
625/// into method calls:
626/// - using `x.some_method()` syntax, where some_method takes `&mut self`,
627/// - using `Foo::some_method(&mut x, ...)` syntax,
628/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).
629///
630/// Anything else should be rejected until generalized two-phase borrow support
631/// is implemented. Right now, dataflow can't handle the general case where there
632/// is more than one use of a mutable borrow, and we don't want to accept too much
633/// new code via two-phase borrows, so we try to limit where we create two-phase
634/// capable mutable borrows.
635/// See #49434 for tracking.
636#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
637pub enum AllowTwoPhase {
638    // FIXME: We should use this when appropriate.
639    Yes,
640    No,
641}
642
643#[derive(Clone, Debug, PartialEq, Eq, Hash)]
644pub enum Adjust {
645    /// Go from ! to any type.
646    NeverToAny,
647    /// Dereference once, producing a place.
648    Deref(Option<OverloadedDeref>),
649    /// Take the address and produce either a `&` or `*` pointer.
650    Borrow(AutoBorrow),
651    Pointer(PointerCast),
652}
653
654/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
655/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
656/// The target type is `U` in both cases, with the region and mutability
657/// being those shared by both the receiver and the returned reference.
658#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
659pub struct OverloadedDeref(pub Mutability);
660
661#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
662pub enum AutoBorrowMutability {
663    Mut { allow_two_phase_borrow: AllowTwoPhase },
664    Not,
665}
666
667impl AutoBorrowMutability {
668    /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows.
669    ///
670    /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored
671    pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {
672        match mutbl {
673            Mutability::Not => Self::Not,
674            Mutability::Mut => Self::Mut { allow_two_phase_borrow },
675        }
676    }
677}
678
679impl From<AutoBorrowMutability> for Mutability {
680    fn from(m: AutoBorrowMutability) -> Self {
681        match m {
682            AutoBorrowMutability::Mut { .. } => Mutability::Mut,
683            AutoBorrowMutability::Not => Mutability::Not,
684        }
685    }
686}
687
688#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
689pub enum AutoBorrow {
690    /// Converts from T to &T.
691    Ref(AutoBorrowMutability),
692    /// Converts from T to *T.
693    RawPtr(Mutability),
694}
695
696#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
697pub enum PointerCast {
698    /// Go from a fn-item type to a fn-pointer type.
699    ReifyFnPointer,
700
701    /// Go from a safe fn pointer to an unsafe fn pointer.
702    UnsafeFnPointer,
703
704    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
705    /// It cannot convert a closure that requires unsafe.
706    ClosureFnPointer(Safety),
707
708    /// Go from a mut raw pointer to a const raw pointer.
709    MutToConstPointer,
710
711    #[allow(dead_code)]
712    /// Go from `*const [T; N]` to `*const T`
713    ArrayToPointer,
714
715    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
716    /// `&[T]`. Note that the source could be a thin or fat pointer.
717    /// This will do things like convert thin pointers to fat
718    /// pointers, or convert structs containing thin pointers to
719    /// structs containing fat pointers, or convert between fat
720    /// pointers. We don't store the details of how the transform is
721    /// done (in fact, we don't know that, because it might depend on
722    /// the precise type parameters). We just store the target
723    /// type. Codegen backends and miri figure out what has to be done
724    /// based on the precise source/target type at hand.
725    Unsize,
726}
727
728/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern
729/// against it. Currently, this is used only for implicit dereferences.
730#[derive(Debug, Clone, PartialEq, Eq)]
731pub struct PatAdjustment {
732    pub kind: PatAdjust,
733    /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the
734    /// pattern.
735    pub source: StoredTy,
736}
737
738/// Represents implicit coercions of patterns' types, rather than values' types.
739#[derive(Clone, Copy, PartialEq, Eq, Debug)]
740pub enum PatAdjust {
741    /// An implicit dereference before matching, such as when matching the pattern `0` against a
742    /// scrutinee of type `&u8` or `&mut u8`.
743    BuiltinDeref,
744    /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the
745    /// pattern `[..]` against a scrutinee of type `Vec<T>`.
746    OverloadedDeref,
747}
748
749/// The result of type inference: A mapping from expressions and patterns to types.
750///
751/// When you add a field that stores types (including `Substitution` and the like), don't forget
752/// `resolve_completely()`'ing  them in `InferenceContext::resolve_all()`. Inference variables must
753/// not appear in the final inference result.
754#[derive(Clone, PartialEq, Eq, Debug, SalsaValue)]
755pub struct InferenceResult<'db> {
756    /// For each method call expr, records the function it resolves to.
757    method_resolutions: FxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,
758    /// For each field access expr, records the field it resolves to.
759    field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
760    /// For each struct literal or pattern, records the variant it resolves to.
761    variant_resolutions: FxHashMap<ExprOrPatIdPacked, VariantId>,
762    /// For each associated item record what it resolves to
763    assoc_resolutions: FxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>,
764    /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in
765    /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of
766    /// that which allows us to resolve a [`TupleFieldId`]s type.
767    tuple_field_access_types: ThinVec<StoredTys>,
768
769    pub type_of_expr: ArenaMap<ExprId, StoredTy>,
770    /// For each pattern record the type it resolves to.
771    ///
772    /// **Note**: When a pattern type is resolved it may still contain
773    /// unresolved or missing subpatterns or subpatterns of mismatched types.
774    pub type_of_pat: ArenaMap<PatId, StoredTy>,
775    pub type_of_binding: ArenaMap<BindingId, StoredTy>,
776    pub type_of_type_placeholder: FxHashMap<TypeRefId, StoredTy>,
777    pub type_of_opaque: FxHashMap<InternedOpaqueTyId<'db>, StoredTy>,
778
779    /// Whether there are any type-mismatching errors in the result.
780    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to
781    // `TyKind::Error`.
782    // Which will then mark this field.
783    pub has_errors: bool,
784    /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.
785    diagnostics: ThinVec<InferenceDiagnostic>,
786    // FIXME: Remove this, change it to be in `InferenceContext`:
787    nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatIdPacked>>>,
788
789    /// Interned `Error` type to return references to.
790    // FIXME: Remove this.
791    error_ty: StoredTy,
792
793    pub expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
794    /// Stores the types which were implicitly dereferenced in pattern binding modes.
795    pub pat_adjustments: FxHashMap<PatId, Vec<PatAdjustment>>,
796    /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.
797    ///
798    /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an
799    /// or pattern can have multiple binding modes. For example:
800    /// ```
801    /// fn foo(mut slice: &[u32]) -> usize {
802    ///     slice = match slice {
803    ///         [0, rest @ ..] | rest => rest,
804    ///     };
805    ///     0
806    /// }
807    /// ```
808    /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
809    pub binding_modes: ArenaMap<PatId, BindingMode>,
810
811    /// Set of reference patterns that match against a match-ergonomics inserted reference
812    /// (as opposed to against a reference in the scrutinee type).
813    skipped_ref_pats: FxHashSet<PatId>,
814
815    pub coercion_casts: FxHashSet<ExprId>,
816
817    pub closures_data: FxHashMap<ExprId, ClosureData>,
818
819    defined_anon_consts: ThinVec<AnonConstId<'db>>,
820}
821
822#[derive(Clone, PartialEq, Eq, Debug)]
823pub struct ClosureData {
824    /// Tracks the minimum captures required for a closure;
825    /// see `MinCaptureInformationMap` for more details.
826    pub min_captures: RootVariableMinCaptureList,
827
828    /// Tracks the fake reads required for a closure and the reason for the fake read.
829    /// When performing pattern matching for closures, there are times we don't end up
830    /// reading places that are mentioned in a closure (because of _ patterns). However,
831    /// to ensure the places are initialized, we introduce fake reads.
832    /// Consider these two examples:
833    /// ```ignore (discriminant matching with only wildcard arm)
834    /// let x: u8;
835    /// let c = || match x { _ => () };
836    /// ```
837    /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
838    /// want to capture it. However, we do still want an error here, because `x` should have
839    /// to be initialized at the point where c is created. Therefore, we add a "fake read"
840    /// instead.
841    /// ```ignore (destructured assignments)
842    /// let c = || {
843    ///     let (t1, t2) = t;
844    /// }
845    /// ```
846    /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
847    /// we never capture `t`. This becomes an issue when we build MIR as we require
848    /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
849    /// issue by fake reading `t`.
850    pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,
851
852    /// For each fn, records the "liberated" types of its arguments
853    /// and return type. Liberated means that all bound regions
854    /// (including late-bound regions) are replaced with free
855    /// equivalents. This table is not used in codegen (since regions
856    /// are erased there) and hence is not serialized to metadata.
857    ///
858    /// This table also contains the "revealed" values for any `impl Trait`
859    /// that appear in the signature and whose values are being inferred
860    /// by this function.
861    ///
862    /// # Example
863    ///
864    /// ```rust
865    /// # use std::fmt::Debug;
866    /// fn foo(x: &u32) -> impl Debug { *x }
867    /// ```
868    ///
869    /// The function signature here would be:
870    ///
871    /// ```ignore (illustrative)
872    /// for<'a> fn(&'a u32) -> Foo
873    /// ```
874    ///
875    /// where `Foo` is an opaque type created for this function.
876    ///
877    ///
878    /// The *liberated* form of this would be
879    ///
880    /// ```ignore (illustrative)
881    /// fn(&'a u32) -> u32
882    /// ```
883    ///
884    /// Note that `'a` is not bound (it would be an `ReLateParam`) and
885    /// that the `Foo` opaque type is replaced by its hidden type.
886    pub liberated_sig: StoredFnSig,
887}
888
889/// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`.
890/// Used to track the minimum set of `Place`s that need to be captured to support all
891/// Places captured by the closure starting at a given root variable.
892///
893/// This provides a convenient and quick way of checking if a variable being used within
894/// a closure is a capture of a local variable.
895pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;
896
897/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
898pub(crate) type MinCaptureList = Vec<CapturedPlace>;
899
900/// A composite describing a `Place` that is captured by a closure.
901#[derive(Eq, PartialEq, Clone, Debug, Hash)]
902pub struct CapturedPlace {
903    /// The `Place` that is captured.
904    pub place: Place,
905
906    /// `CaptureKind` and expression(s) that resulted in such capture of `place`.
907    pub info: CaptureInfo,
908
909    /// Represents if `place` can be mutated or not.
910    pub mutability: Mutability,
911}
912
913impl CapturedPlace {
914    pub fn is_by_ref(&self) -> bool {
915        match self.info.capture_kind {
916            UpvarCapture::ByValue | UpvarCapture::ByUse => false,
917            UpvarCapture::ByRef(..) => true,
918        }
919    }
920
921    pub fn captured_local(&self) -> BindingId {
922        match self.place.base {
923            PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,
924            PlaceBase::Rvalue | PlaceBase::StaticItem => {
925                unreachable!("only locals can be captured")
926            }
927        }
928    }
929
930    /// The type of the capture stored in the closure, which is different from the type of the captured place
931    /// if we capture by reference.
932    pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
933        let place_ty = self.place.ty();
934        let make_ref = |mutbl| {
935            let interner = DbInterner::new_no_crate(db);
936            let region = Region::new_erased(interner);
937            Ty::new_ref(interner, region, place_ty, mutbl)
938        };
939        match self.info.capture_kind {
940            UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,
941            UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),
942        }
943    }
944}
945
946#[derive(Clone)]
947pub struct CaptureSourceStack(CaptureSourceStackRepr);
948
949#[derive(Clone)]
950enum CaptureSourceStackRepr {
951    One(ExprOrPatIdPacked),
952    Two([ExprOrPatIdPacked; 2]),
953    Many(ThinVec<ExprOrPatIdPacked>),
954}
955
956impl PartialEq for CaptureSourceStack {
957    fn eq(&self, other: &Self) -> bool {
958        **self == **other
959    }
960}
961
962impl Eq for CaptureSourceStack {}
963
964impl std::hash::Hash for CaptureSourceStack {
965    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
966        (**self).hash(state);
967    }
968}
969
970#[cfg(target_pointer_width = "64")]
971const _: () = assert!(size_of::<CaptureSourceStack>() == 16);
972
973impl Deref for CaptureSourceStack {
974    type Target = [ExprOrPatIdPacked];
975
976    #[inline]
977    fn deref(&self) -> &Self::Target {
978        match &self.0 {
979            CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),
980            CaptureSourceStackRepr::Two(it) => it,
981            CaptureSourceStackRepr::Many(it) => it,
982        }
983    }
984}
985
986impl fmt::Debug for CaptureSourceStack {
987    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
988        f.debug_tuple("CaptureSourceStack").field(&&**self).finish()
989    }
990}
991
992impl CaptureSourceStack {
993    #[inline]
994    pub fn len(&self) -> usize {
995        match &self.0 {
996            CaptureSourceStackRepr::One(_) => 1,
997            CaptureSourceStackRepr::Two(_) => 2,
998            CaptureSourceStackRepr::Many(it) => it.len(),
999        }
1000    }
1001
1002    #[inline]
1003    pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self {
1004        Self(CaptureSourceStackRepr::One(id))
1005    }
1006
1007    #[inline]
1008    pub fn final_source(&self) -> ExprOrPatIdPacked {
1009        *self.last().expect("should always have a final source")
1010    }
1011
1012    pub fn push(&mut self, new_id: ExprOrPatIdPacked) {
1013        match &mut self.0 {
1014            CaptureSourceStackRepr::One(old_id) => {
1015                self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])
1016            }
1017            CaptureSourceStackRepr::Two([old_id1, old_id2]) => {
1018                self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));
1019            }
1020            CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),
1021        }
1022    }
1023
1024    pub fn truncate(&mut self, new_len: usize) {
1025        debug_assert!(new_len > 0);
1026        match &mut self.0 {
1027            CaptureSourceStackRepr::One(_) => {}
1028            CaptureSourceStackRepr::Two([first, _]) => {
1029                if new_len == 1 {
1030                    self.0 = CaptureSourceStackRepr::One(*first)
1031                }
1032            }
1033            CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),
1034        }
1035    }
1036
1037    pub fn shrink_to_fit(&mut self) {
1038        match &mut self.0 {
1039            CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}
1040            CaptureSourceStackRepr::Many(ids) => match **ids {
1041                [one] => self.0 = CaptureSourceStackRepr::One(one),
1042                [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),
1043                _ => ids.shrink_to_fit(),
1044            },
1045        }
1046    }
1047}
1048
1049/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
1050/// for a particular capture as well as identifying the part of the source code
1051/// that triggered this capture to occur.
1052#[derive(Eq, PartialEq, Clone, Debug, Hash)]
1053pub struct CaptureInfo {
1054    pub sources: SmallVec<[CaptureSourceStack; 2]>,
1055
1056    /// Capture mode that was selected
1057    pub capture_kind: UpvarCapture,
1058}
1059
1060/// Information describing the capture of an upvar. This is computed
1061/// during `typeck`, specifically by `regionck`.
1062#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]
1063pub enum UpvarCapture {
1064    /// Upvar is captured by reference.
1065    ByRef(BorrowKind),
1066
1067    /// Upvar is captured by use. This is true when the closure is labeled `use`.
1068    ByUse,
1069
1070    /// Upvar is captured by value. This is always true when the
1071    /// closure is labeled `move`, but can also be true in other cases
1072    /// depending on inference.
1073    ByValue,
1074}
1075
1076// Used in closure::analysis::determine_capture_info
1077impl PartialOrd for UpvarCapture {
1078    #[inline]
1079    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1080        match (self, other) {
1081            (Self::ByValue, Self::ByValue) | (Self::ByUse, Self::ByUse) => {
1082                Some(cmp::Ordering::Equal)
1083            }
1084            (Self::ByValue | Self::ByUse, Self::ByRef(_)) => Some(cmp::Ordering::Greater),
1085            (Self::ByRef(_), Self::ByValue | Self::ByUse) => Some(cmp::Ordering::Less),
1086            (Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(right)),
1087            (Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None,
1088        }
1089    }
1090}
1091
1092#[salsa::tracked]
1093impl<'db> InferenceResult<'db> {
1094    #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
1095    fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {
1096        infer_query(db, def)
1097    }
1098
1099    /// Infer types for all const expressions in an item's signature.
1100    ///
1101    /// Returns an `InferenceResult` containing type information for array lengths,
1102    /// const generic arguments, and other const expressions appearing in type
1103    /// positions within the item's signature.
1104    #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]
1105    fn for_anon_const(db: &'db dyn HirDatabase, def: AnonConstId<'db>) -> InferenceResult<'db> {
1106        infer_anon_const_query(db, def)
1107    }
1108}
1109
1110impl<'db> InferenceResult<'db> {
1111    #[inline]
1112    pub fn of(
1113        db: &'db dyn HirDatabase,
1114        def: impl Into<InferBodyId<'db>>,
1115    ) -> &'db InferenceResult<'db> {
1116        match def.into() {
1117            InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),
1118            InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),
1119        }
1120    }
1121}
1122
1123impl<'db> InferenceResult<'db> {
1124    fn new(error_ty: Ty<'_>) -> Self {
1125        Self {
1126            method_resolutions: Default::default(),
1127            field_resolutions: Default::default(),
1128            variant_resolutions: Default::default(),
1129            assoc_resolutions: Default::default(),
1130            tuple_field_access_types: Default::default(),
1131            diagnostics: Default::default(),
1132            nodes_with_type_mismatches: Default::default(),
1133            type_of_expr: Default::default(),
1134            type_of_pat: Default::default(),
1135            type_of_binding: Default::default(),
1136            type_of_type_placeholder: Default::default(),
1137            type_of_opaque: Default::default(),
1138            skipped_ref_pats: Default::default(),
1139            has_errors: Default::default(),
1140            error_ty: error_ty.store(),
1141            pat_adjustments: Default::default(),
1142            binding_modes: Default::default(),
1143            expr_adjustments: Default::default(),
1144            coercion_casts: Default::default(),
1145            closures_data: Default::default(),
1146            defined_anon_consts: Default::default(),
1147        }
1148    }
1149
1150    pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {
1151        self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))
1152    }
1153    pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
1154        self.field_resolutions.get(&expr).copied()
1155    }
1156    pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
1157        self.variant_resolutions.get(&id.into()).copied()
1158    }
1159    pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
1160        self.variant_resolutions.get(&id.into()).copied()
1161    }
1162    pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
1163        match id {
1164            ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
1165            ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
1166        }
1167    }
1168    pub fn assoc_resolutions_for_expr<'a>(
1169        &self,
1170        id: ExprId,
1171    ) -> Option<(CandidateId, GenericArgs<'a>)> {
1172        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1173    }
1174    pub fn assoc_resolutions_for_pat<'a>(
1175        &self,
1176        id: PatId,
1177    ) -> Option<(CandidateId, GenericArgs<'a>)> {
1178        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1179    }
1180    pub fn assoc_resolutions_for_expr_or_pat<'a>(
1181        &self,
1182        id: ExprOrPatId,
1183    ) -> Option<(CandidateId, GenericArgs<'a>)> {
1184        match id {
1185            ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
1186            ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
1187        }
1188    }
1189    pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool {
1190        self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node))
1191    }
1192    pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {
1193        self.expr_or_pat_has_type_mismatch(expr.into())
1194    }
1195    pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {
1196        self.expr_or_pat_has_type_mismatch(pat.into())
1197    }
1198    pub fn exprs_have_type_mismatches(&self) -> bool {
1199        self.nodes_with_type_mismatches
1200            .as_ref()
1201            .is_some_and(|it| it.iter().any(|node| node.is_expr()))
1202    }
1203    pub fn has_type_mismatches(&self) -> bool {
1204        self.nodes_with_type_mismatches.is_some()
1205    }
1206    pub fn placeholder_types<'a>(&self) -> impl Iterator<Item = (TypeRefId, Ty<'a>)> {
1207        self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref()))
1208    }
1209    pub fn type_of_type_placeholder<'a>(&self, type_ref: TypeRefId) -> Option<Ty<'a>> {
1210        self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref())
1211    }
1212    pub fn type_of_expr_or_pat<'a>(&self, id: ExprOrPatId) -> Option<Ty<'a>> {
1213        match id {
1214            ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()),
1215            ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()),
1216        }
1217    }
1218    pub fn type_of_expr_with_adjust<'a>(&self, id: ExprId) -> Option<Ty<'a>> {
1219        match self.expr_adjustments.get(&id).and_then(|adjustments| {
1220            adjustments.iter().rfind(|adj| {
1221                // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140
1222                !matches!(
1223                    adj,
1224                    Adjustment {
1225                        kind: Adjust::NeverToAny,
1226                        target,
1227                    } if target.as_ref().is_never()
1228                )
1229            })
1230        }) {
1231            Some(adjustment) => Some(adjustment.target.as_ref()),
1232            None => self.type_of_expr.get(id).map(|it| it.as_ref()),
1233        }
1234    }
1235    pub fn type_of_pat_with_adjust<'a>(&self, id: PatId) -> Ty<'a> {
1236        match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
1237            Some(adjusted) => adjusted.source.as_ref(),
1238            None => self.pat_ty(id),
1239        }
1240    }
1241    pub fn is_erroneous(&self) -> bool {
1242        self.has_errors && self.type_of_expr.iter().count() == 0
1243    }
1244
1245    pub fn diagnostics(&self) -> &[InferenceDiagnostic] {
1246        &self.diagnostics
1247    }
1248
1249    pub fn tuple_field_access_type<'a>(&self, id: TupleId) -> Tys<'a> {
1250        self.tuple_field_access_types[id.0 as usize].as_ref()
1251    }
1252
1253    pub fn pat_adjustment(&self, id: PatId) -> Option<&[PatAdjustment]> {
1254        self.pat_adjustments.get(&id).map(|it| &**it)
1255    }
1256
1257    pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {
1258        self.expr_adjustments.get(&id).map(|it| &**it)
1259    }
1260
1261    pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {
1262        self.binding_modes.get(id).copied()
1263    }
1264
1265    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
1266    pub fn expression_types<'a>(&self) -> impl Iterator<Item = (ExprId, Ty<'a>)> {
1267        self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref()))
1268    }
1269
1270    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
1271    pub fn pattern_types<'a>(&self) -> impl Iterator<Item = (PatId, Ty<'a>)> {
1272        self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref()))
1273    }
1274
1275    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
1276    pub fn binding_types<'a>(&self) -> impl Iterator<Item = (BindingId, Ty<'a>)> {
1277        self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref()))
1278    }
1279
1280    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.
1281    pub fn return_position_impl_trait_types<'a>(
1282        &'a self,
1283        db: &'a dyn HirDatabase,
1284    ) -> impl Iterator<Item = (ImplTraitIdx, Ty<'a>)> {
1285        self.type_of_opaque.iter().filter_map(move |(&id, ty)| {
1286            let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {
1287                return None;
1288            };
1289            Some((rpit_idx, ty.as_ref()))
1290        })
1291    }
1292
1293    pub fn expr_ty<'a>(&self, id: ExprId) -> Ty<'a> {
1294        self.type_of_expr.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())
1295    }
1296
1297    pub fn pat_ty<'a>(&self, id: PatId) -> Ty<'a> {
1298        self.type_of_pat.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())
1299    }
1300
1301    pub fn expr_or_pat_ty<'a>(&self, id: ExprOrPatId) -> Ty<'a> {
1302        self.type_of_expr_or_pat(id).unwrap_or(self.error_ty.as_ref())
1303    }
1304
1305    pub fn binding_ty<'a>(&self, id: BindingId) -> Ty<'a> {
1306        self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())
1307    }
1308
1309    /// This does not deduplicate, which means you'll get the types once per capture.
1310    pub fn closure_captures_tys<'a>(&self, closure: ExprId) -> impl Iterator<Item = Ty<'a>> {
1311        self.closures_data[&closure]
1312            .min_captures
1313            .values()
1314            .flat_map(|captures| captures.iter().map(|capture| capture.place.ty()))
1315    }
1316
1317    /// Like [`Self::closure_captures_tys()`], but using [`CapturedPlace::captured_ty()`].
1318    pub fn closure_captures_captured_tys<'a>(
1319        &self,
1320        db: &'a dyn HirDatabase,
1321        closure: ExprId,
1322    ) -> impl Iterator<Item = Ty<'a>> {
1323        self.closures_data[&closure]
1324            .min_captures
1325            .values()
1326            .flat_map(|captures| captures.iter().map(|capture| capture.captured_ty(db)))
1327    }
1328
1329    pub fn is_skipped_ref_pat(&self, pat: PatId) -> bool {
1330        self.skipped_ref_pats.contains(&pat)
1331    }
1332}
1333
1334#[derive(Debug, Clone, Copy)]
1335enum DerefPatBorrowMode {
1336    Borrow(Mutability),
1337    Box,
1338}
1339
1340/// The inference context contains all information needed during type inference.
1341#[derive(Debug)]
1342pub(crate) struct InferenceContext<'db> {
1343    pub(crate) db: &'db dyn HirDatabase,
1344    pub(crate) owner: InferBodyId<'db>,
1345    pub(crate) store_owner: ExpressionStoreOwnerId,
1346    pub(crate) generic_def: GenericDefId,
1347    pub(crate) store: &'db ExpressionStore,
1348    pub(crate) lowering_mode: LoweringMode,
1349    /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
1350    /// and resolve the path via its methods. This will ensure proper error reporting.
1351    pub(crate) resolver: Resolver<'db>,
1352    target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,
1353    data_layout: OnceCell<&'db TargetDataLayout>,
1354    pub(crate) edition: Edition,
1355    allow_using_generic_params: bool,
1356    generics: OnceCell<Generics<'db>>,
1357    identity_args: OnceCell<GenericArgs<'db>>,
1358    pub(crate) table: unify::InferenceTable<'db>,
1359    pub(crate) lang_items: &'db LangItems,
1360    pub(crate) features: &'db UnstableFeatures,
1361    /// The traits in scope, disregarding block modules. This is used for caching purposes.
1362    traits_in_scope: FxHashSet<TraitId>,
1363    pub(crate) result: InferenceResult<'db>,
1364    tuple_field_accesses_rev:
1365        IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
1366    /// The return type of the function being inferred, the closure or async block if we're
1367    /// currently within one.
1368    ///
1369    /// We might consider using a nested inference context for checking
1370    /// closures so we can swap all shared things out at once.
1371    return_ty: Ty<'db>,
1372    /// If `Some`, this stores coercion information for returned
1373    /// expressions. If `None`, this is in a context where return is
1374    /// inappropriate, such as a const expression.
1375    return_coercion: Option<DynamicCoerceMany<'db>>,
1376    /// The resume type and the yield type, respectively, of the coroutine being inferred.
1377    resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,
1378    diverges: Diverges,
1379    breakables: Vec<BreakableContext<'db>>,
1380    types: &'db crate::next_solver::DefaultAny<'db>,
1381
1382    deferred_cast_checks: Vec<CastCheck<'db>>,
1383
1384    /// The key is an expression defining a closure or a coroutine closure.
1385    deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>,
1386
1387    diagnostics: Diagnostics,
1388    vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>,
1389
1390    defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>,
1391}
1392
1393#[derive(Clone, Debug)]
1394struct BreakableContext<'db> {
1395    /// Whether this context contains at least one break expression.
1396    may_break: bool,
1397    /// The coercion target of the context.
1398    coerce: Option<DynamicCoerceMany<'db>>,
1399    /// The optional label of the context.
1400    label: Option<LabelId>,
1401    kind: BreakableKind,
1402}
1403
1404#[derive(Clone, Debug)]
1405enum BreakableKind {
1406    Block,
1407    Loop,
1408    /// A border is something like an async block, closure etc. Anything that prevents
1409    /// breaking/continuing through
1410    Border,
1411}
1412
1413fn find_breakable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {
1414    let mut ctxs = ctxs
1415        .iter()
1416        .enumerate()
1417        .rev()
1418        .take_while(|(_, it)| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
1419    let result = match label {
1420        Some(_) => ctxs.find(|(_, ctx)| ctx.label == label),
1421        None => ctxs.find(|(_, ctx)| matches!(ctx.kind, BreakableKind::Loop)),
1422    };
1423    result.map(|(idx, _)| idx)
1424}
1425
1426fn find_continuable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {
1427    find_breakable(ctxs, label)
1428        .filter(|&idx| label.is_none() || matches!(ctxs[idx].kind, BreakableKind::Loop))
1429}
1430
1431impl<'db> InferenceContext<'db> {
1432    fn new(
1433        db: &'db dyn HirDatabase,
1434        owner: InferBodyId<'db>,
1435        store_owner: ExpressionStoreOwnerId,
1436        generic_def: GenericDefId,
1437        store: &'db ExpressionStore,
1438        resolver: Resolver<'db>,
1439        allow_using_generic_params: bool,
1440        lowering_mode: LoweringMode,
1441    ) -> Self {
1442        let trait_env = db.trait_environment(generic_def);
1443        let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), owner);
1444        let types = crate::next_solver::default_types();
1445        InferenceContext {
1446            result: InferenceResult::new(types.types.error),
1447            return_ty: types.types.error, // set in collect_* calls
1448            types,
1449            target_features: OnceCell::new(),
1450            data_layout: OnceCell::new(),
1451            lang_items: table.interner().lang_items(),
1452            features: resolver.top_level_def_map().features(),
1453            edition: resolver.krate().data(db).edition,
1454            table,
1455            tuple_field_accesses_rev: Default::default(),
1456            resume_yield_tys: None,
1457            return_coercion: None,
1458            db,
1459            owner,
1460            store_owner,
1461            generic_def,
1462            allow_using_generic_params,
1463            generics: OnceCell::new(),
1464            identity_args: OnceCell::new(),
1465            store,
1466            traits_in_scope: resolver.traits_in_scope(db),
1467            resolver,
1468            diverges: Diverges::Maybe,
1469            breakables: Vec::new(),
1470            deferred_cast_checks: Vec::new(),
1471            diagnostics: Diagnostics::default(),
1472            vars_emitted_type_must_be_known_for: FxHashSet::default(),
1473            deferred_call_resolutions: FxHashMap::default(),
1474            defined_anon_consts: RefCell::new(ThinVec::new()),
1475            lowering_mode,
1476        }
1477    }
1478
1479    fn merge(&mut self, other: &InferenceResult<'db>) {
1480        let InferenceResult {
1481            method_resolutions,
1482            field_resolutions,
1483            variant_resolutions,
1484            assoc_resolutions,
1485            tuple_field_access_types: _,
1486            type_of_expr,
1487            type_of_pat,
1488            type_of_binding,
1489            type_of_type_placeholder,
1490            type_of_opaque,
1491            has_errors: _,
1492            diagnostics: _,
1493            error_ty: _,
1494            expr_adjustments,
1495            pat_adjustments,
1496            binding_modes,
1497            skipped_ref_pats,
1498            coercion_casts,
1499            closures_data,
1500            nodes_with_type_mismatches,
1501            defined_anon_consts: _,
1502        } = &mut self.result;
1503        merge_hash_maps(method_resolutions, &other.method_resolutions);
1504        merge_hash_maps(variant_resolutions, &other.variant_resolutions);
1505        merge_hash_maps(assoc_resolutions, &other.assoc_resolutions);
1506        field_resolutions.extend(other.field_resolutions.iter().map(
1507            |(&field_expr, &field_resolution)| {
1508                let mut field_resolution = field_resolution;
1509                if let Either::Right(tuple_field) = &mut field_resolution {
1510                    let tys = other.tuple_field_access_type(tuple_field.tuple);
1511                    tuple_field.tuple =
1512                        TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);
1513                };
1514                (field_expr, field_resolution)
1515            },
1516        ));
1517        merge_arena_maps(type_of_expr, &other.type_of_expr);
1518        merge_arena_maps(type_of_pat, &other.type_of_pat);
1519        merge_arena_maps(type_of_binding, &other.type_of_binding);
1520        merge_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);
1521        merge_hash_maps(type_of_opaque, &other.type_of_opaque);
1522        merge_hash_maps(expr_adjustments, &other.expr_adjustments);
1523        merge_hash_maps(pat_adjustments, &other.pat_adjustments);
1524        merge_arena_maps(binding_modes, &other.binding_modes);
1525        merge_hash_set(skipped_ref_pats, &other.skipped_ref_pats);
1526        merge_hash_set(coercion_casts, &other.coercion_casts);
1527        merge_hash_maps(closures_data, &other.closures_data);
1528        if let Some(other_nodes_with_type_mismatches) = &other.nodes_with_type_mismatches {
1529            merge_hash_set(
1530                nodes_with_type_mismatches.get_or_insert_default(),
1531                other_nodes_with_type_mismatches,
1532            );
1533        }
1534        self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());
1535        self.diagnostics.extend(&other.diagnostics);
1536
1537        fn merge_hash_set<T: Hash + Eq + Clone>(dest: &mut FxHashSet<T>, source: &FxHashSet<T>) {
1538            dest.extend(source.iter().cloned());
1539        }
1540
1541        #[cfg_attr(debug_assertions, track_caller)]
1542        fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(
1543            dest: &mut FxHashMap<K, V>,
1544            source: &FxHashMap<K, V>,
1545        ) {
1546            if cfg!(debug_assertions) {
1547                for (key, src) in source {
1548                    assert!(dest.get(key).is_none_or(|dst| dst == src));
1549                }
1550            }
1551
1552            dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));
1553        }
1554
1555        #[cfg_attr(debug_assertions, track_caller)]
1556        fn merge_arena_maps<K, V: Clone + PartialEq>(
1557            dest: &mut ArenaMap<la_arena::Idx<K>, V>,
1558            source: &ArenaMap<la_arena::Idx<K>, V>,
1559        ) {
1560            if cfg!(debug_assertions) {
1561                for (key, src) in source.iter() {
1562                    assert!(dest.get(key).is_none_or(|dst| dst == src));
1563                }
1564            }
1565
1566            dest.extend(source.iter().map(|(k, v)| (k, v.clone())));
1567        }
1568    }
1569
1570    #[inline]
1571    fn krate(&self) -> Crate {
1572        self.resolver.krate()
1573    }
1574
1575    fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {
1576        let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {
1577            let target_features = match self.store_owner {
1578                ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {
1579                    TargetFeatures::from_fn(self.db, id)
1580                }
1581                _ => TargetFeatures::default(),
1582            };
1583            let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {
1584                Ok(target) => crate::utils::target_feature_is_safe_in_target(target),
1585                Err(_) => TargetFeatureIsSafeInTarget::No,
1586            };
1587            (target_features, target_feature_is_safe)
1588        });
1589        (target_features, *target_feature_is_safe)
1590    }
1591
1592    fn data_layout(&self) -> &'db TargetDataLayout {
1593        self.data_layout.get_or_init(|| self.db.target_data_layout_or_default(self.krate()))
1594    }
1595
1596    /// How should a deref pattern find the place for its inner pattern to match on?
1597    ///
1598    /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner
1599    /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.
1600    /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;
1601    /// in this case, we return `DerefPatBorrowMode::Box`.
1602    fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {
1603        if pointer_ty.is_box() {
1604            DerefPatBorrowMode::Box
1605        } else {
1606            let mutability =
1607                if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
1608            DerefPatBorrowMode::Borrow(mutability)
1609        }
1610    }
1611
1612    #[inline]
1613    fn set_tainted_by_errors(&mut self) {
1614        self.result.has_errors = true;
1615    }
1616
1617    /// Copy the inference of defined anon consts to ourselves, so that we don't need to lookup the defining
1618    /// anon const when looking the type of something.
1619    fn merge_anon_consts(&mut self) {
1620        let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());
1621        defined_anon_consts.retain(|&konst| {
1622            if konst.loc(self.db).owner != self.store_owner {
1623                // This comes from the signature, we don't define it.
1624                return false;
1625            }
1626
1627            let const_infer = InferenceResult::of(self.db, konst);
1628            self.merge(const_infer);
1629            true
1630        });
1631        // Caution, other defined anon consts might have been added by `merge()`!
1632        self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);
1633    }
1634
1635    fn resolve_all(self) -> InferenceResult<'db> {
1636        let InferenceContext {
1637            table,
1638            mut result,
1639            tuple_field_accesses_rev,
1640            diagnostics,
1641            types,
1642            vars_emitted_type_must_be_known_for,
1643            ..
1644        } = self;
1645        let diagnostics = diagnostics.finish();
1646        // Destructure every single field so whenever new fields are added to `InferenceResult` we
1647        // don't forget to handle them here.
1648        let InferenceResult {
1649            method_resolutions,
1650            field_resolutions: _,
1651            variant_resolutions: _,
1652            assoc_resolutions,
1653            type_of_expr,
1654            type_of_pat,
1655            type_of_binding,
1656            type_of_type_placeholder,
1657            type_of_opaque,
1658            skipped_ref_pats,
1659            closures_data,
1660            has_errors,
1661            error_ty: _,
1662            pat_adjustments,
1663            binding_modes: _,
1664            expr_adjustments,
1665            tuple_field_access_types,
1666            coercion_casts: _,
1667            diagnostics: result_diagnostics,
1668            nodes_with_type_mismatches,
1669            defined_anon_consts: result_defined_anon_consts,
1670        } = &mut result;
1671
1672        *result_defined_anon_consts = self.defined_anon_consts.into_inner();
1673        result_defined_anon_consts.shrink_to_fit();
1674
1675        let mut resolver =
1676            WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);
1677
1678        skipped_ref_pats.shrink_to_fit();
1679        for ty in type_of_expr.values_mut() {
1680            resolver.resolve_completely(ty);
1681        }
1682        type_of_expr.shrink_to_fit();
1683        for ty in type_of_pat.values_mut() {
1684            resolver.resolve_completely(ty);
1685        }
1686        type_of_pat.shrink_to_fit();
1687        for ty in type_of_binding.values_mut() {
1688            resolver.resolve_completely(ty);
1689        }
1690        type_of_binding.shrink_to_fit();
1691        for ty in type_of_type_placeholder.values_mut() {
1692            resolver.resolve_completely(ty);
1693        }
1694        type_of_type_placeholder.shrink_to_fit();
1695        type_of_opaque.shrink_to_fit();
1696
1697        if let Some(nodes_with_type_mismatches) = nodes_with_type_mismatches {
1698            *has_errors = true;
1699            nodes_with_type_mismatches.shrink_to_fit();
1700        }
1701        for (_, subst) in method_resolutions.values_mut() {
1702            resolver.resolve_completely(subst);
1703        }
1704        method_resolutions.shrink_to_fit();
1705        for (_, subst) in assoc_resolutions.values_mut() {
1706            resolver.resolve_completely(subst);
1707        }
1708        assoc_resolutions.shrink_to_fit();
1709        for adjustment in expr_adjustments.values_mut().flatten() {
1710            resolver.resolve_completely(&mut adjustment.target);
1711        }
1712        expr_adjustments.shrink_to_fit();
1713        for adjustments in pat_adjustments.values_mut() {
1714            for adjustment in &mut *adjustments {
1715                resolver.resolve_completely(&mut adjustment.source);
1716            }
1717            adjustments.shrink_to_fit();
1718        }
1719        pat_adjustments.shrink_to_fit();
1720        for closure_data in closures_data.values_mut() {
1721            let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data;
1722            let dummy_place = || Place {
1723                base_ty: types.types.error.store(),
1724                base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,
1725                projections: Vec::new(),
1726            };
1727
1728            for (place, _, sources) in fake_reads {
1729                resolver.resolve_completely_with_default(place, dummy_place());
1730                place.projections.shrink_to_fit();
1731                for source in &mut *sources {
1732                    source.shrink_to_fit();
1733                }
1734                sources.shrink_to_fit();
1735            }
1736
1737            for min_capture in min_captures.values_mut() {
1738                for captured in &mut *min_capture {
1739                    let CapturedPlace { place, info, mutability: _ } = captured;
1740                    resolver.resolve_completely_with_default(place, dummy_place());
1741                    let CaptureInfo { sources, capture_kind: _ } = info;
1742                    for source in &mut *sources {
1743                        source.shrink_to_fit();
1744                    }
1745                    sources.shrink_to_fit();
1746                }
1747                min_capture.shrink_to_fit();
1748            }
1749            min_captures.shrink_to_fit();
1750
1751            resolver.resolve_completely(liberated_sig);
1752        }
1753        closures_data.shrink_to_fit();
1754        *tuple_field_access_types = tuple_field_accesses_rev
1755            .into_iter()
1756            .map(|mut subst| {
1757                resolver.resolve_completely(&mut subst);
1758                subst.store()
1759            })
1760            .collect();
1761        tuple_field_access_types.shrink_to_fit();
1762
1763        let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();
1764        *result_diagnostics = diagnostics;
1765        *has_errors |= resolver_has_errors;
1766
1767        result
1768    }
1769
1770    fn collect_const_or_static(&mut self, id: ValueTyDefId) {
1771        let return_ty = self.db.value_ty(id).unwrap().instantiate_identity().skip_norm_wip();
1772        self.return_ty = self.process_remote_user_written_ty(return_ty);
1773    }
1774
1775    fn collect_fn(
1776        &mut self,
1777        func: FunctionId,
1778        self_param: Option<BindingId>,
1779        params: &[Param<PatId>],
1780    ) {
1781        let sig = self.interner().liberate_late_bound_regions(
1782            func.into(),
1783            self.db.callable_item_signature(func.into()).instantiate_identity().skip_norm_wip(),
1784        );
1785
1786        // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1787        // (as it's created inside the body itself, not passed in from outside).
1788        let maybe_va_list =
1789            if sig.fn_sig_kind.c_variadic() { self.resolve_va_list() } else { None };
1790        let maybe_va_list = maybe_va_list.map(|va_list| {
1791            let region = self.table.next_region_var(
1792                params.last().expect("variadic function must have parameters").user_written.into(),
1793            );
1794            Ty::new_adt(self.interner(), va_list, GenericArgs::new_from_slice(&[region.into()]))
1795        });
1796
1797        let mut param_tys = sig.inputs().iter().copied();
1798
1799        if let Some(self_param) = self_param
1800            && let Some(ty) = param_tys.next()
1801        {
1802            let ty = self.process_remote_user_written_ty(ty);
1803            self.write_binding_ty(self_param, ty);
1804        }
1805
1806        let mut param_tys = param_tys.chain(maybe_va_list);
1807        for pat in params {
1808            let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));
1809            let ty = self.process_remote_user_written_ty(ty);
1810
1811            self.infer_top_pat(pat.formal, ty, PatOrigin::Param);
1812        }
1813
1814        self.return_ty = self.process_remote_user_written_ty(sig.output());
1815        self.return_coercion = Some(CoerceMany::new(self.return_ty));
1816    }
1817
1818    #[inline]
1819    pub(crate) fn interner(&self) -> DbInterner<'db> {
1820        self.table.interner()
1821    }
1822
1823    #[inline]
1824    pub(crate) fn infcx(&self) -> &InferCtxt<'db> {
1825        &self.table.infer_ctxt
1826    }
1827
1828    /// If `ty` is an error, returns an infer var instead. Otherwise, returns it.
1829    ///
1830    /// "Refreshing" types like this is useful for getting better types, but it is also
1831    /// very dangerous: we might create duplicate diagnostics, for example if we try
1832    /// to resolve it and fail. rustc doesn't do that for this reason (and is in general
1833    /// more strict with how it uses error types; an error type in inputs will almost
1834    /// always cause it to infer an error type in output, while we infer some type as much
1835    /// as we can).
1836    ///
1837    /// Unfortunately, we cannot allow ourselves to do that. Not only we more often work
1838    /// with incomplete code, we also have assists, for example "Generate constant", that
1839    /// will assume the inferred type is the expected type even if the expression itself
1840    /// cannot be inferred. Therefore, we choose a middle ground: refresh the type,
1841    /// but if we return a new var, mark it so that no diagnostics will be issued on it.
1842    fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
1843        if ty.is_ty_error() {
1844            let var = self.table.next_ty_var(Span::Dummy);
1845
1846            // Suppress future errors on this var. Add more things here when we add more diagnostics.
1847            self.vars_emitted_type_must_be_known_for.insert(var.into());
1848
1849            var
1850        } else {
1851            ty
1852        }
1853    }
1854
1855    fn infer_body(&mut self, body_expr: ExprId) {
1856        match self.return_coercion {
1857            Some(_) => self.infer_return(body_expr),
1858            None => {
1859                _ = self.infer_expr_coerce(
1860                    body_expr,
1861                    &Expectation::has_type(self.return_ty),
1862                    ExprIsRead::Yes,
1863                )
1864            }
1865        }
1866    }
1867
1868    fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {
1869        self.result.type_of_expr.insert(expr, ty.store());
1870    }
1871
1872    pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1873        if adjustments.is_empty() {
1874            return;
1875        }
1876        match self.result.expr_adjustments.entry(expr) {
1877            std::collections::hash_map::Entry::Occupied(mut entry) => {
1878                match (&mut entry.get_mut()[..], &adjustments[..]) {
1879                    (
1880                        [Adjustment { kind: Adjust::NeverToAny, target }],
1881                        [.., Adjustment { target: new_target, .. }],
1882                    ) => {
1883                        // NeverToAny coercion can target any type, so instead of adding a new
1884                        // adjustment on top we can change the target.
1885                        *target = new_target.clone();
1886                    }
1887                    _ => {
1888                        *entry.get_mut() = adjustments;
1889                    }
1890                }
1891            }
1892            std::collections::hash_map::Entry::Vacant(entry) => {
1893                entry.insert(adjustments);
1894            }
1895        }
1896    }
1897
1898    pub(crate) fn write_method_resolution(
1899        &mut self,
1900        expr: ExprId,
1901        func: FunctionId,
1902        subst: GenericArgs<'db>,
1903    ) {
1904        self.result.method_resolutions.insert(expr, (func, subst.store()));
1905    }
1906
1907    fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) {
1908        self.result.variant_resolutions.insert(id, variant);
1909    }
1910
1911    fn write_assoc_resolution(
1912        &mut self,
1913        id: ExprOrPatIdPacked,
1914        item: CandidateId,
1915        subs: GenericArgs<'db>,
1916    ) {
1917        self.result.assoc_resolutions.insert(id, (item, subs.store()));
1918    }
1919
1920    fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {
1921        self.result.type_of_pat.insert(pat, ty.store());
1922    }
1923
1924    fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {
1925        self.result.type_of_binding.insert(id, ty.store());
1926    }
1927
1928    pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1929        self.diagnostics.push(diagnostic);
1930    }
1931
1932    fn record_deferred_call_resolution(
1933        &mut self,
1934        closure_def_id: ExprId,
1935        r: DeferredCallResolution<'db>,
1936    ) {
1937        self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
1938    }
1939
1940    fn remove_deferred_call_resolutions(
1941        &mut self,
1942        closure_def_id: ExprId,
1943    ) -> Vec<DeferredCallResolution<'db>> {
1944        self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
1945    }
1946
1947    fn with_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R) -> R {
1948        let mut infer_vars = InferenceTyLoweringVarsCtx {
1949            table: &mut self.table,
1950            type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
1951        };
1952        let mut ctx = TyLoweringContext::new(
1953            self.db,
1954            &self.resolver,
1955            self.store,
1956            &self.diagnostics,
1957            self.store_owner,
1958            self.generic_def,
1959            &self.generics,
1960            LifetimeElisionKind::Infer,
1961            self.allow_using_generic_params,
1962            &mut infer_vars,
1963            &self.defined_anon_consts,
1964            LifetimeLoweringMode::LateParam,
1965        );
1966        f(&mut ctx)
1967    }
1968
1969    pub(crate) fn make_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
1970        let ty = self.with_ty_lowering(|ctx| ctx.lower_ty(type_ref));
1971        self.process_user_written_ty(ty)
1972    }
1973
1974    fn generics(&self) -> &Generics<'db> {
1975        self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
1976    }
1977
1978    fn identity_args(&self) -> GenericArgs<'db> {
1979        *self.identity_args.get_or_init(|| {
1980            GenericArgs::identity_for_item(self.interner(), self.generic_def.into())
1981        })
1982    }
1983
1984    pub(crate) fn create_anon_const(&mut self, expr: ExprId, expected_ty: Ty<'db>) -> Const<'db> {
1985        never!(expected_ty.has_infer(), "cannot have infer vars in an anon const's ty");
1986        let konst = create_anon_const(
1987            self.interner(),
1988            self.store_owner,
1989            self.store,
1990            expr,
1991            &self.resolver,
1992            expected_ty,
1993            &|| self.generics(),
1994            Some(&mut |span| self.table.next_const_var(span)),
1995            self.lowering_mode,
1996            (!self.allow_using_generic_params).then_some(0),
1997            // The situation around body anon consts using generic params is complicated.
1998            // rustc disallows them all, except for array repeat expressions. However in another place even repeat exprs
1999            // are disallowed, so in practice they cause an error.
2000            false,
2001        );
2002
2003        if let Ok(konst) = konst
2004            && let ConstKind::Unevaluated(konst) = konst.kind()
2005            && let GeneralConstId::AnonConstId(konst) = konst.def.0
2006        {
2007            self.defined_anon_consts.borrow_mut().push(konst);
2008        } else {
2009            self.write_expr_ty(expr, expected_ty);
2010        }
2011
2012        // FIXME: Report an error if needed.
2013        konst.unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2014    }
2015
2016    pub(crate) fn make_path_as_const(&mut self, path: &Path) -> Const<'db> {
2017        let forbid_params_after = if self.allow_using_generic_params { None } else { Some(0) };
2018        // FIXME: Report errors.
2019        path_to_const(self.db, &self.resolver, &|| self.generics(), forbid_params_after, path)
2020            .unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2021    }
2022
2023    fn err_ty(&self) -> Ty<'db> {
2024        self.types.types.error
2025    }
2026
2027    pub(crate) fn make_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
2028        let lt = self.with_ty_lowering(|ctx| ctx.lower_lifetime(lifetime_ref));
2029        self.insert_type_vars(lt)
2030    }
2031
2032    fn insert_type_vars<T>(&mut self, ty: T) -> T
2033    where
2034        T: TypeFoldable<DbInterner<'db>>,
2035    {
2036        self.table.insert_type_vars(ty)
2037    }
2038
2039    /// Attempts to returns the deeply last field of nested structures, but
2040    /// does not apply any normalization in its search. Returns the same type
2041    /// if input `ty` is not a structure at all.
2042    fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db> {
2043        self.struct_tail_with_normalize(ty, identity)
2044    }
2045
2046    /// Returns the deeply last field of nested structures, or the same type if
2047    /// not a structure at all. Corresponds to the only possible unsized field,
2048    /// and its type can be used to determine unsizing strategy.
2049    ///
2050    /// This is parameterized over the normalization strategy (i.e. how to
2051    /// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
2052    /// function to indicate no normalization should take place.
2053    fn struct_tail_with_normalize(
2054        &mut self,
2055        mut ty: Ty<'db>,
2056        mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
2057    ) -> Ty<'db> {
2058        // FIXME: fetch the limit properly
2059        let recursion_limit = 10;
2060        for iteration in 0.. {
2061            if iteration > recursion_limit {
2062                return self.err_ty();
2063            }
2064            match ty.kind() {
2065                TyKind::Adt(adt_def, substs) => match adt_def.def_id() {
2066                    AdtId::StructId(struct_id) => {
2067                        match self
2068                            .db
2069                            .field_types(struct_id.into())
2070                            .values()
2071                            .next_back()
2072                            .map(|it| it.ty())
2073                        {
2074                            Some(field) => {
2075                                ty = field.instantiate(self.interner(), substs).skip_norm_wip();
2076                            }
2077                            None => break,
2078                        }
2079                    }
2080                    _ => break,
2081                },
2082                TyKind::Tuple(substs) => match substs.as_slice().split_last() {
2083                    Some((last_ty, _)) => ty = *last_ty,
2084                    None => break,
2085                },
2086                TyKind::Alias(..) => {
2087                    let normalized = normalize(ty);
2088                    if ty == normalized {
2089                        return ty;
2090                    } else {
2091                        ty = normalized;
2092                    }
2093                }
2094                _ => break,
2095            }
2096        }
2097        ty
2098    }
2099
2100    /// Whenever you lower a user-written type, you should call this.
2101    fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2102        self.table.process_user_written_ty(ty)
2103    }
2104
2105    /// The difference of this method from `process_user_written_ty()` is that this method doesn't register a well-formed obligation,
2106    /// while `process_user_written_ty()` should (but doesn't currently).
2107    fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2108        self.table.process_remote_user_written_ty(ty)
2109    }
2110
2111    fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
2112        self.table.shallow_resolve(ty)
2113    }
2114
2115    pub(crate) fn resolve_vars_if_possible<T: TypeFoldable<DbInterner<'db>>>(&self, t: T) -> T {
2116        self.table.resolve_vars_if_possible(t)
2117    }
2118
2119    pub(crate) fn structurally_resolve_type(
2120        &mut self,
2121        node: ExprOrPatIdPacked,
2122        ty: Ty<'db>,
2123    ) -> Ty<'db> {
2124        let result = self.table.try_structurally_resolve_type(node.into(), ty);
2125        if result.is_ty_var() { self.type_must_be_known_at_this_point(node, ty) } else { result }
2126    }
2127
2128    pub(crate) fn innermost_tail_expr(&self, mut expr: ExprId) -> ExprId {
2129        while let Expr::Block { tail: Some(tail), label: None, .. } = self.store[expr] {
2130            expr = tail;
2131        }
2132        expr
2133    }
2134
2135    pub(crate) fn emit_type_mismatch(
2136        &mut self,
2137        node: ExprOrPatIdPacked,
2138        expected: Ty<'db>,
2139        found: Ty<'db>,
2140    ) {
2141        if self.result.nodes_with_type_mismatches.get_or_insert_default().insert(node) {
2142            self.diagnostics.push(InferenceDiagnostic::TypeMismatch {
2143                node,
2144                expected: expected.store(),
2145                found: found.store(),
2146            });
2147        }
2148    }
2149
2150    fn demand_eqtype(
2151        &mut self,
2152        id: ExprOrPatIdPacked,
2153        expected: Ty<'db>,
2154        actual: Ty<'db>,
2155    ) -> Result<(), ()> {
2156        let result = self
2157            .table
2158            .at(&ObligationCause::new(id))
2159            .eq(expected, actual)
2160            .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2161        if result.is_err() {
2162            self.emit_type_mismatch(id, expected, actual);
2163        }
2164        result.map_err(drop)
2165    }
2166
2167    fn demand_eqtype_fixme_no_diag(
2168        &mut self,
2169        expected: Ty<'db>,
2170        actual: Ty<'db>,
2171    ) -> Result<(), ()> {
2172        let result = self
2173            .table
2174            .at(&ObligationCause::dummy())
2175            .eq(expected, actual)
2176            .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2177        result.map_err(drop)
2178    }
2179
2180    fn demand_suptype(
2181        &mut self,
2182        id: ExprOrPatIdPacked,
2183        expected: Ty<'db>,
2184        actual: Ty<'db>,
2185    ) -> Result<(), ()> {
2186        let result = self
2187            .table
2188            .at(&ObligationCause::new(id))
2189            .sup(expected, actual)
2190            .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2191        if result.is_err() {
2192            self.emit_type_mismatch(id, expected, actual);
2193        }
2194        result.map_err(drop)
2195    }
2196
2197    fn demand_coerce(
2198        &mut self,
2199        expr: ExprId,
2200        checked_ty: Ty<'db>,
2201        expected: Ty<'db>,
2202        allow_two_phase: AllowTwoPhase,
2203        expr_is_read: ExprIsRead,
2204    ) -> Ty<'db> {
2205        let result = self.coerce(expr, checked_ty, expected, allow_two_phase, expr_is_read);
2206        if let Err(_err) = result {
2207            // FIXME: Emit diagnostic.
2208        }
2209        result.unwrap_or(self.types.types.error)
2210    }
2211
2212    pub(crate) fn type_must_be_known_at_this_point(
2213        &mut self,
2214        node: ExprOrPatIdPacked,
2215        ty: Ty<'db>,
2216    ) -> Ty<'db> {
2217        if self.vars_emitted_type_must_be_known_for.insert(ty.into()) {
2218            self.push_diagnostic(InferenceDiagnostic::TypeMustBeKnown {
2219                at_point: node.into(),
2220                top_term: None,
2221            });
2222        }
2223        self.types.types.error
2224    }
2225
2226    pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>, span: Span) {
2227        if !ty.references_non_lt_error()
2228            && let Some(sized_trait) = self.lang_items.Sized
2229        {
2230            self.table.register_bound(ty, sized_trait, ObligationCause::new(span));
2231        }
2232    }
2233
2234    fn expr_ty(&self, expr: ExprId) -> Ty<'db> {
2235        self.result.expr_ty(expr)
2236    }
2237
2238    fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
2239        let mut ty = None;
2240        if let Some(it) = self.result.expr_adjustments.get(&e)
2241            && let Some(it) = it.last()
2242        {
2243            ty = Some(it.target.as_ref());
2244        }
2245        ty.unwrap_or_else(|| self.expr_ty(e))
2246    }
2247
2248    fn resolve_variant(
2249        &mut self,
2250        node: ExprOrPatIdPacked,
2251        path: &Path,
2252        value_ns: bool,
2253    ) -> (Ty<'db>, Option<VariantId>) {
2254        let interner = self.interner();
2255        let mut vars_ctx = InferenceTyLoweringVarsCtx {
2256            table: &mut self.table,
2257            type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
2258        };
2259        let mut ctx = TyLoweringContext::new(
2260            self.db,
2261            &self.resolver,
2262            self.store,
2263            &self.diagnostics,
2264            self.store_owner,
2265            self.generic_def,
2266            &self.generics,
2267            LifetimeElisionKind::Infer,
2268            self.allow_using_generic_params,
2269            &mut vars_ctx,
2270            &self.defined_anon_consts,
2271            LifetimeLoweringMode::LateParam,
2272        );
2273
2274        if let Some(type_anchor) = path.type_anchor() {
2275            let mut segments = path.segments();
2276            if segments.is_empty() {
2277                return (self.types.types.error, None);
2278            }
2279            let (mut ty, type_ns) = ctx.lower_ty_ext(type_anchor);
2280            ty = ctx.expect_table().process_user_written_ty(ty);
2281
2282            if let Some(TypeNs::SelfType(impl_)) = type_ns
2283                && let Some(trait_ref) = self.db.impl_trait(impl_)
2284                && let trait_ref = trait_ref.instantiate_identity().skip_norm_wip()
2285                && let Some(assoc_type) = trait_ref
2286                    .def_id
2287                    .0
2288                    .trait_items(self.db)
2289                    .associated_type_by_name(segments.first().unwrap().name)
2290            {
2291                // `<Self>::AssocType`
2292                let args = ctx.expect_table().infer_ctxt.fill_rest_fresh_args(
2293                    node.into(),
2294                    assoc_type.into(),
2295                    trait_ref.args,
2296                );
2297                let alias = Ty::new_alias(
2298                    interner,
2299                    AliasTy::new_from_args(
2300                        interner,
2301                        AliasTyKind::Projection { def_id: assoc_type.into() },
2302                        args,
2303                    ),
2304                );
2305                ty = ctx.expect_table().try_structurally_resolve_type(node.into(), alias);
2306                segments = segments.skip(1);
2307            }
2308
2309            let variant = match ty.as_adt() {
2310                Some((AdtId::StructId(id), _)) => id.into(),
2311                Some((AdtId::UnionId(id), _)) => id.into(),
2312                Some((AdtId::EnumId(id), _)) => {
2313                    if let Some(segment) = segments.first()
2314                        && let enum_data = id.enum_variants(self.db)
2315                        && let Some(variant) = enum_data.variant(segment.name)
2316                    {
2317                        // FIXME: Report error if there are generics on the variant.
2318                        segments = segments.skip(1);
2319                        variant.into()
2320                    } else {
2321                        return (self.types.types.error, None);
2322                    }
2323                }
2324                None => return (self.types.types.error, None),
2325            };
2326
2327            if !segments.is_empty() {
2328                // FIXME: Report an error.
2329                return (self.types.types.error, None);
2330            } else {
2331                return (ty, Some(variant));
2332            }
2333        }
2334
2335        let mut path_ctx = ctx.at_path(path, node);
2336        let interner = DbInterner::conjure();
2337        let (resolution, unresolved) = if value_ns {
2338            let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
2339                return (self.types.types.error, None);
2340            };
2341            match res {
2342                ResolveValueResult::ValueNs(value) => match value {
2343                    ValueNs::EnumVariantId(var) => {
2344                        let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2345                        drop(ctx);
2346                        let ty = self
2347                            .db
2348                            .ty(var.lookup(self.db).parent.into())
2349                            .instantiate(interner, args)
2350                            .skip_norm_wip();
2351                        let ty = self.insert_type_vars(ty);
2352                        return (ty, Some(var.into()));
2353                    }
2354                    ValueNs::StructId(strukt) => {
2355                        let args =
2356                            path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2357                        drop(ctx);
2358                        let ty =
2359                            self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2360                        let ty = self.insert_type_vars(ty);
2361                        return (ty, Some(strukt.into()));
2362                    }
2363                    ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
2364                    _ => {
2365                        drop(ctx);
2366                        return (self.types.types.error, None);
2367                    }
2368                },
2369                ResolveValueResult::Partial(typens, unresolved) => (typens, Some(unresolved)),
2370            }
2371        } else {
2372            match path_ctx.resolve_path_in_type_ns() {
2373                Some((it, idx)) => (it, idx),
2374                None => return (self.types.types.error, None),
2375            }
2376        };
2377        return match resolution {
2378            TypeNs::AdtId(AdtId::StructId(strukt)) => {
2379                let args = path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2380                drop(ctx);
2381                let ty = self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2382                let ty = self.insert_type_vars(ty);
2383                forbid_unresolved_segments(self, (ty, Some(strukt.into())), unresolved)
2384            }
2385            TypeNs::AdtId(AdtId::UnionId(u)) => {
2386                let args = path_ctx.substs_from_path(u.into(), true, false, node.into());
2387                drop(ctx);
2388                let ty = self.db.ty(u.into()).instantiate(interner, args).skip_norm_wip();
2389                let ty = self.insert_type_vars(ty);
2390                forbid_unresolved_segments(self, (ty, Some(u.into())), unresolved)
2391            }
2392            TypeNs::EnumVariantId(var) => {
2393                let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2394                drop(ctx);
2395                let ty = self
2396                    .db
2397                    .ty(var.lookup(self.db).parent.into())
2398                    .instantiate(interner, args)
2399                    .skip_norm_wip();
2400                let ty = self.insert_type_vars(ty);
2401                forbid_unresolved_segments(self, (ty, Some(var.into())), unresolved)
2402            }
2403            TypeNs::SelfType(impl_id) => {
2404                let mut ty = self.db.impl_self_ty(impl_id).instantiate_identity().skip_norm_wip();
2405
2406                let Some(remaining_idx) = unresolved else {
2407                    drop(ctx);
2408                    let Some(mod_path) = path.mod_path() else {
2409                        never!("resolver should always resolve lang item paths");
2410                        return (self.types.types.error, None);
2411                    };
2412                    return self.resolve_variant_on_alias(node, ty, None, mod_path);
2413                };
2414
2415                let mut remaining_segments = path.segments().skip(remaining_idx);
2416
2417                if remaining_segments.len() >= 2 {
2418                    path_ctx.ignore_last_segment();
2419                }
2420
2421                // We need to try resolving unresolved segments one by one because each may resolve
2422                // to a projection, which `TyLoweringContext` cannot handle on its own.
2423                let mut tried_resolving_once = false;
2424                while let Some(current_segment) = remaining_segments.first() {
2425                    // If we can resolve to an enum variant, it takes priority over associated type
2426                    // of the same name.
2427                    if let TyKind::Adt(adt_def, _) = ty.kind()
2428                        && let AdtId::EnumId(id) = adt_def.def_id()
2429                    {
2430                        let enum_data = id.enum_variants(self.db);
2431                        if let Some(variant) = enum_data.variant(current_segment.name) {
2432                            return if remaining_segments.len() == 1 {
2433                                (ty, Some(variant.into()))
2434                            } else {
2435                                // We still have unresolved paths, but enum variants never have
2436                                // associated types!
2437                                // FIXME: Report an error.
2438                                (self.types.types.error, None)
2439                            };
2440                        }
2441                    }
2442
2443                    if tried_resolving_once {
2444                        // FIXME: with `inherent_associated_types` this is allowed, but our `lower_partly_resolved_path()`
2445                        // will need to be updated to err at the correct segment.
2446                        break;
2447                    }
2448
2449                    // `lower_partly_resolved_path()` returns `None` as type namespace unless
2450                    // `remaining_segments` is empty, which is never the case here. We don't know
2451                    // which namespace the new `ty` is in until normalized anyway.
2452                    (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2453                    tried_resolving_once = true;
2454
2455                    ty = path_ctx.expect_table().process_user_written_ty(ty);
2456                    if ty.is_ty_error() {
2457                        return (self.types.types.error, None);
2458                    }
2459
2460                    remaining_segments = remaining_segments.skip(1);
2461                }
2462                drop(ctx);
2463
2464                let variant = ty.as_adt().and_then(|(id, _)| match id {
2465                    AdtId::StructId(s) => Some(VariantId::StructId(s)),
2466                    AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2467                    AdtId::EnumId(_) => {
2468                        // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
2469                        None
2470                    }
2471                });
2472                (ty, variant)
2473            }
2474            TypeNs::TraitId(_) => {
2475                let Some(remaining_idx) = unresolved else {
2476                    return (self.types.types.error, None);
2477                };
2478
2479                let remaining_segments = path.segments().skip(remaining_idx);
2480
2481                if remaining_segments.len() >= 2 {
2482                    path_ctx.ignore_last_segment();
2483                }
2484
2485                let (mut ty, _) =
2486                    path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2487                ty = ctx.expect_table().process_user_written_ty(ty);
2488
2489                if let Some(segment) = remaining_segments.get(1)
2490                    && let Some((AdtId::EnumId(id), _)) = ty.as_adt()
2491                {
2492                    let enum_data = id.enum_variants(self.db);
2493                    if let Some(variant) = enum_data.variant(segment.name) {
2494                        return if remaining_segments.len() == 2 {
2495                            (ty, Some(variant.into()))
2496                        } else {
2497                            // We still have unresolved paths, but enum variants never have
2498                            // associated types!
2499                            // FIXME: Report an error.
2500                            (self.types.types.error, None)
2501                        };
2502                    }
2503                }
2504
2505                let variant = ty.as_adt().and_then(|(id, _)| match id {
2506                    AdtId::StructId(s) => Some(VariantId::StructId(s)),
2507                    AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2508                    AdtId::EnumId(_) => {
2509                        // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
2510                        None
2511                    }
2512                });
2513                (ty, variant)
2514            }
2515            TypeNs::TypeAliasId(it) => {
2516                let Some(mod_path) = path.mod_path() else {
2517                    never!("resolver should always resolve lang item paths");
2518                    return (self.types.types.error, None);
2519                };
2520                let args =
2521                    path_ctx.substs_from_path_segment(it.into(), true, None, false, node.into());
2522                let interner = path_ctx.interner();
2523                drop(ctx);
2524                let ty = self.db.ty(it.into()).instantiate(interner, args).skip_norm_wip();
2525                let ty = self.insert_type_vars(ty);
2526
2527                self.resolve_variant_on_alias(node, ty, unresolved, mod_path)
2528            }
2529            TypeNs::AdtSelfType(_) => {
2530                // FIXME this could happen in array size expressions, once we're checking them
2531                (self.types.types.error, None)
2532            }
2533            TypeNs::GenericParam(_) => {
2534                // FIXME potentially resolve assoc type
2535                (self.types.types.error, None)
2536            }
2537            TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::ModuleId(_) => {
2538                // FIXME diagnostic
2539                (self.types.types.error, None)
2540            }
2541        };
2542
2543        fn forbid_unresolved_segments<'db>(
2544            ctx: &InferenceContext<'db>,
2545            result: (Ty<'db>, Option<VariantId>),
2546            unresolved: Option<usize>,
2547        ) -> (Ty<'db>, Option<VariantId>) {
2548            if unresolved.is_none() {
2549                result
2550            } else {
2551                // FIXME diagnostic
2552                (ctx.types.types.error, None)
2553            }
2554        }
2555    }
2556
2557    fn resolve_variant_on_alias(
2558        &mut self,
2559        node: ExprOrPatIdPacked,
2560        ty: Ty<'db>,
2561        unresolved: Option<usize>,
2562        path: &ModPath,
2563    ) -> (Ty<'db>, Option<VariantId>) {
2564        let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
2565        let ty = self.table.try_structurally_resolve_type(node.into(), ty);
2566        match remaining {
2567            None => {
2568                let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
2569                    AdtId::StructId(s) => Some(VariantId::StructId(s)),
2570                    AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2571                    AdtId::EnumId(_) => {
2572                        // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
2573                        None
2574                    }
2575                });
2576                (ty, variant)
2577            }
2578            Some(1) => {
2579                let segment = path.segments().last().unwrap();
2580                // this could be an enum variant or associated type
2581                if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
2582                    let enum_data = enum_id.enum_variants(self.db);
2583                    if let Some(variant) = enum_data.variant(segment) {
2584                        return (ty, Some(variant.into()));
2585                    }
2586                }
2587                // FIXME potentially resolve assoc type
2588                (self.err_ty(), None)
2589            }
2590            Some(_) => {
2591                // FIXME diagnostic
2592                (self.err_ty(), None)
2593            }
2594        }
2595    }
2596
2597    fn resolve_va_list(&self) -> Option<AdtId> {
2598        let struct_ = self.lang_items.VaList?;
2599        Some(struct_.into())
2600    }
2601
2602    pub(crate) fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
2603        let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
2604        if b_traits.peek().is_some() {
2605            Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
2606        } else {
2607            Either::Right(&self.traits_in_scope)
2608        }
2609    }
2610
2611    fn has_applicable_non_exhaustive(&self, def: AttrDefId) -> bool {
2612        AttrFlags::query(self.db, def).contains(AttrFlags::NON_EXHAUSTIVE)
2613            && def.krate(self.db) != self.krate()
2614    }
2615}
2616
2617/// When inferring an expression, we propagate downward whatever type hint we
2618/// are able in the form of an `Expectation`.
2619#[derive(Clone, PartialEq, Eq, Debug)]
2620pub(crate) enum Expectation<'db> {
2621    None,
2622    HasType(Ty<'db>),
2623    Castable(Ty<'db>),
2624    RValueLikeUnsized(Ty<'db>),
2625}
2626
2627impl<'db> Expectation<'db> {
2628    /// The expectation that the type of the expression needs to equal the given
2629    /// type.
2630    fn has_type(ty: Ty<'db>) -> Self {
2631        if ty.is_ty_error() {
2632            // FIXME: get rid of this?
2633            Expectation::None
2634        } else {
2635            Expectation::HasType(ty)
2636        }
2637    }
2638
2639    /// The following explanation is copied straight from rustc:
2640    /// Provides an expectation for an rvalue expression given an *optional*
2641    /// hint, which is not required for type safety (the resulting type might
2642    /// be checked higher up, as is the case with `&expr` and `box expr`), but
2643    /// is useful in determining the concrete type.
2644    ///
2645    /// The primary use case is where the expected type is a fat pointer,
2646    /// like `&[isize]`. For example, consider the following statement:
2647    ///
2648    ///     let it: &[isize] = &[1, 2, 3];
2649    ///
2650    /// In this case, the expected type for the `&[1, 2, 3]` expression is
2651    /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
2652    /// expectation `ExpectHasType([isize])`, that would be too strong --
2653    /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
2654    /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
2655    /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
2656    /// which still is useful, because it informs integer literals and the like.
2657    /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
2658    /// for examples of where this comes up,.
2659    fn rvalue_hint(ctx: &mut InferenceContext<'db>, ty: Ty<'db>) -> Self {
2660        match ctx.struct_tail_without_normalization(ty).kind() {
2661            TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(..) => {
2662                Expectation::RValueLikeUnsized(ty)
2663            }
2664            _ => Expectation::has_type(ty),
2665        }
2666    }
2667
2668    /// This expresses no expectation on the type.
2669    fn none() -> Self {
2670        Expectation::None
2671    }
2672
2673    fn resolve(&self, table: &unify::InferenceTable<'db>) -> Expectation<'db> {
2674        match self {
2675            Expectation::None => Expectation::None,
2676            Expectation::HasType(t) => Expectation::HasType(table.shallow_resolve(*t)),
2677            Expectation::Castable(t) => Expectation::Castable(table.shallow_resolve(*t)),
2678            Expectation::RValueLikeUnsized(t) => {
2679                Expectation::RValueLikeUnsized(table.shallow_resolve(*t))
2680            }
2681        }
2682    }
2683
2684    fn to_option(&self, table: &unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2685        match self.resolve(table) {
2686            Expectation::None => None,
2687            Expectation::HasType(t)
2688            | Expectation::Castable(t)
2689            | Expectation::RValueLikeUnsized(t) => Some(t),
2690        }
2691    }
2692
2693    fn only_has_type(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2694        match self {
2695            Expectation::HasType(t) => Some(table.resolve_vars_if_possible(*t)),
2696            Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2697                None
2698            }
2699        }
2700    }
2701
2702    fn coercion_target_type(&self, table: &mut unify::InferenceTable<'db>, span: Span) -> Ty<'db> {
2703        self.only_has_type(table).unwrap_or_else(|| table.next_ty_var(span))
2704    }
2705
2706    /// Comment copied from rustc:
2707    /// Disregard "castable to" expectations because they
2708    /// can lead us astray. Consider for example `if cond
2709    /// {22} else {c} as u8` -- if we propagate the
2710    /// "castable to u8" constraint to 22, it will pick the
2711    /// type 22u8, which is overly constrained (c might not
2712    /// be a u8). In effect, the problem is that the
2713    /// "castable to" expectation is not the tightest thing
2714    /// we can say, so we want to drop it in this case.
2715    /// The tightest thing we can say is "must unify with
2716    /// else branch". Note that in the case of a "has type"
2717    /// constraint, this limitation does not hold.
2718    ///
2719    /// If the expected type is just a type variable, then don't use
2720    /// an expected type. Otherwise, we might write parts of the type
2721    /// when checking the 'then' block which are incompatible with the
2722    /// 'else' branch.
2723    fn adjust_for_branches(
2724        &self,
2725        table: &mut unify::InferenceTable<'db>,
2726        span: Span,
2727    ) -> Expectation<'db> {
2728        match *self {
2729            Expectation::HasType(ety) => {
2730                let ety = table.try_structurally_resolve_type(span, ety);
2731                if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2732            }
2733            Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),
2734            _ => Expectation::None,
2735        }
2736    }
2737}
2738
2739#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2740enum Diverges {
2741    Maybe,
2742    Always,
2743}
2744
2745impl Diverges {
2746    fn is_always(self) -> bool {
2747        self == Diverges::Always
2748    }
2749}
2750
2751impl std::ops::BitAnd for Diverges {
2752    type Output = Self;
2753    fn bitand(self, other: Self) -> Self {
2754        std::cmp::min(self, other)
2755    }
2756}
2757
2758impl std::ops::BitOr for Diverges {
2759    type Output = Self;
2760    fn bitor(self, other: Self) -> Self {
2761        std::cmp::max(self, other)
2762    }
2763}
2764
2765impl std::ops::BitAndAssign for Diverges {
2766    fn bitand_assign(&mut self, other: Self) {
2767        *self = *self & other;
2768    }
2769}
2770
2771impl std::ops::BitOrAssign for Diverges {
2772    fn bitor_assign(&mut self, other: Self) {
2773        *self = *self | other;
2774    }
2775}