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