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