Skip to main content

hir_ty/
infer.rs

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