Skip to main content

hir_ty/
infer.rs

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