src/tools/rust-analyzer/crates/hir-ty/src/infer.rs RUST 2,805 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,805.
1//! Type inference, i.e. the process of walking through the code and determining2//! the type of each expression and pattern.3//!4//! For type inference, compare the implementations in rustc (the various5//! check_* methods in rustc_hir_analysis/check/mod.rs are a good entry point) and6//! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for7//! inference here is the `infer` function, which infers the types of all8//! 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, or13//! to certain types. To record this, we use the union-find implementation from14//! the `ena` crate, which is extracted from rustc.1516mod autoderef;17mod callee;18pub(crate) mod cast;19pub(crate) mod closure;20mod coerce;21pub(crate) mod diagnostics;22mod expr;23mod fallback;24mod mutability;25mod op;26mod opaques;27mod pat;28mod path;29mod place_op;30pub(crate) mod unify;3132use std::{33    cell::{OnceCell, RefCell},34    convert::identity,35    fmt,36    hash::Hash,37    ops::Deref,38};3940use base_db::{Crate, FxIndexMap};41use either::Either;42use hir_def::{43    AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId,44    FunctionId, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, StaticId, TraitId,45    TupleFieldId, TupleId, VariantId,46    attrs::AttrFlags,47    expr_store::{Body, ExpressionStore, HygieneId, path::Path},48    hir::{BindingId, ExprId, ExprOrPatId, LabelId, PatId},49    lang_item::LangItems,50    layout::Integer,51    resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},52    signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature},53    type_ref::{LifetimeRefId, TypeRefId},54    unstable_features::UnstableFeatures,55};56use hir_expand::{mod_path::ModPath, name::Name};57use indexmap::IndexSet;58use la_arena::ArenaMap;59use macros::{TypeFoldable, TypeVisitable};60use rustc_ast_ir::Mutability;61use rustc_hash::{FxHashMap, FxHashSet};62use rustc_type_ir::{63    AliasTyKind, TypeFoldable, TypeVisitableExt,64    inherent::{GenericArgs as _, IntoKind, Ty as _},65};66use smallvec::SmallVec;67use span::Edition;68use stdx::never;69use thin_vec::ThinVec;7071use crate::{72    ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,73    TargetFeatures,74    closure_analysis::PlaceBase,75    consteval::{create_anon_const, path_to_const},76    db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},77    generics::Generics,78    infer::{79        callee::DeferredCallResolution,80        closure::analysis::{81            BorrowKind,82            expr_use_visitor::{FakeReadCause, Place},83        },84        coerce::{CoerceMany, DynamicCoerceMany},85        diagnostics::{86            Diagnostics, InferenceTyLoweringContext as TyLoweringContext,87            InferenceTyLoweringVarsCtx,88        },89        expr::ExprIsRead,90        pat::PatOrigin,91        unify::resolve_completely::WriteBackCtxt,92    },93    lower::{94        ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, LoweringMode,95        diagnostics::TyLoweringDiagnostic,96    },97    method_resolution::CandidateId,98    next_solver::{99        AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region,100        StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,101        abi::Safety,102        infer::{InferCtxt, ObligationInspector, traits::ObligationCause},103    },104    solver_errors::SolverDiagnostic,105    utils::TargetFeatureIsSafeInTarget,106};107108// This lint has a false positive here. See the link below for details.109//110// https://github.com/rust-lang/rust/issues/57411111#[allow(unreachable_pub)]112pub use coerce::could_coerce;113#[allow(unreachable_pub)]114pub use unify::{could_unify, could_unify_deeply};115116use cast::{CastCheck, CastError};117118/// The entry point of type inference.119fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult {120    infer_query_with_inspect(db, def, None, LoweringMode::Analysis)121}122123pub fn infer_query_with_inspect<'db>(124    db: &'db dyn HirDatabase,125    def: DefWithBodyId,126    inspect: Option<ObligationInspector<'db>>,127    lowering_mode: LoweringMode,128) -> InferenceResult {129    let _p = tracing::info_span!("infer_query").entered();130    let resolver = def.resolver(db);131    let body = Body::of(db, def);132    let mut ctx = InferenceContext::new(133        db,134        InferBodyId::DefWithBodyId(def),135        ExpressionStoreOwnerId::Body(def),136        def.generic_def(db),137        &body.store,138        resolver,139        true,140        lowering_mode,141    );142143    if let Some(inspect) = inspect {144        ctx.table.infer_ctxt.attach_obligation_inspector(inspect);145    }146147    match def {148        DefWithBodyId::FunctionId(f) => ctx.collect_fn(f, body.self_param(), &body.params),149        DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)),150        DefWithBodyId::StaticId(s) => ctx.collect_static(s, StaticSignature::of(db, s)),151        DefWithBodyId::VariantId(v) => {152            ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {153                hir_def::layout::IntegerType::Pointer(signed) => match signed {154                    true => ctx.types.types.isize,155                    false => ctx.types.types.usize,156                },157                hir_def::layout::IntegerType::Fixed(size, signed) => match signed {158                    true => match size {159                        Integer::I8 => ctx.types.types.i8,160                        Integer::I16 => ctx.types.types.i16,161                        Integer::I32 => ctx.types.types.i32,162                        Integer::I64 => ctx.types.types.i64,163                        Integer::I128 => ctx.types.types.i128,164                    },165                    false => match size {166                        Integer::I8 => ctx.types.types.u8,167                        Integer::I16 => ctx.types.types.u16,168                        Integer::I32 => ctx.types.types.u32,169                        Integer::I64 => ctx.types.types.u64,170                        Integer::I128 => ctx.types.types.u128,171                    },172                },173            };174        }175    }176177    ctx.infer_body(body.root_expr());178179    ctx.infer_mut_body(body.root_expr());180181    infer_finalize(ctx)182}183184fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult {185    InferenceResult {186        has_errors: true,187        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))188    }189}190191/// Infer types for an anonymous const expression.192fn infer_anon_const_query(db: &dyn HirDatabase, def: AnonConstId) -> InferenceResult {193    let _p = tracing::info_span!("infer_anon_const_query").entered();194    let loc = def.loc(db);195    let store_owner = loc.owner;196    let store = ExpressionStore::of(db, store_owner);197198    let resolver = store_owner.resolver(db);199200    let mut ctx = InferenceContext::new(201        db,202        InferBodyId::AnonConstId(def),203        store_owner,204        loc.owner.generic_def(db),205        store,206        resolver,207        loc.allow_using_generic_params,208        LoweringMode::Analysis,209    );210211    ctx.infer_expr(212        loc.expr,213        &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),214        ExprIsRead::Yes,215    );216217    infer_finalize(ctx)218}219220fn infer_anon_const_cycle_result(221    db: &dyn HirDatabase,222    _: salsa::Id,223    _: AnonConstId,224) -> InferenceResult {225    InferenceResult {226        has_errors: true,227        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))228    }229}230231fn infer_finalize(mut ctx: InferenceContext<'_, '_>) -> InferenceResult {232    ctx.handle_opaque_type_uses();233234    ctx.type_inference_fallback();235236    // Comment from rustc:237    // Even though coercion casts provide type hints, we check casts after fallback for238    // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.239    let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);240    for mut cast in cast_checks.into_iter() {241        if let Err(diag) = cast.check(&mut ctx) {242            ctx.diagnostics.push(diag);243        }244    }245246    ctx.table.select_obligations_where_possible();247248    // Closure and coroutine analysis may run after fallback249    // because they don't constrain other type variables.250    ctx.closure_analyze();251    assert!(ctx.deferred_call_resolutions.is_empty());252253    ctx.table.select_obligations_where_possible();254255    ctx.handle_opaque_type_uses();256257    ctx.merge_anon_consts();258259    ctx.resolve_all()260}261262#[derive(Clone, Copy, Debug, Eq, PartialEq)]263pub enum ByRef {264    Yes(Mutability),265    No,266}267268/// The mode of a binding (`mut`, `ref mut`, etc).269/// Used for both the explicit binding annotations given in the HIR for a binding270/// and the final binding mode that we infer after type inference/match ergonomics.271/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),272/// `.1` is the mutability of the binding.273#[derive(Copy, Clone, Debug, Eq, PartialEq)]274pub struct BindingMode(pub ByRef, pub Mutability);275276#[derive(Debug, PartialEq, Eq, Clone, Copy)]277pub enum InferenceTyDiagnosticSource {278    /// Diagnostics that come from types in the body.279    Body,280    /// Diagnostics that come from types in fn parameters/return type, or static & const types.281    Signature,282}283284#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]285pub enum InferenceDiagnostic {286    NoSuchField {287        #[type_visitable(ignore)]288        field: ExprOrPatId,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: u128,299        #[type_visitable(ignore)]300        found: u128,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: ExprOrPatId,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: ExprOrPatId,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 to351        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: ExprOrPatId,358    },359    UnresolvedIdent {360        #[type_visitable(ignore)]361        id: ExprOrPatId,362    },363    // FIXME: This should be emitted in body lowering364    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    FunctionalRecordUpdateOnNonStruct {383        #[type_visitable(ignore)]384        base_expr: ExprId,385    },386    MismatchedArgCount {387        #[type_visitable(ignore)]388        call_expr: ExprId,389        #[type_visitable(ignore)]390        expected: usize,391        #[type_visitable(ignore)]392        found: usize,393    },394    MismatchedTupleStructPatArgCount {395        #[type_visitable(ignore)]396        pat: PatId,397        #[type_visitable(ignore)]398        expected: usize,399        #[type_visitable(ignore)]400        found: usize,401    },402    ExpectedFunction {403        #[type_visitable(ignore)]404        call_expr: ExprId,405        found: StoredTy,406    },407    CannotBeDereferenced {408        #[type_visitable(ignore)]409        expr: ExprId,410        found: StoredTy,411    },412    CannotImplicitlyDerefTraitObject {413        #[type_visitable(ignore)]414        pat: PatId,415        found: StoredTy,416    },417    CannotIndexInto {418        #[type_visitable(ignore)]419        expr: ExprId,420        found: StoredTy,421    },422    TypedHole {423        #[type_visitable(ignore)]424        expr: ExprId,425        expected: StoredTy,426    },427    CastToUnsized {428        #[type_visitable(ignore)]429        expr: ExprId,430        cast_ty: StoredTy,431    },432    InvalidCast {433        #[type_visitable(ignore)]434        expr: ExprId,435        #[type_visitable(ignore)]436        error: CastError,437        expr_ty: StoredTy,438        cast_ty: StoredTy,439    },440    TyDiagnostic {441        #[type_visitable(ignore)]442        source: InferenceTyDiagnosticSource,443        #[type_visitable(ignore)]444        diag: TyLoweringDiagnostic,445    },446    PathDiagnostic {447        #[type_visitable(ignore)]448        node: ExprOrPatId,449        #[type_visitable(ignore)]450        diag: PathLoweringDiagnostic,451    },452    MethodCallIncorrectGenericsLen {453        #[type_visitable(ignore)]454        expr: ExprId,455        #[type_visitable(ignore)]456        provided_count: u32,457        #[type_visitable(ignore)]458        expected_count: u32,459        #[type_visitable(ignore)]460        kind: IncorrectGenericsLenKind,461        #[type_visitable(ignore)]462        def: GenericDefId,463    },464    MethodCallIllegalSizedBound {465        #[type_visitable(ignore)]466        call_expr: ExprId,467    },468    MethodCallIncorrectGenericsOrder {469        #[type_visitable(ignore)]470        expr: ExprId,471        #[type_visitable(ignore)]472        param_id: GenericParamId,473        #[type_visitable(ignore)]474        arg_idx: u32,475        /// Whether the `GenericArgs` contains a `Self` arg.476        #[type_visitable(ignore)]477        has_self_arg: bool,478    },479    InvalidLhsOfAssignment {480        #[type_visitable(ignore)]481        lhs: ExprId,482    },483    TypeMustBeKnown {484        #[type_visitable(ignore)]485        at_point: Span,486        top_term: Option<StoredGenericArg>,487    },488    UnionExprMustHaveExactlyOneField {489        #[type_visitable(ignore)]490        expr: ExprId,491    },492    TypeMismatch {493        #[type_visitable(ignore)]494        node: ExprOrPatId,495        expected: StoredTy,496        found: StoredTy,497    },498    SolverDiagnostic(SolverDiagnostic),499    ExplicitDropMethodUse {500        #[type_visitable(ignore)]501        kind: ExplicitDropMethodUseKind,502    },503    MutableRefBinding {504        #[type_visitable(ignore)]505        pat: PatId,506    },507}508509#[derive(Debug, PartialEq, Eq, Clone)]510pub enum ExplicitDropMethodUseKind {511    MethodCall(ExprId),512    Path(ExprOrPatId),513}514515/// Represents coercing a value to a different type of value.516///517/// We transform values by following a number of `Adjust` steps in order.518/// See the documentation on variants of `Adjust` for more details.519///520/// Here are some common scenarios:521///522/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.523///    Here the pointer will be dereferenced N times (where a dereference can524///    happen to raw or borrowed pointers or any smart pointer which implements525///    Deref, including Box<_>). The types of dereferences is given by526///    `autoderefs`. It can then be auto-referenced zero or one times, indicated527///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is528///    `false`.529///530/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start531///    with a thin pointer, deref a number of times, unsize the underlying data,532///    then autoref. The 'unsize' phase may change a fixed length array to a533///    dynamically sized one, a concrete object to a trait object, or statically534///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is535///    represented by:536///537///    ```ignore538///    Deref(None) -> [i32; 4],539///    Borrow(AutoBorrow::Ref) -> &[i32; 4],540///    Unsize -> &[i32],541///    ```542///543///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.544///    E.g., `struct Foo<T> { it: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>545///    The autoderef and -ref are the same as in the above example, but the type546///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about547///    the underlying conversions from `[i32; 4]` to `[i32]`.548///549/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In550///    that case, we have the pointer we need coming in, so there are no551///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.552///    At some point, of course, `Box` should move out of the compiler, in which553///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->554///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.555#[derive(Clone, Debug, PartialEq, Eq, Hash)]556pub struct Adjustment {557    pub kind: Adjust,558    pub target: StoredTy,559}560561impl Adjustment {562    pub fn borrow<'db>(563        interner: DbInterner<'db>,564        m: Mutability,565        ty: Ty<'db>,566        lt: Region<'db>,567    ) -> Self {568        let ty = Ty::new_ref(interner, lt, ty, m);569        Adjustment {570            kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),571            target: ty.store(),572        }573    }574}575576/// At least for initial deployment, we want to limit two-phase borrows to577/// only a few specific cases. Right now, those are mostly "things that desugar"578/// into method calls:579/// - using `x.some_method()` syntax, where some_method takes `&mut self`,580/// - using `Foo::some_method(&mut x, ...)` syntax,581/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).582///583/// Anything else should be rejected until generalized two-phase borrow support584/// is implemented. Right now, dataflow can't handle the general case where there585/// is more than one use of a mutable borrow, and we don't want to accept too much586/// new code via two-phase borrows, so we try to limit where we create two-phase587/// capable mutable borrows.588/// See #49434 for tracking.589#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]590pub enum AllowTwoPhase {591    // FIXME: We should use this when appropriate.592    Yes,593    No,594}595596#[derive(Clone, Debug, PartialEq, Eq, Hash)]597pub enum Adjust {598    /// Go from ! to any type.599    NeverToAny,600    /// Dereference once, producing a place.601    Deref(Option<OverloadedDeref>),602    /// Take the address and produce either a `&` or `*` pointer.603    Borrow(AutoBorrow),604    Pointer(PointerCast),605}606607/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`608/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.609/// The target type is `U` in both cases, with the region and mutability610/// being those shared by both the receiver and the returned reference.611#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]612pub struct OverloadedDeref(pub Mutability);613614#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]615pub enum AutoBorrowMutability {616    Mut { allow_two_phase_borrow: AllowTwoPhase },617    Not,618}619620impl AutoBorrowMutability {621    /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows.622    ///623    /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored624    pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {625        match mutbl {626            Mutability::Not => Self::Not,627            Mutability::Mut => Self::Mut { allow_two_phase_borrow },628        }629    }630}631632impl From<AutoBorrowMutability> for Mutability {633    fn from(m: AutoBorrowMutability) -> Self {634        match m {635            AutoBorrowMutability::Mut { .. } => Mutability::Mut,636            AutoBorrowMutability::Not => Mutability::Not,637        }638    }639}640641#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]642pub enum AutoBorrow {643    /// Converts from T to &T.644    Ref(AutoBorrowMutability),645    /// Converts from T to *T.646    RawPtr(Mutability),647}648649#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]650pub enum PointerCast {651    /// Go from a fn-item type to a fn-pointer type.652    ReifyFnPointer,653654    /// Go from a safe fn pointer to an unsafe fn pointer.655    UnsafeFnPointer,656657    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.658    /// It cannot convert a closure that requires unsafe.659    ClosureFnPointer(Safety),660661    /// Go from a mut raw pointer to a const raw pointer.662    MutToConstPointer,663664    #[allow(dead_code)]665    /// Go from `*const [T; N]` to `*const T`666    ArrayToPointer,667668    /// Unsize a pointer/reference value, e.g., `&[T; n]` to669    /// `&[T]`. Note that the source could be a thin or fat pointer.670    /// This will do things like convert thin pointers to fat671    /// pointers, or convert structs containing thin pointers to672    /// structs containing fat pointers, or convert between fat673    /// pointers. We don't store the details of how the transform is674    /// done (in fact, we don't know that, because it might depend on675    /// the precise type parameters). We just store the target676    /// type. Codegen backends and miri figure out what has to be done677    /// based on the precise source/target type at hand.678    Unsize,679}680681/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern682/// against it. Currently, this is used only for implicit dereferences.683#[derive(Debug, Clone, PartialEq, Eq)]684pub struct PatAdjustment {685    pub kind: PatAdjust,686    /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the687    /// pattern.688    pub source: StoredTy,689}690691/// Represents implicit coercions of patterns' types, rather than values' types.692#[derive(Clone, Copy, PartialEq, Eq, Debug)]693pub enum PatAdjust {694    /// An implicit dereference before matching, such as when matching the pattern `0` against a695    /// scrutinee of type `&u8` or `&mut u8`.696    BuiltinDeref,697    /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the698    /// pattern `[..]` against a scrutinee of type `Vec<T>`.699    OverloadedDeref,700}701702/// The result of type inference: A mapping from expressions and patterns to types.703///704/// When you add a field that stores types (including `Substitution` and the like), don't forget705/// `resolve_completely()`'ing  them in `InferenceContext::resolve_all()`. Inference variables must706/// not appear in the final inference result.707#[derive(Clone, PartialEq, Eq, Debug)]708pub struct InferenceResult {709    /// For each method call expr, records the function it resolves to.710    method_resolutions: FxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,711    /// For each field access expr, records the field it resolves to.712    field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,713    /// For each struct literal or pattern, records the variant it resolves to.714    variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,715    /// For each associated item record what it resolves to716    assoc_resolutions: FxHashMap<ExprOrPatId, (CandidateId, StoredGenericArgs)>,717    /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in718    /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of719    /// that which allows us to resolve a [`TupleFieldId`]s type.720    tuple_field_access_types: ThinVec<StoredTys>,721722    pub(crate) type_of_expr: ArenaMap<ExprId, StoredTy>,723    /// For each pattern record the type it resolves to.724    ///725    /// **Note**: When a pattern type is resolved it may still contain726    /// unresolved or missing subpatterns or subpatterns of mismatched types.727    pub(crate) type_of_pat: ArenaMap<PatId, StoredTy>,728    pub(crate) type_of_binding: ArenaMap<BindingId, StoredTy>,729    pub(crate) type_of_type_placeholder: FxHashMap<TypeRefId, StoredTy>,730    pub(crate) type_of_opaque: FxHashMap<InternedOpaqueTyId, StoredTy>,731732    /// Whether there are any type-mismatching errors in the result.733    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to734    // `TyKind::Error`.735    // Which will then mark this field.736    pub(crate) has_errors: bool,737    /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.738    diagnostics: ThinVec<InferenceDiagnostic>,739    // FIXME: Remove this, change it to be in `InferenceContext`:740    nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatId>>>,741742    /// Interned `Error` type to return references to.743    // FIXME: Remove this.744    error_ty: StoredTy,745746    pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,747    /// Stores the types which were implicitly dereferenced in pattern binding modes.748    pub(crate) pat_adjustments: FxHashMap<PatId, Vec<PatAdjustment>>,749    /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.750    ///751    /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an752    /// or pattern can have multiple binding modes. For example:753    /// ```754    /// fn foo(mut slice: &[u32]) -> usize {755    ///     slice = match slice {756    ///         [0, rest @ ..] | rest => rest,757    ///     };758    ///     0759    /// }760    /// ```761    /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.762    pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,763764    /// Set of reference patterns that match against a match-ergonomics inserted reference765    /// (as opposed to against a reference in the scrutinee type).766    skipped_ref_pats: FxHashSet<PatId>,767768    pub(crate) coercion_casts: FxHashSet<ExprId>,769770    pub closures_data: FxHashMap<ExprId, ClosureData>,771772    defined_anon_consts: ThinVec<AnonConstId>,773}774775#[derive(Clone, PartialEq, Eq, Debug, Default)]776pub struct ClosureData {777    /// Tracks the minimum captures required for a closure;778    /// see `MinCaptureInformationMap` for more details.779    pub min_captures: RootVariableMinCaptureList,780781    /// Tracks the fake reads required for a closure and the reason for the fake read.782    /// When performing pattern matching for closures, there are times we don't end up783    /// reading places that are mentioned in a closure (because of _ patterns). However,784    /// to ensure the places are initialized, we introduce fake reads.785    /// Consider these two examples:786    /// ```ignore (discriminant matching with only wildcard arm)787    /// let x: u8;788    /// let c = || match x { _ => () };789    /// ```790    /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't791    /// want to capture it. However, we do still want an error here, because `x` should have792    /// to be initialized at the point where c is created. Therefore, we add a "fake read"793    /// instead.794    /// ```ignore (destructured assignments)795    /// let c = || {796    ///     let (t1, t2) = t;797    /// }798    /// ```799    /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but800    /// we never capture `t`. This becomes an issue when we build MIR as we require801    /// information on `t` in order to create place `t.0` and `t.1`. We can solve this802    /// issue by fake reading `t`.803    pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,804}805806/// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`.807/// Used to track the minimum set of `Place`s that need to be captured to support all808/// Places captured by the closure starting at a given root variable.809///810/// This provides a convenient and quick way of checking if a variable being used within811/// a closure is a capture of a local variable.812pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;813814/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.815pub(crate) type MinCaptureList = Vec<CapturedPlace>;816817/// A composite describing a `Place` that is captured by a closure.818#[derive(Eq, PartialEq, Clone, Debug, Hash)]819pub struct CapturedPlace {820    /// The `Place` that is captured.821    pub place: Place,822823    /// `CaptureKind` and expression(s) that resulted in such capture of `place`.824    pub info: CaptureInfo,825826    /// Represents if `place` can be mutated or not.827    pub mutability: Mutability,828}829830impl CapturedPlace {831    pub fn is_by_ref(&self) -> bool {832        match self.info.capture_kind {833            UpvarCapture::ByValue | UpvarCapture::ByUse => false,834            UpvarCapture::ByRef(..) => true,835        }836    }837838    pub fn captured_local(&self) -> BindingId {839        match self.place.base {840            PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,841            PlaceBase::Rvalue | PlaceBase::StaticItem => {842                unreachable!("only locals can be captured")843            }844        }845    }846847    /// The type of the capture stored in the closure, which is different from the type of the captured place848    /// if we capture by reference.849    pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {850        let place_ty = self.place.ty();851        let make_ref = |mutbl| {852            let interner = DbInterner::new_no_crate(db);853            let region = Region::new_erased(interner);854            Ty::new_ref(interner, region, place_ty, mutbl)855        };856        match self.info.capture_kind {857            UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,858            UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),859        }860    }861}862863#[derive(Clone)]864pub struct CaptureSourceStack(CaptureSourceStackRepr);865866#[derive(Clone)]867enum CaptureSourceStackRepr {868    One(ExprOrPatId),869    Two([ExprOrPatId; 2]),870    Many(ThinVec<ExprOrPatId>),871}872873impl PartialEq for CaptureSourceStack {874    fn eq(&self, other: &Self) -> bool {875        **self == **other876    }877}878879impl Eq for CaptureSourceStack {}880881impl std::hash::Hash for CaptureSourceStack {882    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {883        (**self).hash(state);884    }885}886887const _: () = assert!(size_of::<CaptureSourceStack>() == 16);888889impl Deref for CaptureSourceStack {890    type Target = [ExprOrPatId];891892    #[inline]893    fn deref(&self) -> &Self::Target {894        match &self.0 {895            CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),896            CaptureSourceStackRepr::Two(it) => it,897            CaptureSourceStackRepr::Many(it) => it,898        }899    }900}901902impl fmt::Debug for CaptureSourceStack {903    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {904        f.debug_tuple("CaptureSourceStack").field(&&**self).finish()905    }906}907908impl CaptureSourceStack {909    #[inline]910    pub fn len(&self) -> usize {911        match &self.0 {912            CaptureSourceStackRepr::One(_) => 1,913            CaptureSourceStackRepr::Two(_) => 2,914            CaptureSourceStackRepr::Many(it) => it.len(),915        }916    }917918    #[inline]919    pub(crate) fn from_single(id: ExprOrPatId) -> Self {920        Self(CaptureSourceStackRepr::One(id))921    }922923    #[inline]924    pub fn final_source(&self) -> ExprOrPatId {925        *self.last().expect("should always have a final source")926    }927928    pub fn push(&mut self, new_id: ExprOrPatId) {929        match &mut self.0 {930            CaptureSourceStackRepr::One(old_id) => {931                self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])932            }933            CaptureSourceStackRepr::Two([old_id1, old_id2]) => {934                self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));935            }936            CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),937        }938    }939940    pub fn truncate(&mut self, new_len: usize) {941        debug_assert!(new_len > 0);942        match &mut self.0 {943            CaptureSourceStackRepr::One(_) => {}944            CaptureSourceStackRepr::Two([first, _]) => {945                if new_len == 1 {946                    self.0 = CaptureSourceStackRepr::One(*first)947                }948            }949            CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),950        }951    }952953    pub fn shrink_to_fit(&mut self) {954        match &mut self.0 {955            CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}956            CaptureSourceStackRepr::Many(ids) => match **ids {957                [one] => self.0 = CaptureSourceStackRepr::One(one),958                [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),959                _ => ids.shrink_to_fit(),960            },961        }962    }963}964965/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)966/// for a particular capture as well as identifying the part of the source code967/// that triggered this capture to occur.968#[derive(Eq, PartialEq, Clone, Debug, Hash)]969pub struct CaptureInfo {970    pub sources: SmallVec<[CaptureSourceStack; 2]>,971972    /// Capture mode that was selected973    pub capture_kind: UpvarCapture,974}975976/// Information describing the capture of an upvar. This is computed977/// during `typeck`, specifically by `regionck`.978#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]979pub enum UpvarCapture {980    /// Upvar is captured by value. This is always true when the981    /// closure is labeled `move`, but can also be true in other cases982    /// depending on inference.983    ByValue,984985    /// Upvar is captured by use. This is true when the closure is labeled `use`.986    ByUse,987988    /// Upvar is captured by reference.989    ByRef(BorrowKind),990}991992#[salsa::tracked]993impl InferenceResult {994    #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]995    fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult {996        infer_query(db, def)997    }998999    /// Infer types for all const expressions in an item's signature.1000    ///1001    /// Returns an `InferenceResult` containing type information for array lengths,1002    /// const generic arguments, and other const expressions appearing in type1003    /// positions within the item's signature.1004    #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]1005    fn for_anon_const(db: &dyn HirDatabase, def: AnonConstId) -> InferenceResult {1006        infer_anon_const_query(db, def)1007    }10081009    #[inline]1010    pub fn of(db: &dyn HirDatabase, def: impl Into<InferBodyId>) -> &InferenceResult {1011        match def.into() {1012            InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),1013            InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),1014        }1015    }1016}10171018impl InferenceResult {1019    fn new(error_ty: Ty<'_>) -> Self {1020        Self {1021            method_resolutions: Default::default(),1022            field_resolutions: Default::default(),1023            variant_resolutions: Default::default(),1024            assoc_resolutions: Default::default(),1025            tuple_field_access_types: Default::default(),1026            diagnostics: Default::default(),1027            nodes_with_type_mismatches: Default::default(),1028            type_of_expr: Default::default(),1029            type_of_pat: Default::default(),1030            type_of_binding: Default::default(),1031            type_of_type_placeholder: Default::default(),1032            type_of_opaque: Default::default(),1033            skipped_ref_pats: Default::default(),1034            has_errors: Default::default(),1035            error_ty: error_ty.store(),1036            pat_adjustments: Default::default(),1037            binding_modes: Default::default(),1038            expr_adjustments: Default::default(),1039            coercion_casts: Default::default(),1040            closures_data: Default::default(),1041            defined_anon_consts: Default::default(),1042        }1043    }10441045    pub fn method_resolution<'db>(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {1046        self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))1047    }1048    pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {1049        self.field_resolutions.get(&expr).copied()1050    }1051    pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {1052        self.variant_resolutions.get(&id.into()).copied()1053    }1054    pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {1055        self.variant_resolutions.get(&id.into()).copied()1056    }1057    pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {1058        match id {1059            ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),1060            ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),1061        }1062    }1063    pub fn assoc_resolutions_for_expr<'db>(1064        &self,1065        id: ExprId,1066    ) -> Option<(CandidateId, GenericArgs<'db>)> {1067        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1068    }1069    pub fn assoc_resolutions_for_pat<'db>(1070        &self,1071        id: PatId,1072    ) -> Option<(CandidateId, GenericArgs<'db>)> {1073        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1074    }1075    pub fn assoc_resolutions_for_expr_or_pat<'db>(1076        &self,1077        id: ExprOrPatId,1078    ) -> Option<(CandidateId, GenericArgs<'db>)> {1079        match id {1080            ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),1081            ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),1082        }1083    }1084    pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatId) -> bool {1085        self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node))1086    }1087    pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {1088        self.expr_or_pat_has_type_mismatch(expr.into())1089    }1090    pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {1091        self.expr_or_pat_has_type_mismatch(pat.into())1092    }1093    pub fn exprs_have_type_mismatches(&self) -> bool {1094        self.nodes_with_type_mismatches1095            .as_ref()1096            .is_some_and(|it| it.iter().any(|node| node.is_expr()))1097    }1098    pub fn has_type_mismatches(&self) -> bool {1099        self.nodes_with_type_mismatches.is_some()1100    }1101    pub fn placeholder_types<'db>(&self) -> impl Iterator<Item = (TypeRefId, Ty<'db>)> {1102        self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref()))1103    }1104    pub fn type_of_type_placeholder<'db>(&self, type_ref: TypeRefId) -> Option<Ty<'db>> {1105        self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref())1106    }1107    pub fn type_of_expr_or_pat<'db>(&self, id: ExprOrPatId) -> Option<Ty<'db>> {1108        match id {1109            ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()),1110            ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()),1111        }1112    }1113    pub fn type_of_expr_with_adjust<'db>(&self, id: ExprId) -> Option<Ty<'db>> {1114        match self.expr_adjustments.get(&id).and_then(|adjustments| {1115            adjustments.iter().rfind(|adj| {1116                // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L1401117                !matches!(1118                    adj,1119                    Adjustment {1120                        kind: Adjust::NeverToAny,1121                        target,1122                    } if target.as_ref().is_never()1123                )1124            })1125        }) {1126            Some(adjustment) => Some(adjustment.target.as_ref()),1127            None => self.type_of_expr.get(id).map(|it| it.as_ref()),1128        }1129    }1130    pub fn type_of_pat_with_adjust<'db>(&self, id: PatId) -> Ty<'db> {1131        match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {1132            Some(adjusted) => adjusted.source.as_ref(),1133            None => self.pat_ty(id),1134        }1135    }1136    pub fn is_erroneous(&self) -> bool {1137        self.has_errors && self.type_of_expr.iter().count() == 01138    }11391140    pub fn diagnostics(&self) -> &[InferenceDiagnostic] {1141        &self.diagnostics1142    }11431144    pub fn tuple_field_access_type<'db>(&self, id: TupleId) -> Tys<'db> {1145        self.tuple_field_access_types[id.0 as usize].as_ref()1146    }11471148    pub fn pat_adjustment(&self, id: PatId) -> Option<&[PatAdjustment]> {1149        self.pat_adjustments.get(&id).map(|it| &**it)1150    }11511152    pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {1153        self.expr_adjustments.get(&id).map(|it| &**it)1154    }11551156    pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {1157        self.binding_modes.get(id).copied()1158    }11591160    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1161    pub fn expression_types<'db>(&self) -> impl Iterator<Item = (ExprId, Ty<'db>)> {1162        self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref()))1163    }11641165    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1166    pub fn pattern_types<'db>(&self) -> impl Iterator<Item = (PatId, Ty<'db>)> {1167        self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref()))1168    }11691170    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1171    pub fn binding_types<'db>(&self) -> impl Iterator<Item = (BindingId, Ty<'db>)> {1172        self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref()))1173    }11741175    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1176    pub fn return_position_impl_trait_types<'db>(1177        &'db self,1178        db: &'db dyn HirDatabase,1179    ) -> impl Iterator<Item = (ImplTraitIdx, Ty<'db>)> {1180        self.type_of_opaque.iter().filter_map(move |(&id, ty)| {1181            let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {1182                return None;1183            };1184            Some((rpit_idx, ty.as_ref()))1185        })1186    }11871188    pub fn expr_ty<'db>(&self, id: ExprId) -> Ty<'db> {1189        self.type_of_expr.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1190    }11911192    pub fn pat_ty<'db>(&self, id: PatId) -> Ty<'db> {1193        self.type_of_pat.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1194    }11951196    pub fn expr_or_pat_ty<'db>(&self, id: ExprOrPatId) -> Ty<'db> {1197        self.type_of_expr_or_pat(id).unwrap_or(self.error_ty.as_ref())1198    }11991200    pub fn binding_ty<'db>(&self, id: BindingId) -> Ty<'db> {1201        self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1202    }12031204    /// This does not deduplicate, which means you'll get the types once per capture.1205    pub fn closure_captures_tys<'db>(&self, closure: ExprId) -> impl Iterator<Item = Ty<'db>> {1206        self.closures_data[&closure]1207            .min_captures1208            .values()1209            .flat_map(|captures| captures.iter().map(|capture| capture.place.ty()))1210    }12111212    /// Like [`Self::closure_captures_tys()`], but using [`CapturedPlace::captured_ty()`].1213    pub fn closure_captures_captured_tys<'db>(1214        &self,1215        db: &'db dyn HirDatabase,1216        closure: ExprId,1217    ) -> impl Iterator<Item = Ty<'db>> {1218        self.closures_data[&closure]1219            .min_captures1220            .values()1221            .flat_map(|captures| captures.iter().map(|capture| capture.captured_ty(db)))1222    }12231224    pub fn is_skipped_ref_pat(&self, pat: PatId) -> bool {1225        self.skipped_ref_pats.contains(&pat)1226    }1227}12281229#[derive(Debug, Clone, Copy)]1230enum DerefPatBorrowMode {1231    Borrow(Mutability),1232    Box,1233}12341235/// The inference context contains all information needed during type inference.1236#[derive(Debug)]1237pub(crate) struct InferenceContext<'body, 'db> {1238    pub(crate) db: &'db dyn HirDatabase,1239    pub(crate) owner: InferBodyId,1240    pub(crate) store_owner: ExpressionStoreOwnerId,1241    pub(crate) generic_def: GenericDefId,1242    pub(crate) store: &'body ExpressionStore,1243    pub(crate) lowering_mode: LoweringMode,1244    /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext1245    /// and resolve the path via its methods. This will ensure proper error reporting.1246    pub(crate) resolver: Resolver<'db>,1247    target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,1248    pub(crate) edition: Edition,1249    allow_using_generic_params: bool,1250    generics: OnceCell<Generics<'db>>,1251    identity_args: OnceCell<GenericArgs<'db>>,1252    pub(crate) table: unify::InferenceTable<'db>,1253    pub(crate) lang_items: &'db LangItems,1254    pub(crate) features: &'db UnstableFeatures,1255    /// The traits in scope, disregarding block modules. This is used for caching purposes.1256    traits_in_scope: FxHashSet<TraitId>,1257    pub(crate) result: InferenceResult,1258    tuple_field_accesses_rev:1259        IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,1260    /// The return type of the function being inferred, the closure or async block if we're1261    /// currently within one.1262    ///1263    /// We might consider using a nested inference context for checking1264    /// closures so we can swap all shared things out at once.1265    return_ty: Ty<'db>,1266    /// If `Some`, this stores coercion information for returned1267    /// expressions. If `None`, this is in a context where return is1268    /// inappropriate, such as a const expression.1269    return_coercion: Option<DynamicCoerceMany<'db>>,1270    /// The resume type and the yield type, respectively, of the coroutine being inferred.1271    resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,1272    diverges: Diverges,1273    breakables: Vec<BreakableContext<'db>>,1274    types: &'db crate::next_solver::DefaultAny<'db>,12751276    /// Whether we are inside the pattern of a destructuring assignment.1277    inside_assignment: bool,12781279    deferred_cast_checks: Vec<CastCheck<'db>>,12801281    /// The key is an expression defining a closure or a coroutine closure.1282    deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>,12831284    diagnostics: Diagnostics,1285    vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>,12861287    defined_anon_consts: RefCell<ThinVec<AnonConstId>>,1288}12891290#[derive(Clone, Debug)]1291struct BreakableContext<'db> {1292    /// Whether this context contains at least one break expression.1293    may_break: bool,1294    /// The coercion target of the context.1295    coerce: Option<DynamicCoerceMany<'db>>,1296    /// The optional label of the context.1297    label: Option<LabelId>,1298    kind: BreakableKind,1299}13001301#[derive(Clone, Debug)]1302enum BreakableKind {1303    Block,1304    Loop,1305    /// A border is something like an async block, closure etc. Anything that prevents1306    /// breaking/continuing through1307    Border,1308}13091310fn find_breakable<'a, 'db>(1311    ctxs: &'a mut [BreakableContext<'db>],1312    label: Option<LabelId>,1313) -> Option<&'a mut BreakableContext<'db>> {1314    let mut ctxs = ctxs1315        .iter_mut()1316        .rev()1317        .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));1318    match label {1319        Some(_) => ctxs.find(|ctx| ctx.label == label),1320        None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),1321    }1322}13231324fn find_continuable<'a, 'db>(1325    ctxs: &'a mut [BreakableContext<'db>],1326    label: Option<LabelId>,1327) -> Option<&'a mut BreakableContext<'db>> {1328    match label {1329        Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),1330        None => find_breakable(ctxs, label),1331    }1332}13331334impl<'body, 'db> InferenceContext<'body, 'db> {1335    fn new(1336        db: &'db dyn HirDatabase,1337        owner: InferBodyId,1338        store_owner: ExpressionStoreOwnerId,1339        generic_def: GenericDefId,1340        store: &'body ExpressionStore,1341        resolver: Resolver<'db>,1342        allow_using_generic_params: bool,1343        lowering_mode: LoweringMode,1344    ) -> Self {1345        let trait_env = db.trait_environment(generic_def);1346        let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), store_owner);1347        let types = crate::next_solver::default_types(db);1348        InferenceContext {1349            result: InferenceResult::new(types.types.error),1350            return_ty: types.types.error, // set in collect_* calls1351            types,1352            target_features: OnceCell::new(),1353            lang_items: table.interner().lang_items(),1354            features: resolver.top_level_def_map().features(),1355            edition: resolver.krate().data(db).edition,1356            table,1357            tuple_field_accesses_rev: Default::default(),1358            resume_yield_tys: None,1359            return_coercion: None,1360            db,1361            owner,1362            store_owner,1363            generic_def,1364            allow_using_generic_params,1365            generics: OnceCell::new(),1366            identity_args: OnceCell::new(),1367            store,1368            traits_in_scope: resolver.traits_in_scope(db),1369            resolver,1370            diverges: Diverges::Maybe,1371            breakables: Vec::new(),1372            deferred_cast_checks: Vec::new(),1373            inside_assignment: false,1374            diagnostics: Diagnostics::default(),1375            vars_emitted_type_must_be_known_for: FxHashSet::default(),1376            deferred_call_resolutions: FxHashMap::default(),1377            defined_anon_consts: RefCell::new(ThinVec::new()),1378            lowering_mode,1379        }1380    }13811382    fn merge(&mut self, other: &InferenceResult) {1383        let InferenceResult {1384            method_resolutions,1385            field_resolutions,1386            variant_resolutions,1387            assoc_resolutions,1388            tuple_field_access_types: _,1389            type_of_expr,1390            type_of_pat,1391            type_of_binding,1392            type_of_type_placeholder,1393            type_of_opaque,1394            has_errors: _,1395            diagnostics: _,1396            error_ty: _,1397            expr_adjustments,1398            pat_adjustments,1399            binding_modes,1400            skipped_ref_pats,1401            coercion_casts,1402            closures_data,1403            nodes_with_type_mismatches,1404            defined_anon_consts: _,1405        } = &mut self.result;1406        merge_hash_maps(method_resolutions, &other.method_resolutions);1407        merge_hash_maps(variant_resolutions, &other.variant_resolutions);1408        merge_hash_maps(assoc_resolutions, &other.assoc_resolutions);1409        field_resolutions.extend(other.field_resolutions.iter().map(1410            |(&field_expr, &field_resolution)| {1411                let mut field_resolution = field_resolution;1412                if let Either::Right(tuple_field) = &mut field_resolution {1413                    let tys = other.tuple_field_access_type(tuple_field.tuple);1414                    tuple_field.tuple =1415                        TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);1416                };1417                (field_expr, field_resolution)1418            },1419        ));1420        merge_arena_maps(type_of_expr, &other.type_of_expr);1421        merge_arena_maps(type_of_pat, &other.type_of_pat);1422        merge_arena_maps(type_of_binding, &other.type_of_binding);1423        merge_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);1424        merge_hash_maps(type_of_opaque, &other.type_of_opaque);1425        merge_hash_maps(expr_adjustments, &other.expr_adjustments);1426        merge_hash_maps(pat_adjustments, &other.pat_adjustments);1427        merge_arena_maps(binding_modes, &other.binding_modes);1428        merge_hash_set(skipped_ref_pats, &other.skipped_ref_pats);1429        merge_hash_set(coercion_casts, &other.coercion_casts);1430        merge_hash_maps(closures_data, &other.closures_data);1431        if let Some(other_nodes_with_type_mismatches) = &other.nodes_with_type_mismatches {1432            merge_hash_set(1433                nodes_with_type_mismatches.get_or_insert_default(),1434                other_nodes_with_type_mismatches,1435            );1436        }1437        self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());14381439        fn merge_hash_set<T: Hash + Eq + Clone>(dest: &mut FxHashSet<T>, source: &FxHashSet<T>) {1440            dest.extend(source.iter().cloned());1441        }14421443        #[cfg_attr(debug_assertions, track_caller)]1444        fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(1445            dest: &mut FxHashMap<K, V>,1446            source: &FxHashMap<K, V>,1447        ) {1448            if cfg!(debug_assertions) {1449                for (key, src) in source {1450                    assert!(dest.get(key).is_none_or(|dst| dst == src));1451                }1452            }14531454            dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));1455        }14561457        #[cfg_attr(debug_assertions, track_caller)]1458        fn merge_arena_maps<K, V: Clone + PartialEq>(1459            dest: &mut ArenaMap<la_arena::Idx<K>, V>,1460            source: &ArenaMap<la_arena::Idx<K>, V>,1461        ) {1462            if cfg!(debug_assertions) {1463                for (key, src) in source.iter() {1464                    assert!(dest.get(key).is_none_or(|dst| dst == src));1465                }1466            }14671468            dest.extend(source.iter().map(|(k, v)| (k, v.clone())));1469        }1470    }14711472    #[inline]1473    fn krate(&self) -> Crate {1474        self.resolver.krate()1475    }14761477    fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {1478        let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {1479            let target_features = match self.store_owner {1480                ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {1481                    TargetFeatures::from_fn(self.db, id)1482                }1483                _ => TargetFeatures::default(),1484            };1485            let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {1486                Ok(target) => crate::utils::target_feature_is_safe_in_target(target),1487                Err(_) => TargetFeatureIsSafeInTarget::No,1488            };1489            (target_features, target_feature_is_safe)1490        });1491        (target_features, *target_feature_is_safe)1492    }14931494    /// How should a deref pattern find the place for its inner pattern to match on?1495    ///1496    /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner1497    /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.1498    /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;1499    /// in this case, we return `DerefPatBorrowMode::Box`.1500    fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {1501        if pointer_ty.is_box() {1502            DerefPatBorrowMode::Box1503        } else {1504            let mutability =1505                if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };1506            DerefPatBorrowMode::Borrow(mutability)1507        }1508    }15091510    #[inline]1511    fn set_tainted_by_errors(&mut self) {1512        self.result.has_errors = true;1513    }15141515    /// Copy the inference of defined anon consts to ourselves, so that we don't need to lookup the defining1516    /// anon const when looking the type of something.1517    fn merge_anon_consts(&mut self) {1518        let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());1519        defined_anon_consts.retain(|&konst| {1520            if konst.loc(self.db).owner != self.store_owner {1521                // This comes from the signature, we don't define it.1522                return false;1523            }15241525            let const_infer = InferenceResult::of(self.db, konst);1526            self.merge(const_infer);1527            true1528        });1529        // Caution, other defined anon consts might have been added by `merge()`!1530        self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);1531    }15321533    // FIXME: This function should be private in module. It is currently only used in the consteval, since we need1534    // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you1535    // used this function for another workaround, mention it here. If you really need this function and believe that1536    // there is no problem in it being `pub(crate)`, remove this comment.1537    fn resolve_all(self) -> InferenceResult {1538        let InferenceContext {1539            table,1540            mut result,1541            tuple_field_accesses_rev,1542            diagnostics,1543            types,1544            vars_emitted_type_must_be_known_for,1545            ..1546        } = self;1547        let diagnostics = diagnostics.finish();1548        // Destructure every single field so whenever new fields are added to `InferenceResult` we1549        // don't forget to handle them here.1550        let InferenceResult {1551            method_resolutions,1552            field_resolutions: _,1553            variant_resolutions: _,1554            assoc_resolutions,1555            type_of_expr,1556            type_of_pat,1557            type_of_binding,1558            type_of_type_placeholder,1559            type_of_opaque,1560            skipped_ref_pats,1561            closures_data,1562            has_errors,1563            error_ty: _,1564            pat_adjustments,1565            binding_modes: _,1566            expr_adjustments,1567            tuple_field_access_types,1568            coercion_casts: _,1569            diagnostics: result_diagnostics,1570            nodes_with_type_mismatches,1571            defined_anon_consts: result_defined_anon_consts,1572        } = &mut result;15731574        *result_defined_anon_consts = self.defined_anon_consts.into_inner();1575        result_defined_anon_consts.shrink_to_fit();15761577        let mut resolver =1578            WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);15791580        skipped_ref_pats.shrink_to_fit();1581        for ty in type_of_expr.values_mut() {1582            resolver.resolve_completely(ty);1583        }1584        type_of_expr.shrink_to_fit();1585        for ty in type_of_pat.values_mut() {1586            resolver.resolve_completely(ty);1587        }1588        type_of_pat.shrink_to_fit();1589        for ty in type_of_binding.values_mut() {1590            resolver.resolve_completely(ty);1591        }1592        type_of_binding.shrink_to_fit();1593        for ty in type_of_type_placeholder.values_mut() {1594            resolver.resolve_completely(ty);1595        }1596        type_of_type_placeholder.shrink_to_fit();1597        type_of_opaque.shrink_to_fit();15981599        if let Some(nodes_with_type_mismatches) = nodes_with_type_mismatches {1600            *has_errors = true;1601            nodes_with_type_mismatches.shrink_to_fit();1602        }1603        for (_, subst) in method_resolutions.values_mut() {1604            resolver.resolve_completely(subst);1605        }1606        method_resolutions.shrink_to_fit();1607        for (_, subst) in assoc_resolutions.values_mut() {1608            resolver.resolve_completely(subst);1609        }1610        assoc_resolutions.shrink_to_fit();1611        for adjustment in expr_adjustments.values_mut().flatten() {1612            resolver.resolve_completely(&mut adjustment.target);1613        }1614        expr_adjustments.shrink_to_fit();1615        for adjustments in pat_adjustments.values_mut() {1616            for adjustment in &mut *adjustments {1617                resolver.resolve_completely(&mut adjustment.source);1618            }1619            adjustments.shrink_to_fit();1620        }1621        pat_adjustments.shrink_to_fit();1622        for closure_data in closures_data.values_mut() {1623            let ClosureData { min_captures, fake_reads } = closure_data;1624            let dummy_place = || Place {1625                base_ty: types.types.error.store(),1626                base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,1627                projections: Vec::new(),1628            };16291630            for (place, _, sources) in fake_reads {1631                resolver.resolve_completely_with_default(place, dummy_place());1632                place.projections.shrink_to_fit();1633                for source in &mut *sources {1634                    source.shrink_to_fit();1635                }1636                sources.shrink_to_fit();1637            }16381639            for min_capture in min_captures.values_mut() {1640                for captured in &mut *min_capture {1641                    let CapturedPlace { place, info, mutability: _ } = captured;1642                    resolver.resolve_completely_with_default(place, dummy_place());1643                    let CaptureInfo { sources, capture_kind: _ } = info;1644                    for source in &mut *sources {1645                        source.shrink_to_fit();1646                    }1647                    sources.shrink_to_fit();1648                }1649                min_capture.shrink_to_fit();1650            }1651            min_captures.shrink_to_fit();1652        }1653        closures_data.shrink_to_fit();1654        *tuple_field_access_types = tuple_field_accesses_rev1655            .into_iter()1656            .map(|mut subst| {1657                resolver.resolve_completely(&mut subst);1658                subst.store()1659            })1660            .collect();1661        tuple_field_access_types.shrink_to_fit();16621663        let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();1664        *result_diagnostics = diagnostics;1665        *has_errors |= resolver_has_errors;16661667        result1668    }16691670    fn collect_const(&mut self, id: ConstId, data: &ConstSignature) {1671        let return_ty = self.make_ty(1672            data.type_ref,1673            &data.store,1674            InferenceTyDiagnosticSource::Signature,1675            ExpressionStoreOwnerId::Signature(id.into()),1676            LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container),1677        );16781679        self.return_ty = return_ty;1680    }16811682    fn collect_static(&mut self, id: StaticId, data: &StaticSignature) {1683        let return_ty = self.make_ty(1684            data.type_ref,1685            &data.store,1686            InferenceTyDiagnosticSource::Signature,1687            ExpressionStoreOwnerId::Signature(id.into()),1688            LifetimeElisionKind::Elided(self.types.regions.statik),1689        );16901691        self.return_ty = return_ty;1692    }16931694    fn collect_fn(&mut self, func: FunctionId, self_param: Option<BindingId>, params: &[PatId]) {1695        let data = FunctionSignature::of(self.db, func);1696        let mut param_tys = self.with_ty_lowering(1697            &data.store,1698            InferenceTyDiagnosticSource::Signature,1699            ExpressionStoreOwnerId::Signature(func.into()),1700            LifetimeElisionKind::for_fn_params(data),1701            |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),1702        );17031704        // Check if function contains a va_list, if it does then we append it to the parameter types1705        // that are collected from the function data1706        if data.is_varargs() {1707            let va_list_ty = match self.resolve_va_list() {1708                Some(va_list) => Ty::new_adt(1709                    self.interner(),1710                    va_list,1711                    GenericArgs::for_item_with_defaults(1712                        self.interner(),1713                        va_list.into(),1714                        |_, id, _| self.table.var_for_def(id, Span::Dummy),1715                    ),1716                ),1717                None => self.err_ty(),1718            };17191720            param_tys.push(va_list_ty);1721        }1722        let mut param_tys = param_tys.into_iter();1723        if let Some(self_param) = self_param1724            && let Some(ty) = param_tys.next()1725        {1726            let ty = self.process_user_written_ty(ty);1727            self.write_binding_ty(self_param, ty);1728        }1729        for pat in params {1730            let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));1731            let ty = self.process_user_written_ty(ty);17321733            self.infer_top_pat(*pat, ty, PatOrigin::Param);1734        }1735        self.return_ty = match data.ret_type {1736            Some(return_ty) => {1737                let return_ty = self.with_ty_lowering(1738                    &data.store,1739                    InferenceTyDiagnosticSource::Signature,1740                    ExpressionStoreOwnerId::Signature(func.into()),1741                    LifetimeElisionKind::for_fn_ret(self.interner()),1742                    |ctx| {1743                        ctx.impl_trait_mode(ImplTraitLoweringMode::Opaque);1744                        ctx.lower_ty(return_ty)1745                    },1746                );1747                self.process_user_written_ty(return_ty)1748            }1749            None => self.types.types.unit,1750        };17511752        self.return_coercion = Some(CoerceMany::new(self.return_ty));1753    }17541755    #[inline]1756    pub(crate) fn interner(&self) -> DbInterner<'db> {1757        self.table.interner()1758    }17591760    #[inline]1761    pub(crate) fn infcx(&self) -> &InferCtxt<'db> {1762        &self.table.infer_ctxt1763    }17641765    /// If `ty` is an error, returns an infer var instead. Otherwise, returns it.1766    ///1767    /// "Refreshing" types like this is useful for getting better types, but it is also1768    /// very dangerous: we might create duplicate diagnostics, for example if we try1769    /// to resolve it and fail. rustc doesn't do that for this reason (and is in general1770    /// more strict with how it uses error types; an error type in inputs will almost1771    /// always cause it to infer an error type in output, while we infer some type as much1772    /// as we can).1773    ///1774    /// Unfortunately, we cannot allow ourselves to do that. Not only we more often work1775    /// with incomplete code, we also have assists, for example "Generate constant", that1776    /// will assume the inferred type is the expected type even if the expression itself1777    /// cannot be inferred. Therefore, we choose a middle ground: refresh the type,1778    /// but if we return a new var, mark it so that no diagnostics will be issued on it.1779    fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {1780        if ty.is_ty_error() {1781            let var = self.table.next_ty_var(Span::Dummy);17821783            // Suppress future errors on this var. Add more things here when we add more diagnostics.1784            self.vars_emitted_type_must_be_known_for.insert(var.into());17851786            var1787        } else {1788            ty1789        }1790    }17911792    fn infer_body(&mut self, body_expr: ExprId) {1793        match self.return_coercion {1794            Some(_) => self.infer_return(body_expr),1795            None => {1796                _ = self.infer_expr_coerce(1797                    body_expr,1798                    &Expectation::has_type(self.return_ty),1799                    ExprIsRead::Yes,1800                )1801            }1802        }1803    }18041805    fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {1806        self.result.type_of_expr.insert(expr, ty.store());1807    }18081809    pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {1810        if adjustments.is_empty() {1811            return;1812        }1813        match self.result.expr_adjustments.entry(expr) {1814            std::collections::hash_map::Entry::Occupied(mut entry) => {1815                match (&mut entry.get_mut()[..], &adjustments[..]) {1816                    (1817                        [Adjustment { kind: Adjust::NeverToAny, target }],1818                        [.., Adjustment { target: new_target, .. }],1819                    ) => {1820                        // NeverToAny coercion can target any type, so instead of adding a new1821                        // adjustment on top we can change the target.1822                        *target = new_target.clone();1823                    }1824                    _ => {1825                        *entry.get_mut() = adjustments;1826                    }1827                }1828            }1829            std::collections::hash_map::Entry::Vacant(entry) => {1830                entry.insert(adjustments);1831            }1832        }1833    }18341835    pub(crate) fn write_method_resolution(1836        &mut self,1837        expr: ExprId,1838        func: FunctionId,1839        subst: GenericArgs<'db>,1840    ) {1841        self.result.method_resolutions.insert(expr, (func, subst.store()));1842    }18431844    fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {1845        self.result.variant_resolutions.insert(id, variant);1846    }18471848    fn write_assoc_resolution(1849        &mut self,1850        id: ExprOrPatId,1851        item: CandidateId,1852        subs: GenericArgs<'db>,1853    ) {1854        self.result.assoc_resolutions.insert(id, (item, subs.store()));1855    }18561857    fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {1858        self.result.type_of_pat.insert(pat, ty.store());1859    }18601861    fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {1862        self.result.type_of_binding.insert(id, ty.store());1863    }18641865    pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {1866        self.diagnostics.push(diagnostic);1867    }18681869    fn record_deferred_call_resolution(1870        &mut self,1871        closure_def_id: ExprId,1872        r: DeferredCallResolution<'db>,1873    ) {1874        self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);1875    }18761877    fn remove_deferred_call_resolutions(1878        &mut self,1879        closure_def_id: ExprId,1880    ) -> Vec<DeferredCallResolution<'db>> {1881        self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()1882    }18831884    fn with_ty_lowering<R>(1885        &mut self,1886        store: &ExpressionStore,1887        types_source: InferenceTyDiagnosticSource,1888        store_owner: ExpressionStoreOwnerId,1889        lifetime_elision: LifetimeElisionKind<'db>,1890        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,1891    ) -> R {1892        let infer_vars = match types_source {1893            InferenceTyDiagnosticSource::Body => Some(&mut InferenceTyLoweringVarsCtx {1894                table: &mut self.table,1895                type_of_type_placeholder: &mut self.result.type_of_type_placeholder,1896            } as _),1897            InferenceTyDiagnosticSource::Signature => None,1898        };1899        let mut ctx = TyLoweringContext::new(1900            self.db,1901            &self.resolver,1902            store,1903            &self.diagnostics,1904            types_source,1905            store_owner,1906            self.generic_def,1907            &self.generics,1908            lifetime_elision,1909            self.allow_using_generic_params,1910            infer_vars,1911            &self.defined_anon_consts,1912        );1913        f(&mut ctx)1914    }19151916    fn with_body_ty_lowering<R>(1917        &mut self,1918        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,1919    ) -> R {1920        self.with_ty_lowering(1921            self.store,1922            InferenceTyDiagnosticSource::Body,1923            self.store_owner,1924            LifetimeElisionKind::Infer,1925            f,1926        )1927    }19281929    fn make_ty(1930        &mut self,1931        type_ref: TypeRefId,1932        store: &ExpressionStore,1933        type_source: InferenceTyDiagnosticSource,1934        store_owner: ExpressionStoreOwnerId,1935        lifetime_elision: LifetimeElisionKind<'db>,1936    ) -> Ty<'db> {1937        let ty = self.with_ty_lowering(store, type_source, store_owner, lifetime_elision, |ctx| {1938            ctx.lower_ty(type_ref)1939        });1940        self.process_user_written_ty(ty)1941    }19421943    pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {1944        self.make_ty(1945            type_ref,1946            self.store,1947            InferenceTyDiagnosticSource::Body,1948            self.store_owner,1949            LifetimeElisionKind::Infer,1950        )1951    }19521953    fn generics(&self) -> &Generics<'db> {1954        self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))1955    }19561957    fn identity_args(&self) -> GenericArgs<'db> {1958        *self.identity_args.get_or_init(|| {1959            GenericArgs::identity_for_item(self.interner(), self.store_owner.into())1960        })1961    }19621963    pub(crate) fn create_body_anon_const(1964        &mut self,1965        expr: ExprId,1966        expected_ty: Ty<'db>,1967        allow_using_generic_params: bool,1968    ) -> Const<'db> {1969        never!(expected_ty.has_infer(), "cannot have infer vars in an anon const's ty");1970        let konst = create_anon_const(1971            self.interner(),1972            self.store_owner,1973            self.store,1974            expr,1975            &self.resolver,1976            expected_ty,1977            &|| self.generics(),1978            Some(&mut |span| self.table.next_const_var(span)),1979            self.lowering_mode,1980            (!(allow_using_generic_params && self.allow_using_generic_params)).then_some(0),1981        );19821983        if let Ok(konst) = konst1984            && let ConstKind::Unevaluated(konst) = konst.kind()1985            && let GeneralConstId::AnonConstId(konst) = konst.def.01986        {1987            self.defined_anon_consts.borrow_mut().push(konst);1988        }19891990        self.write_expr_ty(expr, expected_ty);1991        // FIXME: Report an error if needed.1992        konst.unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))1993    }19941995    pub(crate) fn make_path_as_body_const(&mut self, path: &Path) -> Const<'db> {1996        let forbid_params_after = if self.allow_using_generic_params { None } else { Some(0) };1997        // FIXME: Report errors.1998        path_to_const(self.db, &self.resolver, &|| self.generics(), forbid_params_after, path)1999            .unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))2000    }

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.