src/tools/rust-analyzer/crates/hir-ty/src/infer.rs RUST 2,856 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,856.
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_typeck/check.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.15//!16//! [`rustc_hir_typeck/check.rs`]: https://github.com/rust-lang/rust/blob/5503df87342a73d0c29126a7e08dc9c1255c46ad/compiler/rustc_hir_typeck/src/check.rs1718mod 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;3334use std::{35    cell::{OnceCell, RefCell},36    convert::identity,37    fmt,38    hash::Hash,39    ops::Deref,40};4142use base_db::{Crate, FxIndexMap};43use either::Either;44use hir_def::{45    AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId,46    FunctionId, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, StaticId, TraitId,47    TupleFieldId, TupleId, VariantId,48    attrs::AttrFlags,49    expr_store::{Body, ExpressionStore, HygieneId, body::Param, path::Path},50    hir::{BindingId, ExprId, ExprOrPatId, ExprOrPatIdPacked, LabelId, PatId},51    lang_item::LangItems,52    layout::Integer,53    resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},54    signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature},55    type_ref::{LifetimeRefId, TypeRefId},56    unstable_features::UnstableFeatures,57};58use hir_expand::{mod_path::ModPath, name::Name};59use indexmap::IndexSet;60use la_arena::ArenaMap;61use macros::{TypeFoldable, TypeVisitable};62use rustc_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;7475use crate::{76    ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,77    TargetFeatures,78    closure_analysis::PlaceBase,79    consteval::{create_anon_const, path_to_const},80    db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},81    generics::Generics,82    infer::{83        callee::DeferredCallResolution,84        closure::analysis::{85            BorrowKind,86            expr_use_visitor::{FakeReadCause, Place},87        },88        coerce::{CoerceMany, DynamicCoerceMany},89        diagnostics::{90            Diagnostics, InferenceTyLoweringContext as TyLoweringContext,91            InferenceTyLoweringVarsCtx,92        },93        expr::ExprIsRead,94        pat::PatOrigin,95        unify::resolve_completely::WriteBackCtxt,96    },97    lower::{98        ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, LifetimeLoweringMode,99        LoweringMode, diagnostics::TyLoweringDiagnostic,100    },101    method_resolution::CandidateId,102    next_solver::{103        AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, StoredFnSig,104        StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,105        abi::Safety,106        infer::{InferCtxt, ObligationInspector, traits::ObligationCause},107    },108    solver_errors::SolverDiagnostic,109    utils::TargetFeatureIsSafeInTarget,110};111112// This lint has a false positive here. See the link below for details.113//114// https://github.com/rust-lang/rust/issues/57411115#[allow(unreachable_pub)]116pub use coerce::could_coerce;117#[allow(unreachable_pub)]118pub use unify::{could_unify, could_unify_deeply};119120use cast::{CastCheck, CastError};121122/// The entry point of type inference.123fn infer_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {124    infer_query_with_inspect(db, def, None, LoweringMode::Analysis)125}126127pub fn infer_query_with_inspect<'db>(128    db: &'db dyn HirDatabase,129    def: DefWithBodyId,130    inspect: Option<ObligationInspector<'db>>,131    lowering_mode: LoweringMode,132) -> InferenceResult<'db> {133    let _p = tracing::info_span!("infer_query").entered();134    let resolver = def.resolver(db);135    let body = Body::of(db, def);136    let mut ctx = InferenceContext::new(137        db,138        InferBodyId::DefWithBodyId(def),139        ExpressionStoreOwnerId::Body(def),140        def.generic_def(db),141        &body.store,142        resolver,143        true,144        lowering_mode,145    );146147    if let Some(inspect) = inspect {148        ctx.table.infer_ctxt.attach_obligation_inspector(inspect);149    }150151    match def {152        DefWithBodyId::FunctionId(f) => {153            ctx.collect_fn(f, body.self_param.map(|param| param.formal), &body.params)154        }155        DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)),156        DefWithBodyId::StaticId(s) => ctx.collect_static(s, StaticSignature::of(db, s)),157        DefWithBodyId::VariantId(v) => {158            ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {159                hir_def::layout::IntegerType::Pointer(signed) => match signed {160                    true => ctx.types.types.isize,161                    false => ctx.types.types.usize,162                },163                hir_def::layout::IntegerType::Fixed(size, signed) => match signed {164                    true => match size {165                        Integer::I8 => ctx.types.types.i8,166                        Integer::I16 => ctx.types.types.i16,167                        Integer::I32 => ctx.types.types.i32,168                        Integer::I64 => ctx.types.types.i64,169                        Integer::I128 => ctx.types.types.i128,170                    },171                    false => match size {172                        Integer::I8 => ctx.types.types.u8,173                        Integer::I16 => ctx.types.types.u16,174                        Integer::I32 => ctx.types.types.u32,175                        Integer::I64 => ctx.types.types.u64,176                        Integer::I128 => ctx.types.types.u128,177                    },178                },179            };180        }181    }182183    ctx.infer_body(body.root_expr());184185    ctx.infer_mut_body(body.root_expr());186187    infer_finalize(ctx)188}189190fn infer_cycle_result<'db>(191    db: &'db dyn HirDatabase,192    _: salsa::Id,193    _: DefWithBodyId,194) -> InferenceResult<'db> {195    InferenceResult {196        has_errors: true,197        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))198    }199}200201/// Infer types for an anonymous const expression.202fn infer_anon_const_query<'db>(203    db: &'db dyn HirDatabase,204    def: AnonConstId<'db>,205) -> InferenceResult<'db> {206    let _p = tracing::info_span!("infer_anon_const_query").entered();207    let loc = def.loc(db);208    let store_owner = loc.owner;209    let store = ExpressionStore::of(db, store_owner);210211    let resolver = store_owner.resolver(db);212213    let mut ctx = InferenceContext::new(214        db,215        InferBodyId::AnonConstId(def),216        store_owner,217        loc.owner.generic_def(db),218        store,219        resolver,220        loc.allow_using_generic_params,221        LoweringMode::Analysis,222    );223224    ctx.infer_expr(225        loc.expr,226        &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),227        ExprIsRead::Yes,228    );229230    infer_finalize(ctx)231}232233fn infer_anon_const_cycle_result<'db>(234    db: &'db dyn HirDatabase,235    _: salsa::Id,236    _: AnonConstId<'db>,237) -> InferenceResult<'db> {238    InferenceResult {239        has_errors: true,240        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))241    }242}243244fn infer_finalize<'db>(mut ctx: InferenceContext<'db>) -> InferenceResult<'db> {245    ctx.handle_opaque_type_uses();246247    ctx.type_inference_fallback();248249    // Comment from rustc:250    // Even though coercion casts provide type hints, we check casts after fallback for251    // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.252    let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);253    for mut cast in cast_checks.into_iter() {254        if let Err(diag) = cast.check(&mut ctx) {255            ctx.diagnostics.push(diag);256        }257    }258259    ctx.table.select_obligations_where_possible();260261    // Closure and coroutine analysis may run after fallback262    // because they don't constrain other type variables.263    ctx.closure_analyze();264    assert!(ctx.deferred_call_resolutions.is_empty());265266    ctx.table.select_obligations_where_possible();267268    ctx.handle_opaque_type_uses();269270    ctx.merge_anon_consts();271272    ctx.resolve_all()273}274275#[derive(Clone, Copy, Debug, Eq, PartialEq)]276pub enum ByRef {277    Yes(Mutability),278    No,279}280281/// The mode of a binding (`mut`, `ref mut`, etc).282/// Used for both the explicit binding annotations given in the HIR for a binding283/// and the final binding mode that we infer after type inference/match ergonomics.284/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),285/// `.1` is the mutability of the binding.286#[derive(Copy, Clone, Debug, Eq, PartialEq)]287pub struct BindingMode(pub ByRef, pub Mutability);288289#[derive(Debug, PartialEq, Eq, Clone, Copy)]290pub enum InferenceTyDiagnosticSource {291    /// Diagnostics that come from types in the body.292    Body,293    /// Diagnostics that come from types in fn parameters/return type, or static & const types.294    Signature,295}296297#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]298pub enum InferenceDiagnostic {299    NoSuchField {300        #[type_visitable(ignore)]301        field: ExprOrPatIdPacked,302        #[type_visitable(ignore)]303        private: Option<LocalFieldId>,304        #[type_visitable(ignore)]305        variant: VariantId,306    },307    MismatchedArrayPatLen {308        #[type_visitable(ignore)]309        pat: PatId,310        #[type_visitable(ignore)]311        expected: u64,312        #[type_visitable(ignore)]313        found: u64,314        #[type_visitable(ignore)]315        has_rest: bool,316    },317    ArrayPatternWithoutFixedLength {318        #[type_visitable(ignore)]319        pat: PatId,320    },321    ExpectedArrayOrSlicePat {322        #[type_visitable(ignore)]323        pat: PatId,324        found: StoredTy,325    },326    InvalidRangePatType {327        #[type_visitable(ignore)]328        pat: PatId,329    },330    DuplicateField {331        #[type_visitable(ignore)]332        field: ExprOrPatIdPacked,333        #[type_visitable(ignore)]334        variant: VariantId,335    },336    PrivateField {337        #[type_visitable(ignore)]338        expr: ExprId,339        #[type_visitable(ignore)]340        field: FieldId,341    },342    PrivateAssocItem {343        #[type_visitable(ignore)]344        id: ExprOrPatIdPacked,345        #[type_visitable(ignore)]346        item: AssocItemId,347    },348    UnresolvedField {349        #[type_visitable(ignore)]350        expr: ExprId,351        receiver: StoredTy,352        #[type_visitable(ignore)]353        name: Name,354        #[type_visitable(ignore)]355        method_with_same_name_exists: bool,356    },357    UnresolvedMethodCall {358        #[type_visitable(ignore)]359        expr: ExprId,360        receiver: StoredTy,361        #[type_visitable(ignore)]362        name: Name,363        /// Contains the type the field resolves to364        field_with_same_name: Option<StoredTy>,365        #[type_visitable(ignore)]366        assoc_func_with_same_name: Option<FunctionId>,367    },368    UnresolvedAssocItem {369        #[type_visitable(ignore)]370        id: ExprOrPatIdPacked,371    },372    UnresolvedIdent {373        #[type_visitable(ignore)]374        id: ExprOrPatIdPacked,375    },376    // FIXME: This should be emitted in body lowering377    BreakOutsideOfLoop {378        #[type_visitable(ignore)]379        expr: ExprId,380        #[type_visitable(ignore)]381        is_break: bool,382        #[type_visitable(ignore)]383        bad_value_break: bool,384    },385    NonExhaustiveRecordExpr {386        #[type_visitable(ignore)]387        expr: ExprId,388    },389    NonExhaustiveRecordPat {390        #[type_visitable(ignore)]391        pat: PatId,392        #[type_visitable(ignore)]393        variant: VariantId,394    },395    UnionPatMustHaveExactlyOneField {396        #[type_visitable(ignore)]397        pat: PatId,398    },399    UnionPatHasRest {400        #[type_visitable(ignore)]401        pat: PatId,402    },403    FunctionalRecordUpdateOnNonStruct {404        #[type_visitable(ignore)]405        base_expr: ExprId,406    },407    MismatchedArgCount {408        #[type_visitable(ignore)]409        call_expr: ExprId,410        #[type_visitable(ignore)]411        expected: usize,412        #[type_visitable(ignore)]413        found: usize,414        /// True when the call goes through the `Fn`/`FnMut`/`FnOnce` trait415        /// (i.e. arguments were bundled into a tuple). Determines whether the416        /// diagnostic surface uses E0057 (Fn-trait call) or E0061 (regular call).417        #[type_visitable(ignore)]418        is_fn_trait_call: bool,419    },420    MismatchedTupleStructPatArgCount {421        #[type_visitable(ignore)]422        pat: PatId,423        #[type_visitable(ignore)]424        expected: usize,425        #[type_visitable(ignore)]426        found: usize,427    },428    ExpectedFunction {429        #[type_visitable(ignore)]430        call_expr: ExprId,431        found: StoredTy,432    },433    CannotBeDereferenced {434        #[type_visitable(ignore)]435        expr: ExprId,436        found: StoredTy,437    },438    MutRefInImmRefPat {439        #[type_visitable(ignore)]440        pat: PatId,441    },442    CannotImplicitlyDerefTraitObject {443        #[type_visitable(ignore)]444        pat: PatId,445        found: StoredTy,446    },447    CannotIndexInto {448        #[type_visitable(ignore)]449        expr: ExprId,450        found: StoredTy,451    },452    TypedHole {453        #[type_visitable(ignore)]454        expr: ExprId,455        expected: StoredTy,456    },457    CastToUnsized {458        #[type_visitable(ignore)]459        expr: ExprId,460        cast_ty: StoredTy,461    },462    InvalidCast {463        #[type_visitable(ignore)]464        expr: ExprId,465        #[type_visitable(ignore)]466        error: CastError,467        expr_ty: StoredTy,468        cast_ty: StoredTy,469    },470    TyDiagnostic {471        #[type_visitable(ignore)]472        source: InferenceTyDiagnosticSource,473        #[type_visitable(ignore)]474        diag: TyLoweringDiagnostic,475    },476    PathDiagnostic {477        #[type_visitable(ignore)]478        node: ExprOrPatIdPacked,479        #[type_visitable(ignore)]480        diag: PathLoweringDiagnostic,481    },482    MethodCallIncorrectGenericsLen {483        #[type_visitable(ignore)]484        expr: ExprId,485        #[type_visitable(ignore)]486        provided_count: u32,487        #[type_visitable(ignore)]488        expected_count: u32,489        #[type_visitable(ignore)]490        kind: IncorrectGenericsLenKind,491        #[type_visitable(ignore)]492        def: GenericDefId,493    },494    MethodCallIllegalSizedBound {495        #[type_visitable(ignore)]496        call_expr: ExprId,497    },498    MethodCallIncorrectGenericsOrder {499        #[type_visitable(ignore)]500        expr: ExprId,501        #[type_visitable(ignore)]502        param_id: GenericParamId,503        #[type_visitable(ignore)]504        arg_idx: u32,505        /// Whether the `GenericArgs` contains a `Self` arg.506        #[type_visitable(ignore)]507        has_self_arg: bool,508    },509    InvalidLhsOfAssignment {510        #[type_visitable(ignore)]511        lhs: ExprId,512    },513    TypeMustBeKnown {514        #[type_visitable(ignore)]515        at_point: Span,516        top_term: Option<StoredGenericArg>,517    },518    UnionExprMustHaveExactlyOneField {519        #[type_visitable(ignore)]520        expr: ExprId,521    },522    TypeMismatch {523        #[type_visitable(ignore)]524        node: ExprOrPatIdPacked,525        expected: StoredTy,526        found: StoredTy,527    },528    SolverDiagnostic(SolverDiagnostic),529    ExplicitDropMethodUse {530        #[type_visitable(ignore)]531        kind: ExplicitDropMethodUseKind,532    },533    MutableRefBinding {534        #[type_visitable(ignore)]535        pat: PatId,536    },537    YieldOutsideCoroutine {538        #[type_visitable(ignore)]539        expr: ExprId,540    },541    ReturnOutsideFunction {542        #[type_visitable(ignore)]543        expr: ExprId,544        #[type_visitable(ignore)]545        kind: ReturnKind,546    },547    RecordMissingFields {548        #[type_visitable(ignore)]549        record: ExprOrPatId,550        #[type_visitable(ignore)]551        variant: VariantId,552        #[type_visitable(ignore)]553        missed_fields: Vec<LocalFieldId>,554    },555}556557#[derive(Debug, PartialEq, Eq, Clone, Copy)]558pub enum ReturnKind {559    ReturnExpr,560    BecomeExpr,561}562563#[derive(Debug, PartialEq, Eq, Clone)]564pub enum ExplicitDropMethodUseKind {565    MethodCall(ExprId),566    Path(ExprOrPatIdPacked),567}568569/// Represents coercing a value to a different type of value.570///571/// We transform values by following a number of `Adjust` steps in order.572/// See the documentation on variants of `Adjust` for more details.573///574/// Here are some common scenarios:575///576/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.577///    Here the pointer will be dereferenced N times (where a dereference can578///    happen to raw or borrowed pointers or any smart pointer which implements579///    Deref, including Box<_>). The types of dereferences is given by580///    `autoderefs`. It can then be auto-referenced zero or one times, indicated581///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is582///    `false`.583///584/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start585///    with a thin pointer, deref a number of times, unsize the underlying data,586///    then autoref. The 'unsize' phase may change a fixed length array to a587///    dynamically sized one, a concrete object to a trait object, or statically588///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is589///    represented by:590///591///    ```ignore592///    Deref(None) -> [i32; 4],593///    Borrow(AutoBorrow::Ref) -> &[i32; 4],594///    Unsize -> &[i32],595///    ```596///597///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.598///    E.g., `struct Foo<T> { it: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>599///    The autoderef and -ref are the same as in the above example, but the type600///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about601///    the underlying conversions from `[i32; 4]` to `[i32]`.602///603/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In604///    that case, we have the pointer we need coming in, so there are no605///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.606///    At some point, of course, `Box` should move out of the compiler, in which607///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->608///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.609#[derive(Clone, Debug, PartialEq, Eq, Hash)]610pub struct Adjustment {611    pub kind: Adjust,612    pub target: StoredTy,613}614615impl Adjustment {616    pub fn borrow<'db>(617        interner: DbInterner<'db>,618        m: Mutability,619        ty: Ty<'db>,620        lt: Region<'db>,621    ) -> Self {622        let ty = Ty::new_ref(interner, lt, ty, m);623        Adjustment {624            kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),625            target: ty.store(),626        }627    }628}629630/// At least for initial deployment, we want to limit two-phase borrows to631/// only a few specific cases. Right now, those are mostly "things that desugar"632/// into method calls:633/// - using `x.some_method()` syntax, where some_method takes `&mut self`,634/// - using `Foo::some_method(&mut x, ...)` syntax,635/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).636///637/// Anything else should be rejected until generalized two-phase borrow support638/// is implemented. Right now, dataflow can't handle the general case where there639/// is more than one use of a mutable borrow, and we don't want to accept too much640/// new code via two-phase borrows, so we try to limit where we create two-phase641/// capable mutable borrows.642/// See #49434 for tracking.643#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]644pub enum AllowTwoPhase {645    // FIXME: We should use this when appropriate.646    Yes,647    No,648}649650#[derive(Clone, Debug, PartialEq, Eq, Hash)]651pub enum Adjust {652    /// Go from ! to any type.653    NeverToAny,654    /// Dereference once, producing a place.655    Deref(Option<OverloadedDeref>),656    /// Take the address and produce either a `&` or `*` pointer.657    Borrow(AutoBorrow),658    Pointer(PointerCast),659}660661/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`662/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.663/// The target type is `U` in both cases, with the region and mutability664/// being those shared by both the receiver and the returned reference.665#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]666pub struct OverloadedDeref(pub Mutability);667668#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]669pub enum AutoBorrowMutability {670    Mut { allow_two_phase_borrow: AllowTwoPhase },671    Not,672}673674impl AutoBorrowMutability {675    /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows.676    ///677    /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored678    pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {679        match mutbl {680            Mutability::Not => Self::Not,681            Mutability::Mut => Self::Mut { allow_two_phase_borrow },682        }683    }684}685686impl From<AutoBorrowMutability> for Mutability {687    fn from(m: AutoBorrowMutability) -> Self {688        match m {689            AutoBorrowMutability::Mut { .. } => Mutability::Mut,690            AutoBorrowMutability::Not => Mutability::Not,691        }692    }693}694695#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]696pub enum AutoBorrow {697    /// Converts from T to &T.698    Ref(AutoBorrowMutability),699    /// Converts from T to *T.700    RawPtr(Mutability),701}702703#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]704pub enum PointerCast {705    /// Go from a fn-item type to a fn-pointer type.706    ReifyFnPointer,707708    /// Go from a safe fn pointer to an unsafe fn pointer.709    UnsafeFnPointer,710711    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.712    /// It cannot convert a closure that requires unsafe.713    ClosureFnPointer(Safety),714715    /// Go from a mut raw pointer to a const raw pointer.716    MutToConstPointer,717718    #[allow(dead_code)]719    /// Go from `*const [T; N]` to `*const T`720    ArrayToPointer,721722    /// Unsize a pointer/reference value, e.g., `&[T; n]` to723    /// `&[T]`. Note that the source could be a thin or fat pointer.724    /// This will do things like convert thin pointers to fat725    /// pointers, or convert structs containing thin pointers to726    /// structs containing fat pointers, or convert between fat727    /// pointers. We don't store the details of how the transform is728    /// done (in fact, we don't know that, because it might depend on729    /// the precise type parameters). We just store the target730    /// type. Codegen backends and miri figure out what has to be done731    /// based on the precise source/target type at hand.732    Unsize,733}734735/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern736/// against it. Currently, this is used only for implicit dereferences.737#[derive(Debug, Clone, PartialEq, Eq)]738pub struct PatAdjustment {739    pub kind: PatAdjust,740    /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the741    /// pattern.742    pub source: StoredTy,743}744745/// Represents implicit coercions of patterns' types, rather than values' types.746#[derive(Clone, Copy, PartialEq, Eq, Debug)]747pub enum PatAdjust {748    /// An implicit dereference before matching, such as when matching the pattern `0` against a749    /// scrutinee of type `&u8` or `&mut u8`.750    BuiltinDeref,751    /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the752    /// pattern `[..]` against a scrutinee of type `Vec<T>`.753    OverloadedDeref,754}755756/// The result of type inference: A mapping from expressions and patterns to types.757///758/// When you add a field that stores types (including `Substitution` and the like), don't forget759/// `resolve_completely()`'ing  them in `InferenceContext::resolve_all()`. Inference variables must760/// not appear in the final inference result.761#[derive(Clone, PartialEq, Eq, Debug, SalsaValue)]762pub struct InferenceResult<'db> {763    /// For each method call expr, records the function it resolves to.764    method_resolutions: FxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,765    /// For each field access expr, records the field it resolves to.766    field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,767    /// For each struct literal or pattern, records the variant it resolves to.768    variant_resolutions: FxHashMap<ExprOrPatIdPacked, VariantId>,769    /// For each associated item record what it resolves to770    assoc_resolutions: FxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>,771    /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in772    /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of773    /// that which allows us to resolve a [`TupleFieldId`]s type.774    tuple_field_access_types: ThinVec<StoredTys>,775776    pub(crate) type_of_expr: ArenaMap<ExprId, StoredTy>,777    /// For each pattern record the type it resolves to.778    ///779    /// **Note**: When a pattern type is resolved it may still contain780    /// unresolved or missing subpatterns or subpatterns of mismatched types.781    pub(crate) type_of_pat: ArenaMap<PatId, StoredTy>,782    pub(crate) type_of_binding: ArenaMap<BindingId, StoredTy>,783    pub(crate) type_of_type_placeholder: FxHashMap<TypeRefId, StoredTy>,784    pub(crate) type_of_opaque: FxHashMap<InternedOpaqueTyId<'db>, StoredTy>,785786    /// Whether there are any type-mismatching errors in the result.787    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to788    // `TyKind::Error`.789    // Which will then mark this field.790    pub(crate) has_errors: bool,791    /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.792    diagnostics: ThinVec<InferenceDiagnostic>,793    // FIXME: Remove this, change it to be in `InferenceContext`:794    nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatIdPacked>>>,795796    /// Interned `Error` type to return references to.797    // FIXME: Remove this.798    error_ty: StoredTy,799800    pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,801    /// Stores the types which were implicitly dereferenced in pattern binding modes.802    pub(crate) pat_adjustments: FxHashMap<PatId, Vec<PatAdjustment>>,803    /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.804    ///805    /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an806    /// or pattern can have multiple binding modes. For example:807    /// ```808    /// fn foo(mut slice: &[u32]) -> usize {809    ///     slice = match slice {810    ///         [0, rest @ ..] | rest => rest,811    ///     };812    ///     0813    /// }814    /// ```815    /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.816    pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,817818    /// Set of reference patterns that match against a match-ergonomics inserted reference819    /// (as opposed to against a reference in the scrutinee type).820    skipped_ref_pats: FxHashSet<PatId>,821822    pub(crate) coercion_casts: FxHashSet<ExprId>,823824    pub closures_data: FxHashMap<ExprId, ClosureData>,825826    defined_anon_consts: ThinVec<AnonConstId<'db>>,827}828829#[derive(Clone, PartialEq, Eq, Debug)]830pub struct ClosureData {831    /// Tracks the minimum captures required for a closure;832    /// see `MinCaptureInformationMap` for more details.833    pub min_captures: RootVariableMinCaptureList,834835    /// Tracks the fake reads required for a closure and the reason for the fake read.836    /// When performing pattern matching for closures, there are times we don't end up837    /// reading places that are mentioned in a closure (because of _ patterns). However,838    /// to ensure the places are initialized, we introduce fake reads.839    /// Consider these two examples:840    /// ```ignore (discriminant matching with only wildcard arm)841    /// let x: u8;842    /// let c = || match x { _ => () };843    /// ```844    /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't845    /// want to capture it. However, we do still want an error here, because `x` should have846    /// to be initialized at the point where c is created. Therefore, we add a "fake read"847    /// instead.848    /// ```ignore (destructured assignments)849    /// let c = || {850    ///     let (t1, t2) = t;851    /// }852    /// ```853    /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but854    /// we never capture `t`. This becomes an issue when we build MIR as we require855    /// information on `t` in order to create place `t.0` and `t.1`. We can solve this856    /// issue by fake reading `t`.857    pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,858859    /// For each fn, records the "liberated" types of its arguments860    /// and return type. Liberated means that all bound regions861    /// (including late-bound regions) are replaced with free862    /// equivalents. This table is not used in codegen (since regions863    /// are erased there) and hence is not serialized to metadata.864    ///865    /// This table also contains the "revealed" values for any `impl Trait`866    /// that appear in the signature and whose values are being inferred867    /// by this function.868    ///869    /// # Example870    ///871    /// ```rust872    /// # use std::fmt::Debug;873    /// fn foo(x: &u32) -> impl Debug { *x }874    /// ```875    ///876    /// The function signature here would be:877    ///878    /// ```ignore (illustrative)879    /// for<'a> fn(&'a u32) -> Foo880    /// ```881    ///882    /// where `Foo` is an opaque type created for this function.883    ///884    ///885    /// The *liberated* form of this would be886    ///887    /// ```ignore (illustrative)888    /// fn(&'a u32) -> u32889    /// ```890    ///891    /// Note that `'a` is not bound (it would be an `ReLateParam`) and892    /// that the `Foo` opaque type is replaced by its hidden type.893    pub liberated_sig: StoredFnSig,894}895896/// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`.897/// Used to track the minimum set of `Place`s that need to be captured to support all898/// Places captured by the closure starting at a given root variable.899///900/// This provides a convenient and quick way of checking if a variable being used within901/// a closure is a capture of a local variable.902pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;903904/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.905pub(crate) type MinCaptureList = Vec<CapturedPlace>;906907/// A composite describing a `Place` that is captured by a closure.908#[derive(Eq, PartialEq, Clone, Debug, Hash)]909pub struct CapturedPlace {910    /// The `Place` that is captured.911    pub place: Place,912913    /// `CaptureKind` and expression(s) that resulted in such capture of `place`.914    pub info: CaptureInfo,915916    /// Represents if `place` can be mutated or not.917    pub mutability: Mutability,918}919920impl CapturedPlace {921    pub fn is_by_ref(&self) -> bool {922        match self.info.capture_kind {923            UpvarCapture::ByValue | UpvarCapture::ByUse => false,924            UpvarCapture::ByRef(..) => true,925        }926    }927928    pub fn captured_local(&self) -> BindingId {929        match self.place.base {930            PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,931            PlaceBase::Rvalue | PlaceBase::StaticItem => {932                unreachable!("only locals can be captured")933            }934        }935    }936937    /// The type of the capture stored in the closure, which is different from the type of the captured place938    /// if we capture by reference.939    pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {940        let place_ty = self.place.ty();941        let make_ref = |mutbl| {942            let interner = DbInterner::new_no_crate(db);943            let region = Region::new_erased(interner);944            Ty::new_ref(interner, region, place_ty, mutbl)945        };946        match self.info.capture_kind {947            UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,948            UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),949        }950    }951}952953#[derive(Clone)]954pub struct CaptureSourceStack(CaptureSourceStackRepr);955956#[derive(Clone)]957enum CaptureSourceStackRepr {958    One(ExprOrPatIdPacked),959    Two([ExprOrPatIdPacked; 2]),960    Many(ThinVec<ExprOrPatIdPacked>),961}962963impl PartialEq for CaptureSourceStack {964    fn eq(&self, other: &Self) -> bool {965        **self == **other966    }967}968969impl Eq for CaptureSourceStack {}970971impl std::hash::Hash for CaptureSourceStack {972    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {973        (**self).hash(state);974    }975}976977#[cfg(target_pointer_width = "64")]978const _: () = assert!(size_of::<CaptureSourceStack>() == 16);979980impl Deref for CaptureSourceStack {981    type Target = [ExprOrPatIdPacked];982983    #[inline]984    fn deref(&self) -> &Self::Target {985        match &self.0 {986            CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),987            CaptureSourceStackRepr::Two(it) => it,988            CaptureSourceStackRepr::Many(it) => it,989        }990    }991}992993impl fmt::Debug for CaptureSourceStack {994    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {995        f.debug_tuple("CaptureSourceStack").field(&&**self).finish()996    }997}998999impl CaptureSourceStack {1000    #[inline]1001    pub fn len(&self) -> usize {1002        match &self.0 {1003            CaptureSourceStackRepr::One(_) => 1,1004            CaptureSourceStackRepr::Two(_) => 2,1005            CaptureSourceStackRepr::Many(it) => it.len(),1006        }1007    }10081009    #[inline]1010    pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self {1011        Self(CaptureSourceStackRepr::One(id))1012    }10131014    #[inline]1015    pub fn final_source(&self) -> ExprOrPatIdPacked {1016        *self.last().expect("should always have a final source")1017    }10181019    pub fn push(&mut self, new_id: ExprOrPatIdPacked) {1020        match &mut self.0 {1021            CaptureSourceStackRepr::One(old_id) => {1022                self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])1023            }1024            CaptureSourceStackRepr::Two([old_id1, old_id2]) => {1025                self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));1026            }1027            CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),1028        }1029    }10301031    pub fn truncate(&mut self, new_len: usize) {1032        debug_assert!(new_len > 0);1033        match &mut self.0 {1034            CaptureSourceStackRepr::One(_) => {}1035            CaptureSourceStackRepr::Two([first, _]) => {1036                if new_len == 1 {1037                    self.0 = CaptureSourceStackRepr::One(*first)1038                }1039            }1040            CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),1041        }1042    }10431044    pub fn shrink_to_fit(&mut self) {1045        match &mut self.0 {1046            CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}1047            CaptureSourceStackRepr::Many(ids) => match **ids {1048                [one] => self.0 = CaptureSourceStackRepr::One(one),1049                [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),1050                _ => ids.shrink_to_fit(),1051            },1052        }1053    }1054}10551056/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)1057/// for a particular capture as well as identifying the part of the source code1058/// that triggered this capture to occur.1059#[derive(Eq, PartialEq, Clone, Debug, Hash)]1060pub struct CaptureInfo {1061    pub sources: SmallVec<[CaptureSourceStack; 2]>,10621063    /// Capture mode that was selected1064    pub capture_kind: UpvarCapture,1065}10661067/// Information describing the capture of an upvar. This is computed1068/// during `typeck`, specifically by `regionck`.1069#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]1070pub enum UpvarCapture {1071    /// Upvar is captured by value. This is always true when the1072    /// closure is labeled `move`, but can also be true in other cases1073    /// depending on inference.1074    ByValue,10751076    /// Upvar is captured by use. This is true when the closure is labeled `use`.1077    ByUse,10781079    /// Upvar is captured by reference.1080    ByRef(BorrowKind),1081}10821083#[salsa::tracked]1084impl<'db> InferenceResult<'db> {1085    #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]1086    fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {1087        infer_query(db, def)1088    }10891090    /// Infer types for all const expressions in an item's signature.1091    ///1092    /// Returns an `InferenceResult` containing type information for array lengths,1093    /// const generic arguments, and other const expressions appearing in type1094    /// positions within the item's signature.1095    #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]1096    fn for_anon_const(db: &'db dyn HirDatabase, def: AnonConstId<'db>) -> InferenceResult<'db> {1097        infer_anon_const_query(db, def)1098    }1099}11001101impl<'db> InferenceResult<'db> {1102    #[inline]1103    pub fn of(1104        db: &'db dyn HirDatabase,1105        def: impl Into<InferBodyId<'db>>,1106    ) -> &'db InferenceResult<'db> {1107        match def.into() {1108            InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),1109            InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),1110        }1111    }1112}11131114impl<'db> InferenceResult<'db> {1115    fn new(error_ty: Ty<'_>) -> Self {1116        Self {1117            method_resolutions: Default::default(),1118            field_resolutions: Default::default(),1119            variant_resolutions: Default::default(),1120            assoc_resolutions: Default::default(),1121            tuple_field_access_types: Default::default(),1122            diagnostics: Default::default(),1123            nodes_with_type_mismatches: Default::default(),1124            type_of_expr: Default::default(),1125            type_of_pat: Default::default(),1126            type_of_binding: Default::default(),1127            type_of_type_placeholder: Default::default(),1128            type_of_opaque: Default::default(),1129            skipped_ref_pats: Default::default(),1130            has_errors: Default::default(),1131            error_ty: error_ty.store(),1132            pat_adjustments: Default::default(),1133            binding_modes: Default::default(),1134            expr_adjustments: Default::default(),1135            coercion_casts: Default::default(),1136            closures_data: Default::default(),1137            defined_anon_consts: Default::default(),1138        }1139    }11401141    pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {1142        self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))1143    }1144    pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {1145        self.field_resolutions.get(&expr).copied()1146    }1147    pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {1148        self.variant_resolutions.get(&id.into()).copied()1149    }1150    pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {1151        self.variant_resolutions.get(&id.into()).copied()1152    }1153    pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {1154        match id {1155            ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),1156            ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),1157        }1158    }1159    pub fn assoc_resolutions_for_expr<'a>(1160        &self,1161        id: ExprId,1162    ) -> Option<(CandidateId, GenericArgs<'a>)> {1163        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1164    }1165    pub fn assoc_resolutions_for_pat<'a>(1166        &self,1167        id: PatId,1168    ) -> Option<(CandidateId, GenericArgs<'a>)> {1169        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1170    }1171    pub fn assoc_resolutions_for_expr_or_pat<'a>(1172        &self,1173        id: ExprOrPatId,1174    ) -> Option<(CandidateId, GenericArgs<'a>)> {1175        match id {1176            ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),1177            ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),1178        }1179    }1180    pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool {1181        self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node))1182    }1183    pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {1184        self.expr_or_pat_has_type_mismatch(expr.into())1185    }1186    pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {1187        self.expr_or_pat_has_type_mismatch(pat.into())1188    }1189    pub fn exprs_have_type_mismatches(&self) -> bool {1190        self.nodes_with_type_mismatches1191            .as_ref()1192            .is_some_and(|it| it.iter().any(|node| node.is_expr()))1193    }1194    pub fn has_type_mismatches(&self) -> bool {1195        self.nodes_with_type_mismatches.is_some()1196    }1197    pub fn placeholder_types<'a>(&self) -> impl Iterator<Item = (TypeRefId, Ty<'a>)> {1198        self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref()))1199    }1200    pub fn type_of_type_placeholder<'a>(&self, type_ref: TypeRefId) -> Option<Ty<'a>> {1201        self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref())1202    }1203    pub fn type_of_expr_or_pat<'a>(&self, id: ExprOrPatId) -> Option<Ty<'a>> {1204        match id {1205            ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()),1206            ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()),1207        }1208    }1209    pub fn type_of_expr_with_adjust<'a>(&self, id: ExprId) -> Option<Ty<'a>> {1210        match self.expr_adjustments.get(&id).and_then(|adjustments| {1211            adjustments.iter().rfind(|adj| {1212                // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L1401213                !matches!(1214                    adj,1215                    Adjustment {1216                        kind: Adjust::NeverToAny,1217                        target,1218                    } if target.as_ref().is_never()1219                )1220            })1221        }) {1222            Some(adjustment) => Some(adjustment.target.as_ref()),1223            None => self.type_of_expr.get(id).map(|it| it.as_ref()),1224        }1225    }1226    pub fn type_of_pat_with_adjust<'a>(&self, id: PatId) -> Ty<'a> {1227        match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {1228            Some(adjusted) => adjusted.source.as_ref(),1229            None => self.pat_ty(id),1230        }1231    }1232    pub fn is_erroneous(&self) -> bool {1233        self.has_errors && self.type_of_expr.iter().count() == 01234    }12351236    pub fn diagnostics(&self) -> &[InferenceDiagnostic] {1237        &self.diagnostics1238    }12391240    pub fn tuple_field_access_type<'a>(&self, id: TupleId) -> Tys<'a> {1241        self.tuple_field_access_types[id.0 as usize].as_ref()1242    }12431244    pub fn pat_adjustment(&self, id: PatId) -> Option<&[PatAdjustment]> {1245        self.pat_adjustments.get(&id).map(|it| &**it)1246    }12471248    pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {1249        self.expr_adjustments.get(&id).map(|it| &**it)1250    }12511252    pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {1253        self.binding_modes.get(id).copied()1254    }12551256    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1257    pub fn expression_types<'a>(&self) -> impl Iterator<Item = (ExprId, Ty<'a>)> {1258        self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref()))1259    }12601261    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1262    pub fn pattern_types<'a>(&self) -> impl Iterator<Item = (PatId, Ty<'a>)> {1263        self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref()))1264    }12651266    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1267    pub fn binding_types<'a>(&self) -> impl Iterator<Item = (BindingId, Ty<'a>)> {1268        self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref()))1269    }12701271    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1272    pub fn return_position_impl_trait_types<'a>(1273        &'a self,1274        db: &'a dyn HirDatabase,1275    ) -> impl Iterator<Item = (ImplTraitIdx, Ty<'a>)> {1276        self.type_of_opaque.iter().filter_map(move |(&id, ty)| {1277            let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {1278                return None;1279            };1280            Some((rpit_idx, ty.as_ref()))1281        })1282    }12831284    pub fn expr_ty<'a>(&self, id: ExprId) -> Ty<'a> {1285        self.type_of_expr.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1286    }12871288    pub fn pat_ty<'a>(&self, id: PatId) -> Ty<'a> {1289        self.type_of_pat.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1290    }12911292    pub fn expr_or_pat_ty<'a>(&self, id: ExprOrPatId) -> Ty<'a> {1293        self.type_of_expr_or_pat(id).unwrap_or(self.error_ty.as_ref())1294    }12951296    pub fn binding_ty<'a>(&self, id: BindingId) -> Ty<'a> {1297        self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1298    }12991300    /// This does not deduplicate, which means you'll get the types once per capture.1301    pub fn closure_captures_tys<'a>(&self, closure: ExprId) -> impl Iterator<Item = Ty<'a>> {1302        self.closures_data[&closure]1303            .min_captures1304            .values()1305            .flat_map(|captures| captures.iter().map(|capture| capture.place.ty()))1306    }13071308    /// Like [`Self::closure_captures_tys()`], but using [`CapturedPlace::captured_ty()`].1309    pub fn closure_captures_captured_tys<'a>(1310        &self,1311        db: &'a dyn HirDatabase,1312        closure: ExprId,1313    ) -> impl Iterator<Item = Ty<'a>> {1314        self.closures_data[&closure]1315            .min_captures1316            .values()1317            .flat_map(|captures| captures.iter().map(|capture| capture.captured_ty(db)))1318    }13191320    pub fn is_skipped_ref_pat(&self, pat: PatId) -> bool {1321        self.skipped_ref_pats.contains(&pat)1322    }1323}13241325#[derive(Debug, Clone, Copy)]1326enum DerefPatBorrowMode {1327    Borrow(Mutability),1328    Box,1329}13301331/// The inference context contains all information needed during type inference.1332#[derive(Debug)]1333pub(crate) struct InferenceContext<'db> {1334    pub(crate) db: &'db dyn HirDatabase,1335    pub(crate) owner: InferBodyId<'db>,1336    pub(crate) store_owner: ExpressionStoreOwnerId,1337    pub(crate) generic_def: GenericDefId,1338    pub(crate) store: &'db ExpressionStore,1339    pub(crate) lowering_mode: LoweringMode,1340    /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext1341    /// and resolve the path via its methods. This will ensure proper error reporting.1342    pub(crate) resolver: Resolver<'db>,1343    target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,1344    data_layout: OnceCell<&'db TargetDataLayout>,1345    pub(crate) edition: Edition,1346    allow_using_generic_params: bool,1347    generics: OnceCell<Generics<'db>>,1348    identity_args: OnceCell<GenericArgs<'db>>,1349    pub(crate) table: unify::InferenceTable<'db>,1350    pub(crate) lang_items: &'db LangItems,1351    pub(crate) features: &'db UnstableFeatures,1352    /// The traits in scope, disregarding block modules. This is used for caching purposes.1353    traits_in_scope: FxHashSet<TraitId>,1354    pub(crate) result: InferenceResult<'db>,1355    tuple_field_accesses_rev:1356        IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,1357    /// The return type of the function being inferred, the closure or async block if we're1358    /// currently within one.1359    ///1360    /// We might consider using a nested inference context for checking1361    /// closures so we can swap all shared things out at once.1362    return_ty: Ty<'db>,1363    /// If `Some`, this stores coercion information for returned1364    /// expressions. If `None`, this is in a context where return is1365    /// inappropriate, such as a const expression.1366    return_coercion: Option<DynamicCoerceMany<'db>>,1367    /// The resume type and the yield type, respectively, of the coroutine being inferred.1368    resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,1369    diverges: Diverges,1370    breakables: Vec<BreakableContext<'db>>,1371    types: &'db crate::next_solver::DefaultAny<'db>,13721373    deferred_cast_checks: Vec<CastCheck<'db>>,13741375    /// The key is an expression defining a closure or a coroutine closure.1376    deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>,13771378    diagnostics: Diagnostics,1379    vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>,13801381    defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>,1382}13831384#[derive(Clone, Debug)]1385struct BreakableContext<'db> {1386    /// Whether this context contains at least one break expression.1387    may_break: bool,1388    /// The coercion target of the context.1389    coerce: Option<DynamicCoerceMany<'db>>,1390    /// The optional label of the context.1391    label: Option<LabelId>,1392    kind: BreakableKind,1393}13941395#[derive(Clone, Debug)]1396enum BreakableKind {1397    Block,1398    Loop,1399    /// A border is something like an async block, closure etc. Anything that prevents1400    /// breaking/continuing through1401    Border,1402}14031404fn find_breakable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {1405    let mut ctxs = ctxs1406        .iter()1407        .enumerate()1408        .rev()1409        .take_while(|(_, it)| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));1410    let result = match label {1411        Some(_) => ctxs.find(|(_, ctx)| ctx.label == label),1412        None => ctxs.find(|(_, ctx)| matches!(ctx.kind, BreakableKind::Loop)),1413    };1414    result.map(|(idx, _)| idx)1415}14161417fn find_continuable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {1418    find_breakable(ctxs, label)1419        .filter(|&idx| label.is_none() || matches!(ctxs[idx].kind, BreakableKind::Loop))1420}14211422impl<'db> InferenceContext<'db> {1423    fn new(1424        db: &'db dyn HirDatabase,1425        owner: InferBodyId<'db>,1426        store_owner: ExpressionStoreOwnerId,1427        generic_def: GenericDefId,1428        store: &'db ExpressionStore,1429        resolver: Resolver<'db>,1430        allow_using_generic_params: bool,1431        lowering_mode: LoweringMode,1432    ) -> Self {1433        let trait_env = db.trait_environment(generic_def);1434        let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), owner);1435        let types = crate::next_solver::default_types(db);1436        InferenceContext {1437            result: InferenceResult::new(types.types.error),1438            return_ty: types.types.error, // set in collect_* calls1439            types,1440            target_features: OnceCell::new(),1441            data_layout: OnceCell::new(),1442            lang_items: table.interner().lang_items(),1443            features: resolver.top_level_def_map().features(),1444            edition: resolver.krate().data(db).edition,1445            table,1446            tuple_field_accesses_rev: Default::default(),1447            resume_yield_tys: None,1448            return_coercion: None,1449            db,1450            owner,1451            store_owner,1452            generic_def,1453            allow_using_generic_params,1454            generics: OnceCell::new(),1455            identity_args: OnceCell::new(),1456            store,1457            traits_in_scope: resolver.traits_in_scope(db),1458            resolver,1459            diverges: Diverges::Maybe,1460            breakables: Vec::new(),1461            deferred_cast_checks: Vec::new(),1462            diagnostics: Diagnostics::default(),1463            vars_emitted_type_must_be_known_for: FxHashSet::default(),1464            deferred_call_resolutions: FxHashMap::default(),1465            defined_anon_consts: RefCell::new(ThinVec::new()),1466            lowering_mode,1467        }1468    }14691470    fn merge(&mut self, other: &InferenceResult<'db>) {1471        let InferenceResult {1472            method_resolutions,1473            field_resolutions,1474            variant_resolutions,1475            assoc_resolutions,1476            tuple_field_access_types: _,1477            type_of_expr,1478            type_of_pat,1479            type_of_binding,1480            type_of_type_placeholder,1481            type_of_opaque,1482            has_errors: _,1483            diagnostics: _,1484            error_ty: _,1485            expr_adjustments,1486            pat_adjustments,1487            binding_modes,1488            skipped_ref_pats,1489            coercion_casts,1490            closures_data,1491            nodes_with_type_mismatches,1492            defined_anon_consts: _,1493        } = &mut self.result;1494        merge_hash_maps(method_resolutions, &other.method_resolutions);1495        merge_hash_maps(variant_resolutions, &other.variant_resolutions);1496        merge_hash_maps(assoc_resolutions, &other.assoc_resolutions);1497        field_resolutions.extend(other.field_resolutions.iter().map(1498            |(&field_expr, &field_resolution)| {1499                let mut field_resolution = field_resolution;1500                if let Either::Right(tuple_field) = &mut field_resolution {1501                    let tys = other.tuple_field_access_type(tuple_field.tuple);1502                    tuple_field.tuple =1503                        TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);1504                };1505                (field_expr, field_resolution)1506            },1507        ));1508        merge_arena_maps(type_of_expr, &other.type_of_expr);1509        merge_arena_maps(type_of_pat, &other.type_of_pat);1510        merge_arena_maps(type_of_binding, &other.type_of_binding);1511        merge_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);1512        merge_hash_maps(type_of_opaque, &other.type_of_opaque);1513        merge_hash_maps(expr_adjustments, &other.expr_adjustments);1514        merge_hash_maps(pat_adjustments, &other.pat_adjustments);1515        merge_arena_maps(binding_modes, &other.binding_modes);1516        merge_hash_set(skipped_ref_pats, &other.skipped_ref_pats);1517        merge_hash_set(coercion_casts, &other.coercion_casts);1518        merge_hash_maps(closures_data, &other.closures_data);1519        if let Some(other_nodes_with_type_mismatches) = &other.nodes_with_type_mismatches {1520            merge_hash_set(1521                nodes_with_type_mismatches.get_or_insert_default(),1522                other_nodes_with_type_mismatches,1523            );1524        }1525        self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());15261527        fn merge_hash_set<T: Hash + Eq + Clone>(dest: &mut FxHashSet<T>, source: &FxHashSet<T>) {1528            dest.extend(source.iter().cloned());1529        }15301531        #[cfg_attr(debug_assertions, track_caller)]1532        fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(1533            dest: &mut FxHashMap<K, V>,1534            source: &FxHashMap<K, V>,1535        ) {1536            if cfg!(debug_assertions) {1537                for (key, src) in source {1538                    assert!(dest.get(key).is_none_or(|dst| dst == src));1539                }1540            }15411542            dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));1543        }15441545        #[cfg_attr(debug_assertions, track_caller)]1546        fn merge_arena_maps<K, V: Clone + PartialEq>(1547            dest: &mut ArenaMap<la_arena::Idx<K>, V>,1548            source: &ArenaMap<la_arena::Idx<K>, V>,1549        ) {1550            if cfg!(debug_assertions) {1551                for (key, src) in source.iter() {1552                    assert!(dest.get(key).is_none_or(|dst| dst == src));1553                }1554            }15551556            dest.extend(source.iter().map(|(k, v)| (k, v.clone())));1557        }1558    }15591560    #[inline]1561    fn krate(&self) -> Crate {1562        self.resolver.krate()1563    }15641565    fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {1566        let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {1567            let target_features = match self.store_owner {1568                ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {1569                    TargetFeatures::from_fn(self.db, id)1570                }1571                _ => TargetFeatures::default(),1572            };1573            let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {1574                Ok(target) => crate::utils::target_feature_is_safe_in_target(target),1575                Err(_) => TargetFeatureIsSafeInTarget::No,1576            };1577            (target_features, target_feature_is_safe)1578        });1579        (target_features, *target_feature_is_safe)1580    }15811582    fn data_layout(&self) -> &'db TargetDataLayout {1583        self.data_layout.get_or_init(|| self.db.target_data_layout_or_default(self.krate()))1584    }15851586    /// How should a deref pattern find the place for its inner pattern to match on?1587    ///1588    /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner1589    /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.1590    /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;1591    /// in this case, we return `DerefPatBorrowMode::Box`.1592    fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {1593        if pointer_ty.is_box() {1594            DerefPatBorrowMode::Box1595        } else {1596            let mutability =1597                if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };1598            DerefPatBorrowMode::Borrow(mutability)1599        }1600    }16011602    #[inline]1603    fn set_tainted_by_errors(&mut self) {1604        self.result.has_errors = true;1605    }16061607    /// Copy the inference of defined anon consts to ourselves, so that we don't need to lookup the defining1608    /// anon const when looking the type of something.1609    fn merge_anon_consts(&mut self) {1610        let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());1611        defined_anon_consts.retain(|&konst| {1612            if konst.loc(self.db).owner != self.store_owner {1613                // This comes from the signature, we don't define it.1614                return false;1615            }16161617            let const_infer = InferenceResult::of(self.db, konst);1618            self.merge(const_infer);1619            true1620        });1621        // Caution, other defined anon consts might have been added by `merge()`!1622        self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);1623    }16241625    // FIXME: This function should be private in module. It is currently only used in the consteval, since we need1626    // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you1627    // used this function for another workaround, mention it here. If you really need this function and believe that1628    // there is no problem in it being `pub(crate)`, remove this comment.1629    fn resolve_all(self) -> InferenceResult<'db> {1630        let InferenceContext {1631            table,1632            mut result,1633            tuple_field_accesses_rev,1634            diagnostics,1635            types,1636            vars_emitted_type_must_be_known_for,1637            ..1638        } = self;1639        let diagnostics = diagnostics.finish();1640        // Destructure every single field so whenever new fields are added to `InferenceResult` we1641        // don't forget to handle them here.1642        let InferenceResult {1643            method_resolutions,1644            field_resolutions: _,1645            variant_resolutions: _,1646            assoc_resolutions,1647            type_of_expr,1648            type_of_pat,1649            type_of_binding,1650            type_of_type_placeholder,1651            type_of_opaque,1652            skipped_ref_pats,1653            closures_data,1654            has_errors,1655            error_ty: _,1656            pat_adjustments,1657            binding_modes: _,1658            expr_adjustments,1659            tuple_field_access_types,1660            coercion_casts: _,1661            diagnostics: result_diagnostics,1662            nodes_with_type_mismatches,1663            defined_anon_consts: result_defined_anon_consts,1664        } = &mut result;16651666        *result_defined_anon_consts = self.defined_anon_consts.into_inner();1667        result_defined_anon_consts.shrink_to_fit();16681669        let mut resolver =1670            WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);16711672        skipped_ref_pats.shrink_to_fit();1673        for ty in type_of_expr.values_mut() {1674            resolver.resolve_completely(ty);1675        }1676        type_of_expr.shrink_to_fit();1677        for ty in type_of_pat.values_mut() {1678            resolver.resolve_completely(ty);1679        }1680        type_of_pat.shrink_to_fit();1681        for ty in type_of_binding.values_mut() {1682            resolver.resolve_completely(ty);1683        }1684        type_of_binding.shrink_to_fit();1685        for ty in type_of_type_placeholder.values_mut() {1686            resolver.resolve_completely(ty);1687        }1688        type_of_type_placeholder.shrink_to_fit();1689        type_of_opaque.shrink_to_fit();16901691        if let Some(nodes_with_type_mismatches) = nodes_with_type_mismatches {1692            *has_errors = true;1693            nodes_with_type_mismatches.shrink_to_fit();1694        }1695        for (_, subst) in method_resolutions.values_mut() {1696            resolver.resolve_completely(subst);1697        }1698        method_resolutions.shrink_to_fit();1699        for (_, subst) in assoc_resolutions.values_mut() {1700            resolver.resolve_completely(subst);1701        }1702        assoc_resolutions.shrink_to_fit();1703        for adjustment in expr_adjustments.values_mut().flatten() {1704            resolver.resolve_completely(&mut adjustment.target);1705        }1706        expr_adjustments.shrink_to_fit();1707        for adjustments in pat_adjustments.values_mut() {1708            for adjustment in &mut *adjustments {1709                resolver.resolve_completely(&mut adjustment.source);1710            }1711            adjustments.shrink_to_fit();1712        }1713        pat_adjustments.shrink_to_fit();1714        for closure_data in closures_data.values_mut() {1715            let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data;1716            let dummy_place = || Place {1717                base_ty: types.types.error.store(),1718                base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,1719                projections: Vec::new(),1720            };17211722            for (place, _, sources) in fake_reads {1723                resolver.resolve_completely_with_default(place, dummy_place());1724                place.projections.shrink_to_fit();1725                for source in &mut *sources {1726                    source.shrink_to_fit();1727                }1728                sources.shrink_to_fit();1729            }17301731            for min_capture in min_captures.values_mut() {1732                for captured in &mut *min_capture {1733                    let CapturedPlace { place, info, mutability: _ } = captured;1734                    resolver.resolve_completely_with_default(place, dummy_place());1735                    let CaptureInfo { sources, capture_kind: _ } = info;1736                    for source in &mut *sources {1737                        source.shrink_to_fit();1738                    }1739                    sources.shrink_to_fit();1740                }1741                min_capture.shrink_to_fit();1742            }1743            min_captures.shrink_to_fit();17441745            resolver.resolve_completely(liberated_sig);1746        }1747        closures_data.shrink_to_fit();1748        *tuple_field_access_types = tuple_field_accesses_rev1749            .into_iter()1750            .map(|mut subst| {1751                resolver.resolve_completely(&mut subst);1752                subst.store()1753            })1754            .collect();1755        tuple_field_access_types.shrink_to_fit();17561757        let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();1758        *result_diagnostics = diagnostics;1759        *has_errors |= resolver_has_errors;17601761        result1762    }17631764    fn collect_const(&mut self, id: ConstId, data: &'db ConstSignature) {1765        let return_ty = self.make_ty(1766            data.type_ref,1767            &data.store,1768            InferenceTyDiagnosticSource::Signature,1769            ExpressionStoreOwnerId::Signature(id.into()),1770            LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container),1771        );17721773        self.return_ty = return_ty;1774    }17751776    fn collect_static(&mut self, id: StaticId, data: &'db StaticSignature) {1777        let return_ty = self.make_ty(1778            data.type_ref,1779            &data.store,1780            InferenceTyDiagnosticSource::Signature,1781            ExpressionStoreOwnerId::Signature(id.into()),1782            LifetimeElisionKind::Elided(self.types.regions.statik),1783        );17841785        self.return_ty = return_ty;1786    }17871788    fn collect_fn(1789        &mut self,1790        func: FunctionId,1791        self_param: Option<BindingId>,1792        params: &[Param<PatId>],1793    ) {1794        let data = FunctionSignature::of(self.db, func);1795        let mut param_tys = self.with_ty_lowering(1796            &data.store,1797            InferenceTyDiagnosticSource::Signature,1798            ExpressionStoreOwnerId::Signature(func.into()),1799            LifetimeElisionKind::for_fn_params(data),1800            |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),1801        );18021803        // Check if function contains a va_list, if it does then we append it to the parameter types1804        // that are collected from the function data1805        if data.is_varargs() {1806            let va_list_ty = match self.resolve_va_list() {1807                Some(va_list) => Ty::new_adt(1808                    self.interner(),1809                    va_list,1810                    GenericArgs::for_item_with_defaults(1811                        self.interner(),1812                        va_list.into(),1813                        |_, id, _| self.table.var_for_def(id, Span::Dummy),1814                    ),1815                ),1816                None => self.err_ty(),1817            };18181819            param_tys.push(va_list_ty);1820        }1821        let mut param_tys = param_tys.into_iter();1822        if let Some(self_param) = self_param1823            && let Some(ty) = param_tys.next()1824        {1825            let ty = self.process_user_written_ty(ty);1826            self.write_binding_ty(self_param, ty);1827        }1828        for pat in params {1829            let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));1830            let ty = self.process_user_written_ty(ty);18311832            self.infer_top_pat(pat.formal, ty, PatOrigin::Param);1833        }1834        self.return_ty = match data.ret_type {1835            Some(return_ty) => {1836                let return_ty = self.with_ty_lowering(1837                    &data.store,1838                    InferenceTyDiagnosticSource::Signature,1839                    ExpressionStoreOwnerId::Signature(func.into()),1840                    LifetimeElisionKind::for_fn_ret(self.interner()),1841                    |ctx| {1842                        ctx.impl_trait_mode(ImplTraitLoweringMode::Opaque);1843                        ctx.lower_ty(return_ty)1844                    },1845                );1846                self.process_user_written_ty(return_ty)1847            }1848            None => self.types.types.unit,1849        };18501851        self.return_coercion = Some(CoerceMany::new(self.return_ty));1852    }18531854    #[inline]1855    pub(crate) fn interner(&self) -> DbInterner<'db> {1856        self.table.interner()1857    }18581859    #[inline]1860    pub(crate) fn infcx(&self) -> &InferCtxt<'db> {1861        &self.table.infer_ctxt1862    }18631864    /// If `ty` is an error, returns an infer var instead. Otherwise, returns it.1865    ///1866    /// "Refreshing" types like this is useful for getting better types, but it is also1867    /// very dangerous: we might create duplicate diagnostics, for example if we try1868    /// to resolve it and fail. rustc doesn't do that for this reason (and is in general1869    /// more strict with how it uses error types; an error type in inputs will almost1870    /// always cause it to infer an error type in output, while we infer some type as much1871    /// as we can).1872    ///1873    /// Unfortunately, we cannot allow ourselves to do that. Not only we more often work1874    /// with incomplete code, we also have assists, for example "Generate constant", that1875    /// will assume the inferred type is the expected type even if the expression itself1876    /// cannot be inferred. Therefore, we choose a middle ground: refresh the type,1877    /// but if we return a new var, mark it so that no diagnostics will be issued on it.1878    fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {1879        if ty.is_ty_error() {1880            let var = self.table.next_ty_var(Span::Dummy);18811882            // Suppress future errors on this var. Add more things here when we add more diagnostics.1883            self.vars_emitted_type_must_be_known_for.insert(var.into());18841885            var1886        } else {1887            ty1888        }1889    }18901891    fn infer_body(&mut self, body_expr: ExprId) {1892        match self.return_coercion {1893            Some(_) => self.infer_return(body_expr),1894            None => {1895                _ = self.infer_expr_coerce(1896                    body_expr,1897                    &Expectation::has_type(self.return_ty),1898                    ExprIsRead::Yes,1899                )1900            }1901        }1902    }19031904    fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {1905        self.result.type_of_expr.insert(expr, ty.store());1906    }19071908    pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {1909        if adjustments.is_empty() {1910            return;1911        }1912        match self.result.expr_adjustments.entry(expr) {1913            std::collections::hash_map::Entry::Occupied(mut entry) => {1914                match (&mut entry.get_mut()[..], &adjustments[..]) {1915                    (1916                        [Adjustment { kind: Adjust::NeverToAny, target }],1917                        [.., Adjustment { target: new_target, .. }],1918                    ) => {1919                        // NeverToAny coercion can target any type, so instead of adding a new1920                        // adjustment on top we can change the target.1921                        *target = new_target.clone();1922                    }1923                    _ => {1924                        *entry.get_mut() = adjustments;1925                    }1926                }1927            }1928            std::collections::hash_map::Entry::Vacant(entry) => {1929                entry.insert(adjustments);1930            }1931        }1932    }19331934    pub(crate) fn write_method_resolution(1935        &mut self,1936        expr: ExprId,1937        func: FunctionId,1938        subst: GenericArgs<'db>,1939    ) {1940        self.result.method_resolutions.insert(expr, (func, subst.store()));1941    }19421943    fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) {1944        self.result.variant_resolutions.insert(id, variant);1945    }19461947    fn write_assoc_resolution(1948        &mut self,1949        id: ExprOrPatIdPacked,1950        item: CandidateId,1951        subs: GenericArgs<'db>,1952    ) {1953        self.result.assoc_resolutions.insert(id, (item, subs.store()));1954    }19551956    fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {1957        self.result.type_of_pat.insert(pat, ty.store());1958    }19591960    fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {1961        self.result.type_of_binding.insert(id, ty.store());1962    }19631964    pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {1965        self.diagnostics.push(diagnostic);1966    }19671968    fn record_deferred_call_resolution(1969        &mut self,1970        closure_def_id: ExprId,1971        r: DeferredCallResolution<'db>,1972    ) {1973        self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);1974    }19751976    fn remove_deferred_call_resolutions(1977        &mut self,1978        closure_def_id: ExprId,1979    ) -> Vec<DeferredCallResolution<'db>> {1980        self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()1981    }19821983    fn with_ty_lowering<R>(1984        &mut self,1985        store: &'db ExpressionStore,1986        types_source: InferenceTyDiagnosticSource,1987        store_owner: ExpressionStoreOwnerId,1988        lifetime_elision: LifetimeElisionKind<'db>,1989        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,1990    ) -> R {1991        let infer_vars = match types_source {1992            InferenceTyDiagnosticSource::Body => Some(&mut InferenceTyLoweringVarsCtx {1993                table: &mut self.table,1994                type_of_type_placeholder: &mut self.result.type_of_type_placeholder,1995            } as _),1996            InferenceTyDiagnosticSource::Signature => None,1997        };1998        let mut ctx = TyLoweringContext::new(1999            self.db,2000            &self.resolver,

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.