src/tools/rust-analyzer/crates/hir-ty/src/infer.rs RUST 2,776 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,776.
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    cmp,37    convert::identity,38    fmt,39    hash::Hash,40    ops::Deref,41};4243use base_db::{Crate, FxIndexMap};44use either::Either;45use hir_def::{46    AdtId, AssocItemId, AttrDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId,47    GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId,48    VariantId,49    attrs::AttrFlags,50    expr_store::{Body, ExpressionStore, HygieneId, body::Param, path::Path},51    hir::{BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked, LabelId, PatId, UnaryOp},52    lang_item::LangItems,53    layout::Integer,54    resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},55    signatures::EnumSignature,56    type_ref::{LifetimeRefId, TypeRefId},57    unstable_features::UnstableFeatures,58};59use hir_expand::{mod_path::ModPath, name::Name};60use indexmap::IndexSet;61use la_arena::ArenaMap;62use macros::{TypeFoldable, TypeVisitable};63use rustc_abi::TargetDataLayout;64use rustc_ast_ir::Mutability;65use rustc_hash::{FxHashMap, FxHashSet};66use rustc_type_ir::{67    AliasTyKind, TypeFoldable, TypeVisitableExt,68    inherent::{GenericArgs as _, IntoKind, Ty as _},69};70use salsa::SalsaValue;71use smallvec::SmallVec;72use span::Edition;73use stdx::never;74use thin_vec::ThinVec;7576use crate::{77    ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,78    TargetFeatures, ValueTyDefId,79    closure_analysis::PlaceBase,80    consteval::{create_anon_const, path_to_const},81    db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},82    generics::Generics,83    infer::{84        callee::DeferredCallResolution,85        closure::analysis::{86            BorrowKind,87            expr_use_visitor::{FakeReadCause, Place},88        },89        coerce::{CoerceMany, DynamicCoerceMany},90        diagnostics::{91            Diagnostics, InferenceTyLoweringContext as TyLoweringContext,92            InferenceTyLoweringVarsCtx,93        },94        expr::ExprIsRead,95        pat::PatOrigin,96        unify::resolve_completely::WriteBackCtxt,97    },98    lower::{99        ImplTraitIdx, LifetimeElisionKind, LifetimeLoweringMode, LoweringMode,100        diagnostics::TyLoweringDiagnostic,101    },102    method_resolution::CandidateId,103    next_solver::{104        AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, StoredFnSig,105        StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,106        abi::Safety,107        infer::{InferCtxt, ObligationInspector, traits::ObligationCause},108    },109    solver_errors::SolverDiagnostic,110    utils::TargetFeatureIsSafeInTarget,111};112113pub use coerce::could_coerce;114pub use unify::{could_unify, could_unify_deeply};115116use cast::{CastCheck, CastError};117118/// The entry point of type inference.119fn infer_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {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<'db> {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) => {149            ctx.collect_fn(f, body.self_param.map(|param| param.formal), &body.params)150        }151        DefWithBodyId::ConstId(c) => ctx.collect_const_or_static(c.into()),152        DefWithBodyId::StaticId(s) => ctx.collect_const_or_static(s.into()),153        DefWithBodyId::VariantId(v) => {154            ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {155                hir_def::layout::IntegerType::Pointer(signed) => match signed {156                    true => ctx.types.types.isize,157                    false => ctx.types.types.usize,158                },159                hir_def::layout::IntegerType::Fixed(size, signed) => match signed {160                    true => match size {161                        Integer::I8 => ctx.types.types.i8,162                        Integer::I16 => ctx.types.types.i16,163                        Integer::I32 => ctx.types.types.i32,164                        Integer::I64 => ctx.types.types.i64,165                        Integer::I128 => ctx.types.types.i128,166                    },167                    false => match size {168                        Integer::I8 => ctx.types.types.u8,169                        Integer::I16 => ctx.types.types.u16,170                        Integer::I32 => ctx.types.types.u32,171                        Integer::I64 => ctx.types.types.u64,172                        Integer::I128 => ctx.types.types.u128,173                    },174                },175            };176        }177    }178179    ctx.infer_body(body.root_expr());180181    ctx.infer_mut_body(body.root_expr());182183    infer_finalize(ctx)184}185186fn infer_cycle_result<'db>(187    db: &'db dyn HirDatabase,188    _: salsa::Id,189    _: DefWithBodyId,190) -> InferenceResult<'db> {191    InferenceResult {192        has_errors: true,193        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))194    }195}196197/// Infer types for an anonymous const expression.198fn infer_anon_const_query<'db>(199    db: &'db dyn HirDatabase,200    def: AnonConstId<'db>,201) -> InferenceResult<'db> {202    let _p = tracing::info_span!("infer_anon_const_query").entered();203    let loc = def.loc(db);204    let store_owner = loc.owner;205    let store = ExpressionStore::of(db, store_owner);206207    let resolver = store_owner.resolver(db);208209    let mut ctx = InferenceContext::new(210        db,211        InferBodyId::AnonConstId(def),212        store_owner,213        loc.owner.generic_def(db),214        store,215        resolver,216        loc.allow_using_generic_params,217        LoweringMode::Analysis,218    );219220    ctx.infer_expr(221        loc.expr,222        &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),223        ExprIsRead::Yes,224    );225226    infer_finalize(ctx)227}228229fn infer_anon_const_cycle_result<'db>(230    db: &'db dyn HirDatabase,231    _: salsa::Id,232    _: AnonConstId<'db>,233) -> InferenceResult<'db> {234    InferenceResult {235        has_errors: true,236        ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))237    }238}239240fn infer_finalize<'db>(mut ctx: InferenceContext<'db>) -> InferenceResult<'db> {241    ctx.handle_opaque_type_uses();242243    ctx.type_inference_fallback();244245    // Comment from rustc:246    // Even though coercion casts provide type hints, we check casts after fallback for247    // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.248    let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);249    for mut cast in cast_checks.into_iter() {250        if let Err(diag) = cast.check(&mut ctx) {251            ctx.diagnostics.push(diag);252        }253    }254255    ctx.table.select_obligations_where_possible();256257    // Closure and coroutine analysis may run after fallback258    // because they don't constrain other type variables.259    ctx.closure_analyze();260    assert!(ctx.deferred_call_resolutions.is_empty());261262    ctx.table.select_obligations_where_possible();263264    ctx.handle_opaque_type_uses();265266    ctx.merge_anon_consts();267268    ctx.resolve_all()269}270271#[derive(Clone, Copy, Debug, Eq, PartialEq)]272pub enum ByRef {273    Yes(Mutability),274    No,275}276277/// The mode of a binding (`mut`, `ref mut`, etc).278/// Used for both the explicit binding annotations given in the HIR for a binding279/// and the final binding mode that we infer after type inference/match ergonomics.280/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),281/// `.1` is the mutability of the binding.282#[derive(Copy, Clone, Debug, Eq, PartialEq)]283pub struct BindingMode(pub ByRef, pub Mutability);284285#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]286pub enum InferenceDiagnostic {287    NoSuchField {288        #[type_visitable(ignore)]289        field: ExprOrPatIdPacked,290        #[type_visitable(ignore)]291        private: Option<LocalFieldId>,292        #[type_visitable(ignore)]293        variant: VariantId,294    },295    MismatchedArrayPatLen {296        #[type_visitable(ignore)]297        pat: PatId,298        #[type_visitable(ignore)]299        expected: u64,300        #[type_visitable(ignore)]301        found: u64,302        #[type_visitable(ignore)]303        has_rest: bool,304    },305    ArrayPatternWithoutFixedLength {306        #[type_visitable(ignore)]307        pat: PatId,308    },309    ExpectedArrayOrSlicePat {310        #[type_visitable(ignore)]311        pat: PatId,312        found: StoredTy,313    },314    InvalidRangePatType {315        #[type_visitable(ignore)]316        pat: PatId,317    },318    DuplicateField {319        #[type_visitable(ignore)]320        field: ExprOrPatIdPacked,321        #[type_visitable(ignore)]322        variant: VariantId,323    },324    PrivateField {325        #[type_visitable(ignore)]326        expr: ExprId,327        #[type_visitable(ignore)]328        field: FieldId,329    },330    PrivateAssocItem {331        #[type_visitable(ignore)]332        id: ExprOrPatIdPacked,333        #[type_visitable(ignore)]334        item: AssocItemId,335    },336    UnresolvedField {337        #[type_visitable(ignore)]338        expr: ExprId,339        receiver: StoredTy,340        #[type_visitable(ignore)]341        name: Name,342        #[type_visitable(ignore)]343        method_with_same_name_exists: bool,344    },345    UnresolvedMethodCall {346        #[type_visitable(ignore)]347        expr: ExprId,348        receiver: StoredTy,349        #[type_visitable(ignore)]350        name: Name,351        /// Contains the type the field resolves to352        field_with_same_name: Option<StoredTy>,353        #[type_visitable(ignore)]354        assoc_func_with_same_name: Option<FunctionId>,355    },356    UnresolvedAssocItem {357        #[type_visitable(ignore)]358        id: ExprOrPatIdPacked,359    },360    UnresolvedIdent {361        #[type_visitable(ignore)]362        id: ExprOrPatIdPacked,363    },364    // FIXME: This should be emitted in body lowering365    BreakOutsideOfLoop {366        #[type_visitable(ignore)]367        expr: ExprId,368        #[type_visitable(ignore)]369        is_break: bool,370        #[type_visitable(ignore)]371        bad_value_break: bool,372    },373    NonExhaustiveRecordExpr {374        #[type_visitable(ignore)]375        expr: ExprId,376    },377    NonExhaustiveRecordPat {378        #[type_visitable(ignore)]379        pat: PatId,380        #[type_visitable(ignore)]381        variant: VariantId,382    },383    UnionPatMustHaveExactlyOneField {384        #[type_visitable(ignore)]385        pat: PatId,386    },387    UnionPatHasRest {388        #[type_visitable(ignore)]389        pat: PatId,390    },391    FunctionalRecordUpdateOnNonStruct {392        #[type_visitable(ignore)]393        base_expr: ExprId,394    },395    MismatchedArgCount {396        #[type_visitable(ignore)]397        call_expr: ExprId,398        #[type_visitable(ignore)]399        expected: usize,400        #[type_visitable(ignore)]401        found: usize,402        /// True when the call goes through the `Fn`/`FnMut`/`FnOnce` trait403        /// (i.e. arguments were bundled into a tuple). Determines whether the404        /// diagnostic surface uses E0057 (Fn-trait call) or E0061 (regular call).405        #[type_visitable(ignore)]406        is_fn_trait_call: bool,407    },408    MismatchedTupleStructPatArgCount {409        #[type_visitable(ignore)]410        pat: PatId,411        #[type_visitable(ignore)]412        expected: usize,413        #[type_visitable(ignore)]414        found: usize,415    },416    ExpectedFunction {417        #[type_visitable(ignore)]418        call_expr: ExprId,419        found: StoredTy,420    },421    CannotBeDereferenced {422        #[type_visitable(ignore)]423        expr: ExprId,424        found: StoredTy,425    },426    UnaryOperatorCannotBeApplied {427        #[type_visitable(ignore)]428        expr: ExprId,429        #[type_visitable(ignore)]430        op: UnaryOp,431        found: StoredTy,432    },433    MutRefInImmRefPat {434        #[type_visitable(ignore)]435        pat: PatId,436    },437    CannotImplicitlyDerefTraitObject {438        #[type_visitable(ignore)]439        pat: PatId,440        found: StoredTy,441    },442    CannotIndexInto {443        #[type_visitable(ignore)]444        expr: ExprId,445        found: StoredTy,446    },447    TypedHole {448        #[type_visitable(ignore)]449        expr: ExprId,450        expected: StoredTy,451    },452    CastToUnsized {453        #[type_visitable(ignore)]454        expr: ExprId,455        cast_ty: StoredTy,456    },457    InvalidCast {458        #[type_visitable(ignore)]459        expr: ExprId,460        #[type_visitable(ignore)]461        error: CastError,462        expr_ty: StoredTy,463        cast_ty: StoredTy,464    },465    TyDiagnostic {466        #[type_visitable(ignore)]467        diag: TyLoweringDiagnostic,468    },469    PathDiagnostic {470        #[type_visitable(ignore)]471        node: ExprOrPatIdPacked,472        #[type_visitable(ignore)]473        diag: PathLoweringDiagnostic,474    },475    MethodCallIncorrectGenericsLen {476        #[type_visitable(ignore)]477        expr: ExprId,478        #[type_visitable(ignore)]479        provided_count: u32,480        #[type_visitable(ignore)]481        expected_count: u32,482        #[type_visitable(ignore)]483        kind: IncorrectGenericsLenKind,484        #[type_visitable(ignore)]485        def: GenericDefId,486    },487    MethodCallIllegalSizedBound {488        #[type_visitable(ignore)]489        call_expr: ExprId,490    },491    MethodCallIncorrectGenericsOrder {492        #[type_visitable(ignore)]493        expr: ExprId,494        #[type_visitable(ignore)]495        param_id: GenericParamId,496        #[type_visitable(ignore)]497        arg_idx: u32,498        /// Whether the `GenericArgs` contains a `Self` arg.499        #[type_visitable(ignore)]500        has_self_arg: bool,501    },502    InvalidLhsOfAssignment {503        #[type_visitable(ignore)]504        lhs: ExprId,505    },506    TypeMustBeKnown {507        #[type_visitable(ignore)]508        at_point: Span,509        top_term: Option<StoredGenericArg>,510    },511    UnionExprMustHaveExactlyOneField {512        #[type_visitable(ignore)]513        expr: ExprId,514    },515    TypeMismatch {516        #[type_visitable(ignore)]517        node: ExprOrPatIdPacked,518        expected: StoredTy,519        found: StoredTy,520    },521    SolverDiagnostic(SolverDiagnostic),522    ExplicitDropMethodUse {523        #[type_visitable(ignore)]524        kind: ExplicitDropMethodUseKind,525    },526    MutableRefBinding {527        #[type_visitable(ignore)]528        pat: PatId,529    },530    YieldOutsideCoroutine {531        #[type_visitable(ignore)]532        expr: ExprId,533    },534    ReturnOutsideFunction {535        #[type_visitable(ignore)]536        expr: ExprId,537        #[type_visitable(ignore)]538        kind: ReturnKind,539    },540    RecordMissingFields {541        #[type_visitable(ignore)]542        record: ExprOrPatId,543        #[type_visitable(ignore)]544        variant: VariantId,545        #[type_visitable(ignore)]546        missed_fields: Vec<LocalFieldId>,547    },548}549550#[derive(Debug, PartialEq, Eq, Clone, Copy)]551pub enum ReturnKind {552    ReturnExpr,553    BecomeExpr,554}555556#[derive(Debug, PartialEq, Eq, Clone)]557pub enum ExplicitDropMethodUseKind {558    MethodCall(ExprId),559    Path(ExprOrPatIdPacked),560}561562/// Represents coercing a value to a different type of value.563///564/// We transform values by following a number of `Adjust` steps in order.565/// See the documentation on variants of `Adjust` for more details.566///567/// Here are some common scenarios:568///569/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.570///    Here the pointer will be dereferenced N times (where a dereference can571///    happen to raw or borrowed pointers or any smart pointer which implements572///    Deref, including Box<_>). The types of dereferences is given by573///    `autoderefs`. It can then be auto-referenced zero or one times, indicated574///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is575///    `false`.576///577/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start578///    with a thin pointer, deref a number of times, unsize the underlying data,579///    then autoref. The 'unsize' phase may change a fixed length array to a580///    dynamically sized one, a concrete object to a trait object, or statically581///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is582///    represented by:583///584///    ```ignore585///    Deref(None) -> [i32; 4],586///    Borrow(AutoBorrow::Ref) -> &[i32; 4],587///    Unsize -> &[i32],588///    ```589///590///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.591///    E.g., `struct Foo<T> { it: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>592///    The autoderef and -ref are the same as in the above example, but the type593///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about594///    the underlying conversions from `[i32; 4]` to `[i32]`.595///596/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In597///    that case, we have the pointer we need coming in, so there are no598///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.599///    At some point, of course, `Box` should move out of the compiler, in which600///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->601///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.602#[derive(Clone, Debug, PartialEq, Eq, Hash)]603pub struct Adjustment {604    pub kind: Adjust,605    pub target: StoredTy,606}607608impl Adjustment {609    pub fn borrow<'db>(610        interner: DbInterner<'db>,611        m: Mutability,612        ty: Ty<'db>,613        lt: Region<'db>,614    ) -> Self {615        let ty = Ty::new_ref(interner, lt, ty, m);616        Adjustment {617            kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),618            target: ty.store(),619        }620    }621}622623/// At least for initial deployment, we want to limit two-phase borrows to624/// only a few specific cases. Right now, those are mostly "things that desugar"625/// into method calls:626/// - using `x.some_method()` syntax, where some_method takes `&mut self`,627/// - using `Foo::some_method(&mut x, ...)` syntax,628/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).629///630/// Anything else should be rejected until generalized two-phase borrow support631/// is implemented. Right now, dataflow can't handle the general case where there632/// is more than one use of a mutable borrow, and we don't want to accept too much633/// new code via two-phase borrows, so we try to limit where we create two-phase634/// capable mutable borrows.635/// See #49434 for tracking.636#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]637pub enum AllowTwoPhase {638    // FIXME: We should use this when appropriate.639    Yes,640    No,641}642643#[derive(Clone, Debug, PartialEq, Eq, Hash)]644pub enum Adjust {645    /// Go from ! to any type.646    NeverToAny,647    /// Dereference once, producing a place.648    Deref(Option<OverloadedDeref>),649    /// Take the address and produce either a `&` or `*` pointer.650    Borrow(AutoBorrow),651    Pointer(PointerCast),652}653654/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`655/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.656/// The target type is `U` in both cases, with the region and mutability657/// being those shared by both the receiver and the returned reference.658#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]659pub struct OverloadedDeref(pub Mutability);660661#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]662pub enum AutoBorrowMutability {663    Mut { allow_two_phase_borrow: AllowTwoPhase },664    Not,665}666667impl AutoBorrowMutability {668    /// Creates an `AutoBorrowMutability` from a mutability and allowance of two phase borrows.669    ///670    /// Note that when `mutbl.is_not()`, `allow_two_phase_borrow` is ignored671    pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {672        match mutbl {673            Mutability::Not => Self::Not,674            Mutability::Mut => Self::Mut { allow_two_phase_borrow },675        }676    }677}678679impl From<AutoBorrowMutability> for Mutability {680    fn from(m: AutoBorrowMutability) -> Self {681        match m {682            AutoBorrowMutability::Mut { .. } => Mutability::Mut,683            AutoBorrowMutability::Not => Mutability::Not,684        }685    }686}687688#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]689pub enum AutoBorrow {690    /// Converts from T to &T.691    Ref(AutoBorrowMutability),692    /// Converts from T to *T.693    RawPtr(Mutability),694}695696#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]697pub enum PointerCast {698    /// Go from a fn-item type to a fn-pointer type.699    ReifyFnPointer,700701    /// Go from a safe fn pointer to an unsafe fn pointer.702    UnsafeFnPointer,703704    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.705    /// It cannot convert a closure that requires unsafe.706    ClosureFnPointer(Safety),707708    /// Go from a mut raw pointer to a const raw pointer.709    MutToConstPointer,710711    #[allow(dead_code)]712    /// Go from `*const [T; N]` to `*const T`713    ArrayToPointer,714715    /// Unsize a pointer/reference value, e.g., `&[T; n]` to716    /// `&[T]`. Note that the source could be a thin or fat pointer.717    /// This will do things like convert thin pointers to fat718    /// pointers, or convert structs containing thin pointers to719    /// structs containing fat pointers, or convert between fat720    /// pointers. We don't store the details of how the transform is721    /// done (in fact, we don't know that, because it might depend on722    /// the precise type parameters). We just store the target723    /// type. Codegen backends and miri figure out what has to be done724    /// based on the precise source/target type at hand.725    Unsize,726}727728/// Represents an implicit coercion applied to the scrutinee of a match before testing a pattern729/// against it. Currently, this is used only for implicit dereferences.730#[derive(Debug, Clone, PartialEq, Eq)]731pub struct PatAdjustment {732    pub kind: PatAdjust,733    /// The type of the scrutinee before the adjustment is applied, or the "adjusted type" of the734    /// pattern.735    pub source: StoredTy,736}737738/// Represents implicit coercions of patterns' types, rather than values' types.739#[derive(Clone, Copy, PartialEq, Eq, Debug)]740pub enum PatAdjust {741    /// An implicit dereference before matching, such as when matching the pattern `0` against a742    /// scrutinee of type `&u8` or `&mut u8`.743    BuiltinDeref,744    /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the745    /// pattern `[..]` against a scrutinee of type `Vec<T>`.746    OverloadedDeref,747}748749/// The result of type inference: A mapping from expressions and patterns to types.750///751/// When you add a field that stores types (including `Substitution` and the like), don't forget752/// `resolve_completely()`'ing  them in `InferenceContext::resolve_all()`. Inference variables must753/// not appear in the final inference result.754#[derive(Clone, PartialEq, Eq, Debug, SalsaValue)]755pub struct InferenceResult<'db> {756    /// For each method call expr, records the function it resolves to.757    method_resolutions: FxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,758    /// For each field access expr, records the field it resolves to.759    field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,760    /// For each struct literal or pattern, records the variant it resolves to.761    variant_resolutions: FxHashMap<ExprOrPatIdPacked, VariantId>,762    /// For each associated item record what it resolves to763    assoc_resolutions: FxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>,764    /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in765    /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of766    /// that which allows us to resolve a [`TupleFieldId`]s type.767    tuple_field_access_types: ThinVec<StoredTys>,768769    pub type_of_expr: ArenaMap<ExprId, StoredTy>,770    /// For each pattern record the type it resolves to.771    ///772    /// **Note**: When a pattern type is resolved it may still contain773    /// unresolved or missing subpatterns or subpatterns of mismatched types.774    pub type_of_pat: ArenaMap<PatId, StoredTy>,775    pub type_of_binding: ArenaMap<BindingId, StoredTy>,776    pub type_of_type_placeholder: FxHashMap<TypeRefId, StoredTy>,777    pub type_of_opaque: FxHashMap<InternedOpaqueTyId<'db>, StoredTy>,778779    /// Whether there are any type-mismatching errors in the result.780    // FIXME: This isn't as useful as initially thought due to us falling back placeholders to781    // `TyKind::Error`.782    // Which will then mark this field.783    pub has_errors: bool,784    /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.785    diagnostics: ThinVec<InferenceDiagnostic>,786    // FIXME: Remove this, change it to be in `InferenceContext`:787    nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatIdPacked>>>,788789    /// Interned `Error` type to return references to.790    // FIXME: Remove this.791    error_ty: StoredTy,792793    pub expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,794    /// Stores the types which were implicitly dereferenced in pattern binding modes.795    pub pat_adjustments: FxHashMap<PatId, Vec<PatAdjustment>>,796    /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.797    ///798    /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an799    /// or pattern can have multiple binding modes. For example:800    /// ```801    /// fn foo(mut slice: &[u32]) -> usize {802    ///     slice = match slice {803    ///         [0, rest @ ..] | rest => rest,804    ///     };805    ///     0806    /// }807    /// ```808    /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.809    pub binding_modes: ArenaMap<PatId, BindingMode>,810811    /// Set of reference patterns that match against a match-ergonomics inserted reference812    /// (as opposed to against a reference in the scrutinee type).813    skipped_ref_pats: FxHashSet<PatId>,814815    pub coercion_casts: FxHashSet<ExprId>,816817    pub closures_data: FxHashMap<ExprId, ClosureData>,818819    defined_anon_consts: ThinVec<AnonConstId<'db>>,820}821822#[derive(Clone, PartialEq, Eq, Debug)]823pub struct ClosureData {824    /// Tracks the minimum captures required for a closure;825    /// see `MinCaptureInformationMap` for more details.826    pub min_captures: RootVariableMinCaptureList,827828    /// Tracks the fake reads required for a closure and the reason for the fake read.829    /// When performing pattern matching for closures, there are times we don't end up830    /// reading places that are mentioned in a closure (because of _ patterns). However,831    /// to ensure the places are initialized, we introduce fake reads.832    /// Consider these two examples:833    /// ```ignore (discriminant matching with only wildcard arm)834    /// let x: u8;835    /// let c = || match x { _ => () };836    /// ```837    /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't838    /// want to capture it. However, we do still want an error here, because `x` should have839    /// to be initialized at the point where c is created. Therefore, we add a "fake read"840    /// instead.841    /// ```ignore (destructured assignments)842    /// let c = || {843    ///     let (t1, t2) = t;844    /// }845    /// ```846    /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but847    /// we never capture `t`. This becomes an issue when we build MIR as we require848    /// information on `t` in order to create place `t.0` and `t.1`. We can solve this849    /// issue by fake reading `t`.850    pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,851852    /// For each fn, records the "liberated" types of its arguments853    /// and return type. Liberated means that all bound regions854    /// (including late-bound regions) are replaced with free855    /// equivalents. This table is not used in codegen (since regions856    /// are erased there) and hence is not serialized to metadata.857    ///858    /// This table also contains the "revealed" values for any `impl Trait`859    /// that appear in the signature and whose values are being inferred860    /// by this function.861    ///862    /// # Example863    ///864    /// ```rust865    /// # use std::fmt::Debug;866    /// fn foo(x: &u32) -> impl Debug { *x }867    /// ```868    ///869    /// The function signature here would be:870    ///871    /// ```ignore (illustrative)872    /// for<'a> fn(&'a u32) -> Foo873    /// ```874    ///875    /// where `Foo` is an opaque type created for this function.876    ///877    ///878    /// The *liberated* form of this would be879    ///880    /// ```ignore (illustrative)881    /// fn(&'a u32) -> u32882    /// ```883    ///884    /// Note that `'a` is not bound (it would be an `ReLateParam`) and885    /// that the `Foo` opaque type is replaced by its hidden type.886    pub liberated_sig: StoredFnSig,887}888889/// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`.890/// Used to track the minimum set of `Place`s that need to be captured to support all891/// Places captured by the closure starting at a given root variable.892///893/// This provides a convenient and quick way of checking if a variable being used within894/// a closure is a capture of a local variable.895pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;896897/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.898pub(crate) type MinCaptureList = Vec<CapturedPlace>;899900/// A composite describing a `Place` that is captured by a closure.901#[derive(Eq, PartialEq, Clone, Debug, Hash)]902pub struct CapturedPlace {903    /// The `Place` that is captured.904    pub place: Place,905906    /// `CaptureKind` and expression(s) that resulted in such capture of `place`.907    pub info: CaptureInfo,908909    /// Represents if `place` can be mutated or not.910    pub mutability: Mutability,911}912913impl CapturedPlace {914    pub fn is_by_ref(&self) -> bool {915        match self.info.capture_kind {916            UpvarCapture::ByValue | UpvarCapture::ByUse => false,917            UpvarCapture::ByRef(..) => true,918        }919    }920921    pub fn captured_local(&self) -> BindingId {922        match self.place.base {923            PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,924            PlaceBase::Rvalue | PlaceBase::StaticItem => {925                unreachable!("only locals can be captured")926            }927        }928    }929930    /// The type of the capture stored in the closure, which is different from the type of the captured place931    /// if we capture by reference.932    pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {933        let place_ty = self.place.ty();934        let make_ref = |mutbl| {935            let interner = DbInterner::new_no_crate(db);936            let region = Region::new_erased(interner);937            Ty::new_ref(interner, region, place_ty, mutbl)938        };939        match self.info.capture_kind {940            UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,941            UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),942        }943    }944}945946#[derive(Clone)]947pub struct CaptureSourceStack(CaptureSourceStackRepr);948949#[derive(Clone)]950enum CaptureSourceStackRepr {951    One(ExprOrPatIdPacked),952    Two([ExprOrPatIdPacked; 2]),953    Many(ThinVec<ExprOrPatIdPacked>),954}955956impl PartialEq for CaptureSourceStack {957    fn eq(&self, other: &Self) -> bool {958        **self == **other959    }960}961962impl Eq for CaptureSourceStack {}963964impl std::hash::Hash for CaptureSourceStack {965    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {966        (**self).hash(state);967    }968}969970#[cfg(target_pointer_width = "64")]971const _: () = assert!(size_of::<CaptureSourceStack>() == 16);972973impl Deref for CaptureSourceStack {974    type Target = [ExprOrPatIdPacked];975976    #[inline]977    fn deref(&self) -> &Self::Target {978        match &self.0 {979            CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),980            CaptureSourceStackRepr::Two(it) => it,981            CaptureSourceStackRepr::Many(it) => it,982        }983    }984}985986impl fmt::Debug for CaptureSourceStack {987    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {988        f.debug_tuple("CaptureSourceStack").field(&&**self).finish()989    }990}991992impl CaptureSourceStack {993    #[inline]994    pub fn len(&self) -> usize {995        match &self.0 {996            CaptureSourceStackRepr::One(_) => 1,997            CaptureSourceStackRepr::Two(_) => 2,998            CaptureSourceStackRepr::Many(it) => it.len(),999        }1000    }10011002    #[inline]1003    pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self {1004        Self(CaptureSourceStackRepr::One(id))1005    }10061007    #[inline]1008    pub fn final_source(&self) -> ExprOrPatIdPacked {1009        *self.last().expect("should always have a final source")1010    }10111012    pub fn push(&mut self, new_id: ExprOrPatIdPacked) {1013        match &mut self.0 {1014            CaptureSourceStackRepr::One(old_id) => {1015                self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])1016            }1017            CaptureSourceStackRepr::Two([old_id1, old_id2]) => {1018                self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));1019            }1020            CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),1021        }1022    }10231024    pub fn truncate(&mut self, new_len: usize) {1025        debug_assert!(new_len > 0);1026        match &mut self.0 {1027            CaptureSourceStackRepr::One(_) => {}1028            CaptureSourceStackRepr::Two([first, _]) => {1029                if new_len == 1 {1030                    self.0 = CaptureSourceStackRepr::One(*first)1031                }1032            }1033            CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),1034        }1035    }10361037    pub fn shrink_to_fit(&mut self) {1038        match &mut self.0 {1039            CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}1040            CaptureSourceStackRepr::Many(ids) => match **ids {1041                [one] => self.0 = CaptureSourceStackRepr::One(one),1042                [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),1043                _ => ids.shrink_to_fit(),1044            },1045        }1046    }1047}10481049/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)1050/// for a particular capture as well as identifying the part of the source code1051/// that triggered this capture to occur.1052#[derive(Eq, PartialEq, Clone, Debug, Hash)]1053pub struct CaptureInfo {1054    pub sources: SmallVec<[CaptureSourceStack; 2]>,10551056    /// Capture mode that was selected1057    pub capture_kind: UpvarCapture,1058}10591060/// Information describing the capture of an upvar. This is computed1061/// during `typeck`, specifically by `regionck`.1062#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]1063pub enum UpvarCapture {1064    /// Upvar is captured by reference.1065    ByRef(BorrowKind),10661067    /// Upvar is captured by use. This is true when the closure is labeled `use`.1068    ByUse,10691070    /// Upvar is captured by value. This is always true when the1071    /// closure is labeled `move`, but can also be true in other cases1072    /// depending on inference.1073    ByValue,1074}10751076// Used in closure::analysis::determine_capture_info1077impl PartialOrd for UpvarCapture {1078    #[inline]1079    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {1080        match (self, other) {1081            (Self::ByValue, Self::ByValue) | (Self::ByUse, Self::ByUse) => {1082                Some(cmp::Ordering::Equal)1083            }1084            (Self::ByValue | Self::ByUse, Self::ByRef(_)) => Some(cmp::Ordering::Greater),1085            (Self::ByRef(_), Self::ByValue | Self::ByUse) => Some(cmp::Ordering::Less),1086            (Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(right)),1087            (Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None,1088        }1089    }1090}10911092#[salsa::tracked]1093impl<'db> InferenceResult<'db> {1094    #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]1095    fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {1096        infer_query(db, def)1097    }10981099    /// Infer types for all const expressions in an item's signature.1100    ///1101    /// Returns an `InferenceResult` containing type information for array lengths,1102    /// const generic arguments, and other const expressions appearing in type1103    /// positions within the item's signature.1104    #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]1105    fn for_anon_const(db: &'db dyn HirDatabase, def: AnonConstId<'db>) -> InferenceResult<'db> {1106        infer_anon_const_query(db, def)1107    }1108}11091110impl<'db> InferenceResult<'db> {1111    #[inline]1112    pub fn of(1113        db: &'db dyn HirDatabase,1114        def: impl Into<InferBodyId<'db>>,1115    ) -> &'db InferenceResult<'db> {1116        match def.into() {1117            InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),1118            InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),1119        }1120    }1121}11221123impl<'db> InferenceResult<'db> {1124    fn new(error_ty: Ty<'_>) -> Self {1125        Self {1126            method_resolutions: Default::default(),1127            field_resolutions: Default::default(),1128            variant_resolutions: Default::default(),1129            assoc_resolutions: Default::default(),1130            tuple_field_access_types: Default::default(),1131            diagnostics: Default::default(),1132            nodes_with_type_mismatches: Default::default(),1133            type_of_expr: Default::default(),1134            type_of_pat: Default::default(),1135            type_of_binding: Default::default(),1136            type_of_type_placeholder: Default::default(),1137            type_of_opaque: Default::default(),1138            skipped_ref_pats: Default::default(),1139            has_errors: Default::default(),1140            error_ty: error_ty.store(),1141            pat_adjustments: Default::default(),1142            binding_modes: Default::default(),1143            expr_adjustments: Default::default(),1144            coercion_casts: Default::default(),1145            closures_data: Default::default(),1146            defined_anon_consts: Default::default(),1147        }1148    }11491150    pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {1151        self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))1152    }1153    pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {1154        self.field_resolutions.get(&expr).copied()1155    }1156    pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {1157        self.variant_resolutions.get(&id.into()).copied()1158    }1159    pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {1160        self.variant_resolutions.get(&id.into()).copied()1161    }1162    pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {1163        match id {1164            ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),1165            ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),1166        }1167    }1168    pub fn assoc_resolutions_for_expr<'a>(1169        &self,1170        id: ExprId,1171    ) -> Option<(CandidateId, GenericArgs<'a>)> {1172        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1173    }1174    pub fn assoc_resolutions_for_pat<'a>(1175        &self,1176        id: PatId,1177    ) -> Option<(CandidateId, GenericArgs<'a>)> {1178        self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))1179    }1180    pub fn assoc_resolutions_for_expr_or_pat<'a>(1181        &self,1182        id: ExprOrPatId,1183    ) -> Option<(CandidateId, GenericArgs<'a>)> {1184        match id {1185            ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),1186            ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),1187        }1188    }1189    pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool {1190        self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node))1191    }1192    pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {1193        self.expr_or_pat_has_type_mismatch(expr.into())1194    }1195    pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {1196        self.expr_or_pat_has_type_mismatch(pat.into())1197    }1198    pub fn exprs_have_type_mismatches(&self) -> bool {1199        self.nodes_with_type_mismatches1200            .as_ref()1201            .is_some_and(|it| it.iter().any(|node| node.is_expr()))1202    }1203    pub fn has_type_mismatches(&self) -> bool {1204        self.nodes_with_type_mismatches.is_some()1205    }1206    pub fn placeholder_types<'a>(&self) -> impl Iterator<Item = (TypeRefId, Ty<'a>)> {1207        self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref()))1208    }1209    pub fn type_of_type_placeholder<'a>(&self, type_ref: TypeRefId) -> Option<Ty<'a>> {1210        self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref())1211    }1212    pub fn type_of_expr_or_pat<'a>(&self, id: ExprOrPatId) -> Option<Ty<'a>> {1213        match id {1214            ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()),1215            ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()),1216        }1217    }1218    pub fn type_of_expr_with_adjust<'a>(&self, id: ExprId) -> Option<Ty<'a>> {1219        match self.expr_adjustments.get(&id).and_then(|adjustments| {1220            adjustments.iter().rfind(|adj| {1221                // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L1401222                !matches!(1223                    adj,1224                    Adjustment {1225                        kind: Adjust::NeverToAny,1226                        target,1227                    } if target.as_ref().is_never()1228                )1229            })1230        }) {1231            Some(adjustment) => Some(adjustment.target.as_ref()),1232            None => self.type_of_expr.get(id).map(|it| it.as_ref()),1233        }1234    }1235    pub fn type_of_pat_with_adjust<'a>(&self, id: PatId) -> Ty<'a> {1236        match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {1237            Some(adjusted) => adjusted.source.as_ref(),1238            None => self.pat_ty(id),1239        }1240    }1241    pub fn is_erroneous(&self) -> bool {1242        self.has_errors && self.type_of_expr.iter().count() == 01243    }12441245    pub fn diagnostics(&self) -> &[InferenceDiagnostic] {1246        &self.diagnostics1247    }12481249    pub fn tuple_field_access_type<'a>(&self, id: TupleId) -> Tys<'a> {1250        self.tuple_field_access_types[id.0 as usize].as_ref()1251    }12521253    pub fn pat_adjustment(&self, id: PatId) -> Option<&[PatAdjustment]> {1254        self.pat_adjustments.get(&id).map(|it| &**it)1255    }12561257    pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {1258        self.expr_adjustments.get(&id).map(|it| &**it)1259    }12601261    pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {1262        self.binding_modes.get(id).copied()1263    }12641265    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1266    pub fn expression_types<'a>(&self) -> impl Iterator<Item = (ExprId, Ty<'a>)> {1267        self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref()))1268    }12691270    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1271    pub fn pattern_types<'a>(&self) -> impl Iterator<Item = (PatId, Ty<'a>)> {1272        self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref()))1273    }12741275    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1276    pub fn binding_types<'a>(&self) -> impl Iterator<Item = (BindingId, Ty<'a>)> {1277        self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref()))1278    }12791280    // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please.1281    pub fn return_position_impl_trait_types<'a>(1282        &'a self,1283        db: &'a dyn HirDatabase,1284    ) -> impl Iterator<Item = (ImplTraitIdx, Ty<'a>)> {1285        self.type_of_opaque.iter().filter_map(move |(&id, ty)| {1286            let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {1287                return None;1288            };1289            Some((rpit_idx, ty.as_ref()))1290        })1291    }12921293    pub fn expr_ty<'a>(&self, id: ExprId) -> Ty<'a> {1294        self.type_of_expr.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1295    }12961297    pub fn pat_ty<'a>(&self, id: PatId) -> Ty<'a> {1298        self.type_of_pat.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1299    }13001301    pub fn expr_or_pat_ty<'a>(&self, id: ExprOrPatId) -> Ty<'a> {1302        self.type_of_expr_or_pat(id).unwrap_or(self.error_ty.as_ref())1303    }13041305    pub fn binding_ty<'a>(&self, id: BindingId) -> Ty<'a> {1306        self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref())1307    }13081309    /// This does not deduplicate, which means you'll get the types once per capture.1310    pub fn closure_captures_tys<'a>(&self, closure: ExprId) -> impl Iterator<Item = Ty<'a>> {1311        self.closures_data[&closure]1312            .min_captures1313            .values()1314            .flat_map(|captures| captures.iter().map(|capture| capture.place.ty()))1315    }13161317    /// Like [`Self::closure_captures_tys()`], but using [`CapturedPlace::captured_ty()`].1318    pub fn closure_captures_captured_tys<'a>(1319        &self,1320        db: &'a dyn HirDatabase,1321        closure: ExprId,1322    ) -> impl Iterator<Item = Ty<'a>> {1323        self.closures_data[&closure]1324            .min_captures1325            .values()1326            .flat_map(|captures| captures.iter().map(|capture| capture.captured_ty(db)))1327    }13281329    pub fn is_skipped_ref_pat(&self, pat: PatId) -> bool {1330        self.skipped_ref_pats.contains(&pat)1331    }1332}13331334#[derive(Debug, Clone, Copy)]1335enum DerefPatBorrowMode {1336    Borrow(Mutability),1337    Box,1338}13391340/// The inference context contains all information needed during type inference.1341#[derive(Debug)]1342pub(crate) struct InferenceContext<'db> {1343    pub(crate) db: &'db dyn HirDatabase,1344    pub(crate) owner: InferBodyId<'db>,1345    pub(crate) store_owner: ExpressionStoreOwnerId,1346    pub(crate) generic_def: GenericDefId,1347    pub(crate) store: &'db ExpressionStore,1348    pub(crate) lowering_mode: LoweringMode,1349    /// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext1350    /// and resolve the path via its methods. This will ensure proper error reporting.1351    pub(crate) resolver: Resolver<'db>,1352    target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,1353    data_layout: OnceCell<&'db TargetDataLayout>,1354    pub(crate) edition: Edition,1355    allow_using_generic_params: bool,1356    generics: OnceCell<Generics<'db>>,1357    identity_args: OnceCell<GenericArgs<'db>>,1358    pub(crate) table: unify::InferenceTable<'db>,1359    pub(crate) lang_items: &'db LangItems,1360    pub(crate) features: &'db UnstableFeatures,1361    /// The traits in scope, disregarding block modules. This is used for caching purposes.1362    traits_in_scope: FxHashSet<TraitId>,1363    pub(crate) result: InferenceResult<'db>,1364    tuple_field_accesses_rev:1365        IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,1366    /// The return type of the function being inferred, the closure or async block if we're1367    /// currently within one.1368    ///1369    /// We might consider using a nested inference context for checking1370    /// closures so we can swap all shared things out at once.1371    return_ty: Ty<'db>,1372    /// If `Some`, this stores coercion information for returned1373    /// expressions. If `None`, this is in a context where return is1374    /// inappropriate, such as a const expression.1375    return_coercion: Option<DynamicCoerceMany<'db>>,1376    /// The resume type and the yield type, respectively, of the coroutine being inferred.1377    resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,1378    diverges: Diverges,1379    breakables: Vec<BreakableContext<'db>>,1380    types: &'db crate::next_solver::DefaultAny<'db>,13811382    deferred_cast_checks: Vec<CastCheck<'db>>,13831384    /// The key is an expression defining a closure or a coroutine closure.1385    deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>,13861387    diagnostics: Diagnostics,1388    vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>,13891390    defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>,1391}13921393#[derive(Clone, Debug)]1394struct BreakableContext<'db> {1395    /// Whether this context contains at least one break expression.1396    may_break: bool,1397    /// The coercion target of the context.1398    coerce: Option<DynamicCoerceMany<'db>>,1399    /// The optional label of the context.1400    label: Option<LabelId>,1401    kind: BreakableKind,1402}14031404#[derive(Clone, Debug)]1405enum BreakableKind {1406    Block,1407    Loop,1408    /// A border is something like an async block, closure etc. Anything that prevents1409    /// breaking/continuing through1410    Border,1411}14121413fn find_breakable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {1414    let mut ctxs = ctxs1415        .iter()1416        .enumerate()1417        .rev()1418        .take_while(|(_, it)| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));1419    let result = match label {1420        Some(_) => ctxs.find(|(_, ctx)| ctx.label == label),1421        None => ctxs.find(|(_, ctx)| matches!(ctx.kind, BreakableKind::Loop)),1422    };1423    result.map(|(idx, _)| idx)1424}14251426fn find_continuable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {1427    find_breakable(ctxs, label)1428        .filter(|&idx| label.is_none() || matches!(ctxs[idx].kind, BreakableKind::Loop))1429}14301431impl<'db> InferenceContext<'db> {1432    fn new(1433        db: &'db dyn HirDatabase,1434        owner: InferBodyId<'db>,1435        store_owner: ExpressionStoreOwnerId,1436        generic_def: GenericDefId,1437        store: &'db ExpressionStore,1438        resolver: Resolver<'db>,1439        allow_using_generic_params: bool,1440        lowering_mode: LoweringMode,1441    ) -> Self {1442        let trait_env = db.trait_environment(generic_def);1443        let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), owner);1444        let types = crate::next_solver::default_types();1445        InferenceContext {1446            result: InferenceResult::new(types.types.error),1447            return_ty: types.types.error, // set in collect_* calls1448            types,1449            target_features: OnceCell::new(),1450            data_layout: OnceCell::new(),1451            lang_items: table.interner().lang_items(),1452            features: resolver.top_level_def_map().features(),1453            edition: resolver.krate().data(db).edition,1454            table,1455            tuple_field_accesses_rev: Default::default(),1456            resume_yield_tys: None,1457            return_coercion: None,1458            db,1459            owner,1460            store_owner,1461            generic_def,1462            allow_using_generic_params,1463            generics: OnceCell::new(),1464            identity_args: OnceCell::new(),1465            store,1466            traits_in_scope: resolver.traits_in_scope(db),1467            resolver,1468            diverges: Diverges::Maybe,1469            breakables: Vec::new(),1470            deferred_cast_checks: Vec::new(),1471            diagnostics: Diagnostics::default(),1472            vars_emitted_type_must_be_known_for: FxHashSet::default(),1473            deferred_call_resolutions: FxHashMap::default(),1474            defined_anon_consts: RefCell::new(ThinVec::new()),1475            lowering_mode,1476        }1477    }14781479    fn merge(&mut self, other: &InferenceResult<'db>) {1480        let InferenceResult {1481            method_resolutions,1482            field_resolutions,1483            variant_resolutions,1484            assoc_resolutions,1485            tuple_field_access_types: _,1486            type_of_expr,1487            type_of_pat,1488            type_of_binding,1489            type_of_type_placeholder,1490            type_of_opaque,1491            has_errors: _,1492            diagnostics: _,1493            error_ty: _,1494            expr_adjustments,1495            pat_adjustments,1496            binding_modes,1497            skipped_ref_pats,1498            coercion_casts,1499            closures_data,1500            nodes_with_type_mismatches,1501            defined_anon_consts: _,1502        } = &mut self.result;1503        merge_hash_maps(method_resolutions, &other.method_resolutions);1504        merge_hash_maps(variant_resolutions, &other.variant_resolutions);1505        merge_hash_maps(assoc_resolutions, &other.assoc_resolutions);1506        field_resolutions.extend(other.field_resolutions.iter().map(1507            |(&field_expr, &field_resolution)| {1508                let mut field_resolution = field_resolution;1509                if let Either::Right(tuple_field) = &mut field_resolution {1510                    let tys = other.tuple_field_access_type(tuple_field.tuple);1511                    tuple_field.tuple =1512                        TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);1513                };1514                (field_expr, field_resolution)1515            },1516        ));1517        merge_arena_maps(type_of_expr, &other.type_of_expr);1518        merge_arena_maps(type_of_pat, &other.type_of_pat);1519        merge_arena_maps(type_of_binding, &other.type_of_binding);1520        merge_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);1521        merge_hash_maps(type_of_opaque, &other.type_of_opaque);1522        merge_hash_maps(expr_adjustments, &other.expr_adjustments);1523        merge_hash_maps(pat_adjustments, &other.pat_adjustments);1524        merge_arena_maps(binding_modes, &other.binding_modes);1525        merge_hash_set(skipped_ref_pats, &other.skipped_ref_pats);1526        merge_hash_set(coercion_casts, &other.coercion_casts);1527        merge_hash_maps(closures_data, &other.closures_data);1528        if let Some(other_nodes_with_type_mismatches) = &other.nodes_with_type_mismatches {1529            merge_hash_set(1530                nodes_with_type_mismatches.get_or_insert_default(),1531                other_nodes_with_type_mismatches,1532            );1533        }1534        self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());1535        self.diagnostics.extend(&other.diagnostics);15361537        fn merge_hash_set<T: Hash + Eq + Clone>(dest: &mut FxHashSet<T>, source: &FxHashSet<T>) {1538            dest.extend(source.iter().cloned());1539        }15401541        #[cfg_attr(debug_assertions, track_caller)]1542        fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(1543            dest: &mut FxHashMap<K, V>,1544            source: &FxHashMap<K, V>,1545        ) {1546            if cfg!(debug_assertions) {1547                for (key, src) in source {1548                    assert!(dest.get(key).is_none_or(|dst| dst == src));1549                }1550            }15511552            dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));1553        }15541555        #[cfg_attr(debug_assertions, track_caller)]1556        fn merge_arena_maps<K, V: Clone + PartialEq>(1557            dest: &mut ArenaMap<la_arena::Idx<K>, V>,1558            source: &ArenaMap<la_arena::Idx<K>, V>,1559        ) {1560            if cfg!(debug_assertions) {1561                for (key, src) in source.iter() {1562                    assert!(dest.get(key).is_none_or(|dst| dst == src));1563                }1564            }15651566            dest.extend(source.iter().map(|(k, v)| (k, v.clone())));1567        }1568    }15691570    #[inline]1571    fn krate(&self) -> Crate {1572        self.resolver.krate()1573    }15741575    fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {1576        let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {1577            let target_features = match self.store_owner {1578                ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {1579                    TargetFeatures::from_fn(self.db, id)1580                }1581                _ => TargetFeatures::default(),1582            };1583            let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {1584                Ok(target) => crate::utils::target_feature_is_safe_in_target(target),1585                Err(_) => TargetFeatureIsSafeInTarget::No,1586            };1587            (target_features, target_feature_is_safe)1588        });1589        (target_features, *target_feature_is_safe)1590    }15911592    fn data_layout(&self) -> &'db TargetDataLayout {1593        self.data_layout.get_or_init(|| self.db.target_data_layout_or_default(self.krate()))1594    }15951596    /// How should a deref pattern find the place for its inner pattern to match on?1597    ///1598    /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner1599    /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.1600    /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;1601    /// in this case, we return `DerefPatBorrowMode::Box`.1602    fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {1603        if pointer_ty.is_box() {1604            DerefPatBorrowMode::Box1605        } else {1606            let mutability =1607                if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };1608            DerefPatBorrowMode::Borrow(mutability)1609        }1610    }16111612    #[inline]1613    fn set_tainted_by_errors(&mut self) {1614        self.result.has_errors = true;1615    }16161617    /// Copy the inference of defined anon consts to ourselves, so that we don't need to lookup the defining1618    /// anon const when looking the type of something.1619    fn merge_anon_consts(&mut self) {1620        let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());1621        defined_anon_consts.retain(|&konst| {1622            if konst.loc(self.db).owner != self.store_owner {1623                // This comes from the signature, we don't define it.1624                return false;1625            }16261627            let const_infer = InferenceResult::of(self.db, konst);1628            self.merge(const_infer);1629            true1630        });1631        // Caution, other defined anon consts might have been added by `merge()`!1632        self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);1633    }16341635    fn resolve_all(self) -> InferenceResult<'db> {1636        let InferenceContext {1637            table,1638            mut result,1639            tuple_field_accesses_rev,1640            diagnostics,1641            types,1642            vars_emitted_type_must_be_known_for,1643            ..1644        } = self;1645        let diagnostics = diagnostics.finish();1646        // Destructure every single field so whenever new fields are added to `InferenceResult` we1647        // don't forget to handle them here.1648        let InferenceResult {1649            method_resolutions,1650            field_resolutions: _,1651            variant_resolutions: _,1652            assoc_resolutions,1653            type_of_expr,1654            type_of_pat,1655            type_of_binding,1656            type_of_type_placeholder,1657            type_of_opaque,1658            skipped_ref_pats,1659            closures_data,1660            has_errors,1661            error_ty: _,1662            pat_adjustments,1663            binding_modes: _,1664            expr_adjustments,1665            tuple_field_access_types,1666            coercion_casts: _,1667            diagnostics: result_diagnostics,1668            nodes_with_type_mismatches,1669            defined_anon_consts: result_defined_anon_consts,1670        } = &mut result;16711672        *result_defined_anon_consts = self.defined_anon_consts.into_inner();1673        result_defined_anon_consts.shrink_to_fit();16741675        let mut resolver =1676            WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);16771678        skipped_ref_pats.shrink_to_fit();1679        for ty in type_of_expr.values_mut() {1680            resolver.resolve_completely(ty);1681        }1682        type_of_expr.shrink_to_fit();1683        for ty in type_of_pat.values_mut() {1684            resolver.resolve_completely(ty);1685        }1686        type_of_pat.shrink_to_fit();1687        for ty in type_of_binding.values_mut() {1688            resolver.resolve_completely(ty);1689        }1690        type_of_binding.shrink_to_fit();1691        for ty in type_of_type_placeholder.values_mut() {1692            resolver.resolve_completely(ty);1693        }1694        type_of_type_placeholder.shrink_to_fit();1695        type_of_opaque.shrink_to_fit();16961697        if let Some(nodes_with_type_mismatches) = nodes_with_type_mismatches {1698            *has_errors = true;1699            nodes_with_type_mismatches.shrink_to_fit();1700        }1701        for (_, subst) in method_resolutions.values_mut() {1702            resolver.resolve_completely(subst);1703        }1704        method_resolutions.shrink_to_fit();1705        for (_, subst) in assoc_resolutions.values_mut() {1706            resolver.resolve_completely(subst);1707        }1708        assoc_resolutions.shrink_to_fit();1709        for adjustment in expr_adjustments.values_mut().flatten() {1710            resolver.resolve_completely(&mut adjustment.target);1711        }1712        expr_adjustments.shrink_to_fit();1713        for adjustments in pat_adjustments.values_mut() {1714            for adjustment in &mut *adjustments {1715                resolver.resolve_completely(&mut adjustment.source);1716            }1717            adjustments.shrink_to_fit();1718        }1719        pat_adjustments.shrink_to_fit();1720        for closure_data in closures_data.values_mut() {1721            let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data;1722            let dummy_place = || Place {1723                base_ty: types.types.error.store(),1724                base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,1725                projections: Vec::new(),1726            };17271728            for (place, _, sources) in fake_reads {1729                resolver.resolve_completely_with_default(place, dummy_place());1730                place.projections.shrink_to_fit();1731                for source in &mut *sources {1732                    source.shrink_to_fit();1733                }1734                sources.shrink_to_fit();1735            }17361737            for min_capture in min_captures.values_mut() {1738                for captured in &mut *min_capture {1739                    let CapturedPlace { place, info, mutability: _ } = captured;1740                    resolver.resolve_completely_with_default(place, dummy_place());1741                    let CaptureInfo { sources, capture_kind: _ } = info;1742                    for source in &mut *sources {1743                        source.shrink_to_fit();1744                    }1745                    sources.shrink_to_fit();1746                }1747                min_capture.shrink_to_fit();1748            }1749            min_captures.shrink_to_fit();17501751            resolver.resolve_completely(liberated_sig);1752        }1753        closures_data.shrink_to_fit();1754        *tuple_field_access_types = tuple_field_accesses_rev1755            .into_iter()1756            .map(|mut subst| {1757                resolver.resolve_completely(&mut subst);1758                subst.store()1759            })1760            .collect();1761        tuple_field_access_types.shrink_to_fit();17621763        let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();1764        *result_diagnostics = diagnostics;1765        *has_errors |= resolver_has_errors;17661767        result1768    }17691770    fn collect_const_or_static(&mut self, id: ValueTyDefId) {1771        let return_ty = self.db.value_ty(id).unwrap().instantiate_identity().skip_norm_wip();1772        self.return_ty = self.process_remote_user_written_ty(return_ty);1773    }17741775    fn collect_fn(1776        &mut self,1777        func: FunctionId,1778        self_param: Option<BindingId>,1779        params: &[Param<PatId>],1780    ) {1781        let sig = self.interner().liberate_late_bound_regions(1782            func.into(),1783            self.db.callable_item_signature(func.into()).instantiate_identity().skip_norm_wip(),1784        );17851786        // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`1787        // (as it's created inside the body itself, not passed in from outside).1788        let maybe_va_list =1789            if sig.fn_sig_kind.c_variadic() { self.resolve_va_list() } else { None };1790        let maybe_va_list = maybe_va_list.map(|va_list| {1791            let region = self.table.next_region_var(1792                params.last().expect("variadic function must have parameters").user_written.into(),1793            );1794            Ty::new_adt(self.interner(), va_list, GenericArgs::new_from_slice(&[region.into()]))1795        });17961797        let mut param_tys = sig.inputs().iter().copied();17981799        if let Some(self_param) = self_param1800            && let Some(ty) = param_tys.next()1801        {1802            let ty = self.process_remote_user_written_ty(ty);1803            self.write_binding_ty(self_param, ty);1804        }18051806        let mut param_tys = param_tys.chain(maybe_va_list);1807        for pat in params {1808            let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));1809            let ty = self.process_remote_user_written_ty(ty);18101811            self.infer_top_pat(pat.formal, ty, PatOrigin::Param);1812        }18131814        self.return_ty = self.process_remote_user_written_ty(sig.output());1815        self.return_coercion = Some(CoerceMany::new(self.return_ty));1816    }18171818    #[inline]1819    pub(crate) fn interner(&self) -> DbInterner<'db> {1820        self.table.interner()1821    }18221823    #[inline]1824    pub(crate) fn infcx(&self) -> &InferCtxt<'db> {1825        &self.table.infer_ctxt1826    }18271828    /// If `ty` is an error, returns an infer var instead. Otherwise, returns it.1829    ///1830    /// "Refreshing" types like this is useful for getting better types, but it is also1831    /// very dangerous: we might create duplicate diagnostics, for example if we try1832    /// to resolve it and fail. rustc doesn't do that for this reason (and is in general1833    /// more strict with how it uses error types; an error type in inputs will almost1834    /// always cause it to infer an error type in output, while we infer some type as much1835    /// as we can).1836    ///1837    /// Unfortunately, we cannot allow ourselves to do that. Not only we more often work1838    /// with incomplete code, we also have assists, for example "Generate constant", that1839    /// will assume the inferred type is the expected type even if the expression itself1840    /// cannot be inferred. Therefore, we choose a middle ground: refresh the type,1841    /// but if we return a new var, mark it so that no diagnostics will be issued on it.1842    fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {1843        if ty.is_ty_error() {1844            let var = self.table.next_ty_var(Span::Dummy);18451846            // Suppress future errors on this var. Add more things here when we add more diagnostics.1847            self.vars_emitted_type_must_be_known_for.insert(var.into());18481849            var1850        } else {1851            ty1852        }1853    }18541855    fn infer_body(&mut self, body_expr: ExprId) {1856        match self.return_coercion {1857            Some(_) => self.infer_return(body_expr),1858            None => {1859                _ = self.infer_expr_coerce(1860                    body_expr,1861                    &Expectation::has_type(self.return_ty),1862                    ExprIsRead::Yes,1863                )1864            }1865        }1866    }18671868    fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {1869        self.result.type_of_expr.insert(expr, ty.store());1870    }18711872    pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {1873        if adjustments.is_empty() {1874            return;1875        }1876        match self.result.expr_adjustments.entry(expr) {1877            std::collections::hash_map::Entry::Occupied(mut entry) => {1878                match (&mut entry.get_mut()[..], &adjustments[..]) {1879                    (1880                        [Adjustment { kind: Adjust::NeverToAny, target }],1881                        [.., Adjustment { target: new_target, .. }],1882                    ) => {1883                        // NeverToAny coercion can target any type, so instead of adding a new1884                        // adjustment on top we can change the target.1885                        *target = new_target.clone();1886                    }1887                    _ => {1888                        *entry.get_mut() = adjustments;1889                    }1890                }1891            }1892            std::collections::hash_map::Entry::Vacant(entry) => {1893                entry.insert(adjustments);1894            }1895        }1896    }18971898    pub(crate) fn write_method_resolution(1899        &mut self,1900        expr: ExprId,1901        func: FunctionId,1902        subst: GenericArgs<'db>,1903    ) {1904        self.result.method_resolutions.insert(expr, (func, subst.store()));1905    }19061907    fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) {1908        self.result.variant_resolutions.insert(id, variant);1909    }19101911    fn write_assoc_resolution(1912        &mut self,1913        id: ExprOrPatIdPacked,1914        item: CandidateId,1915        subs: GenericArgs<'db>,1916    ) {1917        self.result.assoc_resolutions.insert(id, (item, subs.store()));1918    }19191920    fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {1921        self.result.type_of_pat.insert(pat, ty.store());1922    }19231924    fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {1925        self.result.type_of_binding.insert(id, ty.store());1926    }19271928    pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {1929        self.diagnostics.push(diagnostic);1930    }19311932    fn record_deferred_call_resolution(1933        &mut self,1934        closure_def_id: ExprId,1935        r: DeferredCallResolution<'db>,1936    ) {1937        self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);1938    }19391940    fn remove_deferred_call_resolutions(1941        &mut self,1942        closure_def_id: ExprId,1943    ) -> Vec<DeferredCallResolution<'db>> {1944        self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()1945    }19461947    fn with_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R) -> R {1948        let mut infer_vars = InferenceTyLoweringVarsCtx {1949            table: &mut self.table,1950            type_of_type_placeholder: &mut self.result.type_of_type_placeholder,1951        };1952        let mut ctx = TyLoweringContext::new(1953            self.db,1954            &self.resolver,1955            self.store,1956            &self.diagnostics,1957            self.store_owner,1958            self.generic_def,1959            &self.generics,1960            LifetimeElisionKind::Infer,1961            self.allow_using_generic_params,1962            &mut infer_vars,1963            &self.defined_anon_consts,1964            LifetimeLoweringMode::LateParam,1965        );1966        f(&mut ctx)1967    }19681969    pub(crate) fn make_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {1970        let ty = self.with_ty_lowering(|ctx| ctx.lower_ty(type_ref));1971        self.process_user_written_ty(ty)1972    }19731974    fn generics(&self) -> &Generics<'db> {1975        self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))1976    }19771978    fn identity_args(&self) -> GenericArgs<'db> {1979        *self.identity_args.get_or_init(|| {1980            GenericArgs::identity_for_item(self.interner(), self.generic_def.into())1981        })1982    }19831984    pub(crate) fn create_anon_const(&mut self, expr: ExprId, expected_ty: Ty<'db>) -> Const<'db> {1985        never!(expected_ty.has_infer(), "cannot have infer vars in an anon const's ty");1986        let konst = create_anon_const(1987            self.interner(),1988            self.store_owner,1989            self.store,1990            expr,1991            &self.resolver,1992            expected_ty,1993            &|| self.generics(),1994            Some(&mut |span| self.table.next_const_var(span)),1995            self.lowering_mode,1996            (!self.allow_using_generic_params).then_some(0),1997            // The situation around body anon consts using generic params is complicated.1998            // rustc disallows them all, except for array repeat expressions. However in another place even repeat exprs1999            // are disallowed, so in practice they cause an error.2000            false,

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.

Generated by searchcode.com · powered by code_get_file + code_get_findings