Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/hir.rs2
-rw-r--r--crates/hir-def/src/lib.rs8
-rw-r--r--crates/hir-ty/src/db.rs6
-rw-r--r--crates/hir-ty/src/diagnostics/expr.rs12
-rw-r--r--crates/hir-ty/src/diagnostics/unsafe_check.rs4
-rw-r--r--crates/hir-ty/src/display.rs4
-rw-r--r--crates/hir-ty/src/drop.rs4
-rw-r--r--crates/hir-ty/src/infer.rs49
-rw-r--r--crates/hir-ty/src/infer/closure/analysis.rs7
-rw-r--r--crates/hir-ty/src/layout.rs4
-rw-r--r--crates/hir-ty/src/layout/tests.rs3
-rw-r--r--crates/hir-ty/src/method_resolution.rs2
-rw-r--r--crates/hir-ty/src/mir.rs14
-rw-r--r--crates/hir-ty/src/mir/borrowck.rs4
-rw-r--r--crates/hir-ty/src/mir/eval.rs10
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs3
-rw-r--r--crates/hir-ty/src/mir/lower.rs8
-rw-r--r--crates/hir-ty/src/opaques.rs6
-rw-r--r--crates/hir-ty/src/tests.rs41
-rw-r--r--crates/hir-ty/src/tests/closure_captures.rs3
-rw-r--r--crates/hir-ty/src/tests/incremental.rs40
-rw-r--r--crates/hir-ty/src/traits.rs2
-rw-r--r--crates/hir-ty/src/utils.rs20
-rw-r--r--crates/hir/src/lib.rs17
-rw-r--r--crates/hir/src/semantics.rs9
-rw-r--r--crates/hir/src/source_analyzer.rs6
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs6
27 files changed, 168 insertions, 126 deletions
diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs
index 66eade2245..53be0de7d9 100644
--- a/crates/hir-def/src/hir.rs
+++ b/crates/hir-def/src/hir.rs
@@ -45,7 +45,7 @@ pub type PatId = Idx<Pat>;
// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts
// are local to the body.
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update)]
pub enum ExprOrPatId {
ExprId(ExprId),
PatId(PatId),
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index eceadd6742..ad247e0d68 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -600,17 +600,17 @@ impl HasModule for ModuleId {
/// An ID of a module, **local** to a `DefMap`.
pub type LocalModuleId = Idx<nameres::ModuleData>;
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct FieldId {
// FIXME: Store this as an erased `salsa::Id` to save space
pub parent: VariantId,
pub local_id: LocalFieldId,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct TupleId(pub u32);
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct TupleFieldId {
pub tuple: TupleId,
pub index: u32,
@@ -1014,7 +1014,7 @@ impl From<VariantId> for AttrDefId {
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)]
pub enum VariantId {
EnumVariantId(EnumVariantId),
StructId(StructId),
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 40e58aaa9e..df058711a6 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -12,7 +12,7 @@ use salsa::plumbing::AsId;
use triomphe::Arc;
use crate::{
- ImplTraitId, InferenceResult, TraitEnvironment, TyDefId, ValueTyDefId,
+ ImplTraitId, TraitEnvironment, TyDefId, ValueTyDefId,
consteval::ConstEvalError,
dyn_compatibility::DynCompatibilityViolation,
layout::{Layout, LayoutError},
@@ -23,10 +23,6 @@ use crate::{
#[query_group::query_group]
pub trait HirDatabase: DefDatabase + std::fmt::Debug {
- #[salsa::invoke(crate::infer::infer_query)]
- #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
- fn infer<'db>(&'db self, def: DefWithBodyId) -> Arc<InferenceResult<'db>>;
-
// region:mir
// FXME: Collapse `mir_body_for_closure` into `mir_body`
diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs
index b84b70c197..719c7daf42 100644
--- a/crates/hir-ty/src/diagnostics/expr.rs
+++ b/crates/hir-ty/src/diagnostics/expr.rs
@@ -76,7 +76,7 @@ impl BodyValidationDiagnostic {
validate_lints: bool,
) -> Vec<BodyValidationDiagnostic> {
let _p = tracing::info_span!("BodyValidationDiagnostic::collect").entered();
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let body = db.body(owner);
let env = db.trait_environment_for_body(owner);
let interner = DbInterner::new_with(db, env.krate, env.block);
@@ -99,7 +99,7 @@ impl BodyValidationDiagnostic {
struct ExprValidator<'db> {
owner: DefWithBodyId,
body: Arc<Body>,
- infer: Arc<InferenceResult<'db>>,
+ infer: &'db InferenceResult<'db>,
env: Arc<TraitEnvironment<'db>>,
diagnostics: Vec<BodyValidationDiagnostic>,
validate_lints: bool,
@@ -124,7 +124,7 @@ impl<'db> ExprValidator<'db> {
for (id, expr) in body.exprs() {
if let Some((variant, missed_fields, true)) =
- record_literal_missing_fields(db, &self.infer, id, expr)
+ record_literal_missing_fields(db, self.infer, id, expr)
{
self.diagnostics.push(BodyValidationDiagnostic::RecordMissingFields {
record: Either::Left(id),
@@ -155,7 +155,7 @@ impl<'db> ExprValidator<'db> {
for (id, pat) in body.pats() {
if let Some((variant, missed_fields, true)) =
- record_pattern_missing_fields(db, &self.infer, id, pat)
+ record_pattern_missing_fields(db, self.infer, id, pat)
{
self.diagnostics.push(BodyValidationDiagnostic::RecordMissingFields {
record: Either::Right(id),
@@ -240,7 +240,7 @@ impl<'db> ExprValidator<'db> {
.as_reference()
.map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
.unwrap_or(false))
- && types_of_subpatterns_do_match(arm.pat, &self.body, &self.infer)
+ && types_of_subpatterns_do_match(arm.pat, &self.body, self.infer)
{
// If we had a NotUsefulMatchArm diagnostic, we could
// check the usefulness of each pattern as we added it
@@ -388,7 +388,7 @@ impl<'db> ExprValidator<'db> {
pat: PatId,
have_errors: &mut bool,
) -> DeconstructedPat<'a, 'db> {
- let mut patcx = match_check::PatCtxt::new(self.db(), &self.infer, &self.body);
+ let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, &self.body);
let pattern = patcx.lower_pattern(pat);
let pattern = cx.lower_pat(&pattern);
if !patcx.errors.is_empty() {
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 8ac7ab19cd..6160962e3b 100644
--- a/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -42,7 +42,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() };
let body = db.body(def);
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(db, def);
let mut callback = |diag| match diag {
UnsafeDiagnostic::UnsafeOperation { node, inside_unsafe_block, reason } => {
if inside_unsafe_block == InsideUnsafeBlock::No {
@@ -55,7 +55,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
}
}
};
- let mut visitor = UnsafeVisitor::new(db, &infer, &body, def, &mut callback);
+ let mut visitor = UnsafeVisitor::new(db, infer, &body, def, &mut callback);
visitor.walk_expr(body.body_expr);
if !is_unsafe {
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 2c6d7c68d1..3bb8be02aa 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -47,7 +47,7 @@ use stdx::never;
use triomphe::Arc;
use crate::{
- CallableDefId, FnAbi, ImplTraitId, MemoryMap, TraitEnvironment, consteval,
+ CallableDefId, FnAbi, ImplTraitId, InferenceResult, MemoryMap, TraitEnvironment, consteval,
db::{HirDatabase, InternedClosure, InternedCoroutine},
generics::generics,
layout::Layout,
@@ -1398,7 +1398,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
if let Some(sig) = sig {
let sig = sig.skip_binder();
let InternedClosure(def, _) = db.lookup_intern_closure(id);
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(db, def);
let (_, kind) = infer.closure_info(id);
match f.closure_style {
ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs
index 124e7b279f..d76de4b8ca 100644
--- a/crates/hir-ty/src/drop.rs
+++ b/crates/hir-ty/src/drop.rs
@@ -7,7 +7,7 @@ use stdx::never;
use triomphe::Arc;
use crate::{
- TraitEnvironment, consteval,
+ InferenceResult, TraitEnvironment, consteval,
method_resolution::TraitImpls,
next_solver::{
DbInterner, SimplifiedType, Ty, TyKind,
@@ -137,7 +137,7 @@ fn has_drop_glue_impl<'db>(
TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited),
TyKind::Closure(closure_id, subst) => {
let owner = db.lookup_intern_closure(closure_id.0).0;
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let (captures, _) = infer.closure_info(closure_id.0);
let env = db.trait_environment_for_body(owner);
captures
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 36b7015817..ab173799bc 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -54,10 +54,10 @@ use rustc_type_ir::{
AliasTyKind, TypeFoldable,
inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _},
};
+use salsa::Update;
use span::Edition;
use stdx::never;
use thin_vec::ThinVec;
-use triomphe::Arc;
use crate::{
ImplTraitId, IncorrectGenericsLenKind, PathLoweringDiagnostic, TargetFeatures,
@@ -95,7 +95,7 @@ use cast::{CastCheck, CastError};
pub(crate) use closure::analysis::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
/// The entry point of type inference.
-pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult<'_>> {
+fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {
let _p = tracing::info_span!("infer_query").entered();
let resolver = def.resolver(db);
let body = db.body(def);
@@ -159,17 +159,14 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
ctx.handle_opaque_type_uses();
- Arc::new(ctx.resolve_all())
+ ctx.resolve_all()
}
-pub(crate) fn infer_cycle_result(
- db: &dyn HirDatabase,
- _: DefWithBodyId,
-) -> Arc<InferenceResult<'_>> {
- Arc::new(InferenceResult {
+fn infer_cycle_result(db: &dyn HirDatabase, _: DefWithBodyId) -> InferenceResult<'_> {
+ InferenceResult {
has_errors: true,
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
- })
+ }
}
/// Binding modes inferred for patterns.
@@ -199,7 +196,7 @@ pub enum InferenceTyDiagnosticSource {
Signature,
}
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone, Update)]
pub enum InferenceDiagnostic<'db> {
NoSuchField {
field: ExprOrPatId,
@@ -293,7 +290,7 @@ pub enum InferenceDiagnostic<'db> {
}
/// A mismatch between an expected and an inferred type.
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash, Update)]
pub struct TypeMismatch<'db> {
pub expected: Ty<'db>,
pub actual: Ty<'db>,
@@ -339,7 +336,7 @@ pub struct TypeMismatch<'db> {
/// At some point, of course, `Box` should move out of the compiler, in which
/// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
/// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Update)]
pub struct Adjustment<'db> {
#[type_visitable(ignore)]
#[type_foldable(identity)]
@@ -476,9 +473,10 @@ pub enum PointerCast {
/// When you add a field that stores types (including `Substitution` and the like), don't forget
/// `resolve_completely()`'ing them in `InferenceContext::resolve_all()`. Inference variables must
/// not appear in the final inference result.
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug, Update)]
pub struct InferenceResult<'db> {
/// For each method call expr, records the function it resolves to.
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))]
method_resolutions: FxHashMap<ExprId, (FunctionId, GenericArgs<'db>)>,
/// For each field access expr, records the field it resolves to.
field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
@@ -489,15 +487,20 @@ pub struct InferenceResult<'db> {
/// Whenever a tuple field expression access a tuple field, we allocate a tuple id in
/// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of
/// that which allows us to resolve a [`TupleFieldId`]s type.
- tuple_field_access_types: FxHashMap<TupleId, Tys<'db>>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* thinvec is technically update */)))]
+ tuple_field_access_types: ThinVec<Tys<'db>>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))]
pub(crate) type_of_expr: ArenaMap<ExprId, Ty<'db>>,
/// For each pattern record the type it resolves to.
///
/// **Note**: When a pattern type is resolved it may still contain
/// unresolved or missing subpatterns or subpatterns of mismatched types.
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* pat id is technically update */)))]
pub(crate) type_of_pat: ArenaMap<PatId, Ty<'db>>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* binding id is technically update */)))]
pub(crate) type_of_binding: ArenaMap<BindingId, Ty<'db>>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* type ref id is technically update */)))]
pub(crate) type_of_type_placeholder: FxHashMap<TypeRefId, Ty<'db>>,
pub(crate) type_of_opaque: FxHashMap<InternedOpaqueTyId, Ty<'db>>,
@@ -508,14 +511,17 @@ pub struct InferenceResult<'db> {
// Which will then mark this field.
pub(crate) has_errors: bool,
/// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead.
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* thinvec is technically update */)))]
diagnostics: ThinVec<InferenceDiagnostic<'db>>,
/// Interned `Error` type to return references to.
// FIXME: Remove this.
error_ty: Ty<'db>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))]
pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment<'db>]>>,
/// Stores the types which were implicitly dereferenced in pattern binding modes.
+ #[update(unsafe(with(crate::utils::unsafe_update_eq /* pat id is technically update */)))]
pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty<'db>>>,
/// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.
///
@@ -539,6 +545,14 @@ pub struct InferenceResult<'db> {
pub(crate) coercion_casts: FxHashSet<ExprId>,
}
+#[salsa::tracked]
+impl<'db> InferenceResult<'db> {
+ #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
+ pub fn for_body(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {
+ infer_query(db, def)
+ }
+}
+
impl<'db> InferenceResult<'db> {
fn new(error_ty: Ty<'db>) -> Self {
Self {
@@ -672,7 +686,7 @@ impl<'db> InferenceResult<'db> {
}
pub fn tuple_field_access_type(&self, id: TupleId) -> Tys<'db> {
- self.tuple_field_access_types[&id]
+ self.tuple_field_access_types[id.0 as usize]
}
pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty<'db>]> {
@@ -1135,9 +1149,8 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
pat_adjustments.shrink_to_fit();
result.tuple_field_access_types = tuple_field_accesses_rev
.into_iter()
- .enumerate()
- .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
- .inspect(|(_, subst)| {
+ .map(|subst| table.resolve_completely(subst))
+ .inspect(|subst| {
*has_errors = *has_errors || subst.iter().any(|ty| ty.references_non_lt_error());
})
.collect();
diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs
index 935c5a5078..251e7f7cf6 100644
--- a/crates/hir-ty/src/infer/closure/analysis.rs
+++ b/crates/hir-ty/src/infer/closure/analysis.rs
@@ -31,10 +31,10 @@ use crate::{
// The below functions handle capture and closure kind (Fn, FnMut, ..)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)]
pub(crate) struct HirPlace<'db> {
pub(crate) local: BindingId,
- pub(crate) projections: Vec<ProjectionElem<Infallible, Ty<'db>>>,
+ pub(crate) projections: Vec<ProjectionElem<'db, Infallible>>,
}
impl<'db> HirPlace<'db> {
@@ -76,7 +76,7 @@ pub enum CaptureKind {
ByValue,
}
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)]
pub struct CapturedItem<'db> {
pub(crate) place: HirPlace<'db>,
pub(crate) kind: CaptureKind,
@@ -87,6 +87,7 @@ pub struct CapturedItem<'db> {
/// copy all captures of the inner closure to the outer closure, and then we may
/// truncate them, and we want the correct span to be reported.
span_stacks: SmallVec<[SmallVec<[MirSpan; 3]>; 3]>,
+ #[update(unsafe(with(crate::utils::unsafe_update_eq)))]
pub(crate) ty: EarlyBinder<'db, Ty<'db>>,
}
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index 658172d4b0..0a6bb4900f 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -21,7 +21,7 @@ use rustc_type_ir::{
use triomphe::Arc;
use crate::{
- TraitEnvironment,
+ InferenceResult, TraitEnvironment,
consteval::try_const_usize,
db::HirDatabase,
next_solver::{
@@ -322,7 +322,7 @@ pub fn layout_of_ty_query<'db>(
}
TyKind::Closure(id, args) => {
let def = db.lookup_intern_closure(id.0);
- let infer = db.infer(def.0);
+ let infer = InferenceResult::for_body(db, def.0);
let (captures, _) = infer.closure_info(id.0);
let fields = captures
.iter()
diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs
index 2ce0a67920..878813a696 100644
--- a/crates/hir-ty/src/layout/tests.rs
+++ b/crates/hir-ty/src/layout/tests.rs
@@ -9,6 +9,7 @@ use test_fixture::WithFixture;
use triomphe::Arc;
use crate::{
+ InferenceResult,
db::HirDatabase,
layout::{Layout, LayoutError},
next_solver::{DbInterner, GenericArgs},
@@ -136,7 +137,7 @@ fn eval_expr(
.find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal")
.unwrap()
.0;
- let infer = db.infer(function_id.into());
+ let infer = InferenceResult::for_body(&db, function_id.into());
let goal_ty = infer.type_of_binding[b];
db.layout_of_ty(goal_ty, db.trait_environment(function_id.into()))
})
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 8da6baba5d..c104ab6a78 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -81,7 +81,7 @@ pub struct MethodResolutionContext<'a, 'db> {
pub unstable_features: &'a MethodResolutionUnstableFeatures,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub enum CandidateId {
FunctionId(FunctionId),
ConstId(ConstId),
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index 317578fcd9..f47e3b7a30 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -140,21 +140,21 @@ impl<'db> Operand<'db> {
}
}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum ProjectionElem<V, T> {
+#[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)]
+pub enum ProjectionElem<'db, V: PartialEq> {
Deref,
Field(Either<FieldId, TupleFieldId>),
// FIXME: get rid of this, and use FieldId for tuples and closures
ClosureField(usize),
- Index(V),
+ Index(#[update(unsafe(with(crate::utils::unsafe_update_eq)))] V),
ConstantIndex { offset: u64, from_end: bool },
Subslice { from: u64, to: u64 },
//Downcast(Option<Symbol>, VariantIdx),
- OpaqueCast(T),
+ OpaqueCast(Ty<'db>),
}
-impl<V, T> ProjectionElem<V, T> {
- pub fn projected_ty<'db>(
+impl<'db, V: PartialEq> ProjectionElem<'db, V> {
+ pub fn projected_ty(
&self,
infcx: &InferCtxt<'db>,
mut base: Ty<'db>,
@@ -254,7 +254,7 @@ impl<V, T> ProjectionElem<V, T> {
}
}
-type PlaceElem<'db> = ProjectionElem<LocalId<'db>, Ty<'db>>;
+type PlaceElem<'db> = ProjectionElem<'db, LocalId<'db>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ProjectionId(u32);
diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs
index acd064598a..12a08397fd 100644
--- a/crates/hir-ty/src/mir/borrowck.rs
+++ b/crates/hir-ty/src/mir/borrowck.rs
@@ -12,7 +12,7 @@ use stdx::never;
use triomphe::Arc;
use crate::{
- TraitEnvironment,
+ InferenceResult, TraitEnvironment,
db::{HirDatabase, InternedClosure, InternedClosureId},
display::DisplayTarget,
mir::OperandKind,
@@ -121,7 +121,7 @@ fn make_fetch_closure_field<'db>(
) -> impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db> + use<'db> {
|c: InternedClosureId, subst: GenericArgs<'db>, f: usize| {
let InternedClosure(def, _) = db.lookup_intern_closure(c);
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(db, def);
let (captures, _) = infer.closure_info(c);
let parent_subst = subst.split_closure_args_untupled().parent_args;
let interner = DbInterner::new_no_crate(db);
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 7e3a120c06..68c9fb851d 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -34,7 +34,7 @@ use syntax::{SyntaxNodePtr, TextRange};
use triomphe::Arc;
use crate::{
- CallableDefId, ComplexMemoryMap, MemoryMap, TraitEnvironment,
+ CallableDefId, ComplexMemoryMap, InferenceResult, MemoryMap, TraitEnvironment,
consteval::{self, ConstEvalError, try_const_usize},
db::{HirDatabase, InternedClosure, InternedClosureId},
display::{ClosureStyle, DisplayTarget, HirDisplay},
@@ -722,7 +722,7 @@ impl<'db> Evaluator<'db> {
ty,
|c, subst, f| {
let InternedClosure(def, _) = self.db.lookup_intern_closure(c);
- let infer = self.db.infer(def);
+ let infer = InferenceResult::for_body(self.db, def);
let (captures, _) = infer.closure_info(c);
let parent_subst = subst.split_closure_args_untupled().parent_args;
captures
@@ -883,7 +883,8 @@ impl<'db> Evaluator<'db> {
OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
OperandKind::Constant { konst: _, ty } => *ty,
&OperandKind::Static(s) => {
- let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr];
+ let ty =
+ InferenceResult::for_body(self.db, s.into())[self.db.body(s.into()).body_expr];
Ty::new_ref(
self.interner(),
Region::new_static(self.interner()),
@@ -2809,7 +2810,8 @@ impl<'db> Evaluator<'db> {
})?;
self.allocate_const_in_heap(locals, konst)?
} else {
- let ty = self.db.infer(st.into())[self.db.body(st.into()).body_expr];
+ let ty =
+ InferenceResult::for_body(self.db, st.into())[self.db.body(st.into()).body_expr];
let Some((size, align)) = self.size_align_of(ty, locals)? else {
not_supported!("unsized extern static");
};
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index cf08c82408..591c12ec24 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -10,6 +10,7 @@ use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike, Ty as _};
use stdx::never;
use crate::{
+ InferenceResult,
display::DisplayTarget,
drop::{DropGlue, has_drop_glue},
mir::eval::{
@@ -167,7 +168,7 @@ impl<'db> Evaluator<'db> {
};
let addr = Address::from_bytes(arg.get(self)?)?;
let InternedClosure(closure_owner, _) = self.db.lookup_intern_closure(id.0);
- let infer = self.db.infer(closure_owner);
+ let infer = InferenceResult::for_body(self.db, closure_owner);
let (captures, _) = infer.closure_info(id.0);
let layout = self.layout(self_ty)?;
let db = self.db;
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index be2291a62c..5454e8b753 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -2111,7 +2111,7 @@ pub fn mir_body_for_closure_query<'db>(
) -> Result<'db, Arc<MirBody<'db>>> {
let InternedClosure(owner, expr) = db.lookup_intern_closure(closure);
let body = db.body(owner);
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let Expr::Closure { args, body: root, .. } = &body[expr] else {
implementation_error!("closure expression is not closure");
};
@@ -2119,7 +2119,7 @@ pub fn mir_body_for_closure_query<'db>(
implementation_error!("closure expression is not closure");
};
let (captures, kind) = infer.closure_info(closure);
- let mut ctx = MirLowerCtx::new(db, owner, &body, &infer);
+ let mut ctx = MirLowerCtx::new(db, owner, &body, infer);
// 0 is return local
ctx.result.locals.alloc(Local { ty: infer[*root] });
let closure_local = ctx.result.locals.alloc(Local {
@@ -2249,8 +2249,8 @@ pub fn mir_body_query<'db>(
};
let _p = tracing::info_span!("mir_body_query", ?detail).entered();
let body = db.body(def);
- let infer = db.infer(def);
- let mut result = lower_to_mir(db, def, &body, &infer, body.body_expr)?;
+ let infer = InferenceResult::for_body(db, def);
+ let mut result = lower_to_mir(db, def, &body, infer, body.body_expr)?;
result.shrink_to_fit();
Ok(Arc::new(result))
}
diff --git a/crates/hir-ty/src/opaques.rs b/crates/hir-ty/src/opaques.rs
index fa99013d5e..3a3e0040e5 100644
--- a/crates/hir-ty/src/opaques.rs
+++ b/crates/hir-ty/src/opaques.rs
@@ -9,7 +9,7 @@ use rustc_type_ir::inherent::Ty as _;
use syntax::ast;
use crate::{
- ImplTraitId,
+ ImplTraitId, InferenceResult,
db::{HirDatabase, InternedOpaqueTyId},
lower::{ImplTraitIdx, ImplTraits},
next_solver::{
@@ -94,7 +94,7 @@ pub(crate) fn rpit_hidden_types<'db>(
db: &'db dyn HirDatabase,
function: FunctionId,
) -> ArenaMap<ImplTraitIdx<'db>, EarlyBinder<'db, Ty<'db>>> {
- let infer = db.infer(function.into());
+ let infer = InferenceResult::for_body(db, function.into());
let mut result = ArenaMap::new();
for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) {
result.insert(opaque, EarlyBinder::bind(hidden_type));
@@ -128,7 +128,7 @@ pub(crate) fn tait_hidden_types<'db>(
let mut result = ArenaMap::with_capacity(taits_count);
for defining_body in defining_bodies {
- let infer = db.infer(defining_body);
+ let infer = InferenceResult::for_body(db, defining_body);
for (&opaque, &hidden_type) in &infer.type_of_opaque {
let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else {
continue;
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index 002d58961d..1acb0b82b1 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -38,7 +38,6 @@ use triomphe::Arc;
use crate::{
InferenceResult,
- db::HirDatabase,
display::{DisplayTarget, HirDisplay},
infer::{Adjustment, TypeMismatch},
next_solver::Ty,
@@ -148,7 +147,7 @@ fn check_impl(
for (def, krate) in defs {
let display_target = DisplayTarget::from_crate(&db, krate);
let (body, body_source_map) = db.body_with_source_map(def);
- let inference_result = db.infer(def);
+ let inference_result = InferenceResult::for_body(&db, def);
for (pat, mut ty) in inference_result.type_of_pat.iter() {
if let Pat::Bind { id, .. } = body[pat] {
@@ -319,7 +318,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
crate::attach_db(&db, || {
let mut buf = String::new();
- let mut infer_def = |inference_result: Arc<InferenceResult<'_>>,
+ let mut infer_def = |inference_result: &InferenceResult<'_>,
body: Arc<Body>,
body_source_map: Arc<BodySourceMap>,
krate: Crate| {
@@ -443,7 +442,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
});
for (def, krate) in defs {
let (body, source_map) = db.body_with_source_map(def);
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(&db, def);
infer_def(infer, body, source_map, krate);
}
@@ -595,13 +594,16 @@ fn salsa_bug() {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
- db.infer(match def {
- ModuleDefId::FunctionId(it) => it.into(),
- ModuleDefId::EnumVariantId(it) => it.into(),
- ModuleDefId::ConstId(it) => it.into(),
- ModuleDefId::StaticId(it) => it.into(),
- _ => return,
- });
+ InferenceResult::for_body(
+ &db,
+ match def {
+ ModuleDefId::FunctionId(it) => it.into(),
+ ModuleDefId::EnumVariantId(it) => it.into(),
+ ModuleDefId::ConstId(it) => it.into(),
+ ModuleDefId::StaticId(it) => it.into(),
+ _ => return,
+ },
+ );
});
});
@@ -636,13 +638,16 @@ fn salsa_bug() {
let module = db.module_for_file(pos.file_id.file_id(&db));
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
- db.infer(match def {
- ModuleDefId::FunctionId(it) => it.into(),
- ModuleDefId::EnumVariantId(it) => it.into(),
- ModuleDefId::ConstId(it) => it.into(),
- ModuleDefId::StaticId(it) => it.into(),
- _ => return,
- });
+ InferenceResult::for_body(
+ &db,
+ match def {
+ ModuleDefId::FunctionId(it) => it.into(),
+ ModuleDefId::EnumVariantId(it) => it.into(),
+ ModuleDefId::ConstId(it) => it.into(),
+ ModuleDefId::StaticId(it) => it.into(),
+ _ => return,
+ },
+ );
});
})
}
diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs
index 8425c0dd89..ef71681636 100644
--- a/crates/hir-ty/src/tests/closure_captures.rs
+++ b/crates/hir-ty/src/tests/closure_captures.rs
@@ -7,6 +7,7 @@ use syntax::{AstNode, AstPtr};
use test_fixture::WithFixture;
use crate::{
+ InferenceResult,
db::HirDatabase,
display::{DisplayTarget, HirDisplay},
mir::MirSpan,
@@ -34,7 +35,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec
hir_def::ModuleDefId::StaticId(it) => it.into(),
_ => continue,
};
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(&db, def);
let db = &db;
captures_info.extend(infer.closure_info.iter().flat_map(
|(closure_id, (captures, _))| {
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index 87291b619a..fd564a300d 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -4,7 +4,7 @@ use hir_def::{DefWithBodyId, ModuleDefId};
use salsa::EventKind;
use test_fixture::WithFixture;
-use crate::{db::HirDatabase, method_resolution::TraitImpls, test_db::TestDB};
+use crate::{InferenceResult, method_resolution::TraitImpls, test_db::TestDB};
use super::visit_module;
@@ -24,11 +24,11 @@ fn foo() -> i32 {
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
if let ModuleDefId::FunctionId(it) = def {
- db.infer(it.into());
+ InferenceResult::for_body(&db, it.into());
}
});
},
- &[("infer_shim", 1)],
+ &[("InferenceResult < 'db >::for_body_", 1)],
expect_test::expect![[r#"
[
"crate_local_def_map",
@@ -36,7 +36,7 @@ fn foo() -> i32 {
"ast_id_map_shim",
"parse_shim",
"real_span_map_shim",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_shim",
"function_signature_with_source_map_shim",
"AttrFlags::query_",
@@ -68,11 +68,11 @@ fn foo() -> i32 {
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
if let ModuleDefId::FunctionId(it) = def {
- db.infer(it.into());
+ InferenceResult::for_body(&db, it.into());
}
});
},
- &[("infer_shim", 0)],
+ &[("InferenceResult < 'db >::for_body_", 0)],
expect_test::expect![[r#"
[
"parse_shim",
@@ -111,11 +111,11 @@ fn baz() -> i32 {
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
if let ModuleDefId::FunctionId(it) = def {
- db.infer(it.into());
+ InferenceResult::for_body(&db, it.into());
}
});
},
- &[("infer_shim", 3)],
+ &[("InferenceResult < 'db >::for_body_", 3)],
expect_test::expect![[r#"
[
"crate_local_def_map",
@@ -123,7 +123,7 @@ fn baz() -> i32 {
"ast_id_map_shim",
"parse_shim",
"real_span_map_shim",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_shim",
"function_signature_with_source_map_shim",
"AttrFlags::query_",
@@ -137,7 +137,7 @@ fn baz() -> i32 {
"GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_shim",
"function_signature_with_source_map_shim",
"body_shim",
@@ -146,7 +146,7 @@ fn baz() -> i32 {
"GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
"expr_scopes_shim",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_shim",
"function_signature_with_source_map_shim",
"body_shim",
@@ -180,11 +180,11 @@ fn baz() -> i32 {
let crate_def_map = module.def_map(&db);
visit_module(&db, crate_def_map, module.local_id, &mut |def| {
if let ModuleDefId::FunctionId(it) = def {
- db.infer(it.into());
+ InferenceResult::for_body(&db, it.into());
}
});
},
- &[("infer_shim", 1)],
+ &[("InferenceResult < 'db >::for_body_", 1)],
expect_test::expect![[r#"
[
"parse_shim",
@@ -202,7 +202,7 @@ fn baz() -> i32 {
"function_signature_shim",
"body_with_source_map_shim",
"body_shim",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"expr_scopes_shim",
"function_signature_with_source_map_shim",
"function_signature_shim",
@@ -558,7 +558,7 @@ fn main() {
});
for def in defs {
- let _inference_result = db.infer(def);
+ let _inference_result = InferenceResult::for_body(&db, def);
}
},
&[("trait_solve_shim", 0)],
@@ -574,7 +574,7 @@ fn main() {
"body_with_source_map_shim",
"AttrFlags::query_",
"ImplItems::of_",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"trait_signature_shim",
"trait_signature_with_source_map_shim",
"AttrFlags::query_",
@@ -591,7 +591,7 @@ fn main() {
"GenericPredicates < 'db >::query_with_diagnostics_",
"GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_shim",
"function_signature_with_source_map_shim",
"trait_environment_shim",
@@ -655,7 +655,7 @@ fn main() {
});
for def in defs {
- let _inference_result = db.infer(def);
+ let _inference_result = InferenceResult::for_body(&db, def);
}
},
&[("trait_solve_shim", 0)],
@@ -671,7 +671,7 @@ fn main() {
"AttrFlags::query_",
"body_shim",
"ImplItems::of_",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"AttrFlags::query_",
"trait_signature_with_source_map_shim",
"AttrFlags::query_",
@@ -686,7 +686,7 @@ fn main() {
"GenericPredicates < 'db >::query_with_diagnostics_",
"GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
- "infer_shim",
+ "InferenceResult < 'db >::for_body_",
"function_signature_with_source_map_shim",
"GenericPredicates < 'db >::query_with_diagnostics_",
"ImplTraits < 'db >::return_type_impl_traits_",
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs
index 386a95eeb7..bd723ef0c4 100644
--- a/crates/hir-ty/src/traits.rs
+++ b/crates/hir-ty/src/traits.rs
@@ -151,7 +151,7 @@ pub fn next_trait_solve_in_ctxt<'db, 'a>(
res
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, salsa::Update)]
pub enum FnTrait {
// Warning: Order is important. If something implements `x` it should also implement
// `y` if `y <= x`.
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index efc0ac2bf8..7dd73f1e7a 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -25,6 +25,26 @@ use crate::{
mir::pad16,
};
+/// SAFETY: `old_pointer` must be valid for unique writes
+pub(crate) unsafe fn unsafe_update_eq<T>(old_pointer: *mut T, new_value: T) -> bool
+where
+ T: PartialEq,
+{
+ // SAFETY: Caller obligation
+ let old_ref: &mut T = unsafe { &mut *old_pointer };
+
+ if *old_ref != new_value {
+ *old_ref = new_value;
+ true
+ } else {
+ // Subtle but important: Eq impls can be buggy or define equality
+ // in surprising ways. If it says that the value has not changed,
+ // we do not modify the existing value, and thus do not have to
+ // update the revision, as downstream code will not see the new value.
+ false
+ }
+}
+
pub(crate) fn fn_traits(lang_items: &LangItems) -> impl Iterator<Item = TraitId> + '_ {
[lang_items.Fn, lang_items.FnMut, lang_items.FnOnce].into_iter().flatten()
}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index a79dea1949..40d48d4bbc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -76,8 +76,8 @@ use hir_expand::{
AstId, MacroCallKind, RenderedExpandError, ValueResult, proc_macro::ProcMacroKind,
};
use hir_ty::{
- GenericPredicates, TraitEnvironment, TyDefId, TyLoweringDiagnostic, ValueTyDefId,
- all_super_traits, autoderef, check_orphan_rules,
+ GenericPredicates, InferenceResult, TraitEnvironment, TyDefId, TyLoweringDiagnostic,
+ ValueTyDefId, all_super_traits, autoderef, check_orphan_rules,
consteval::try_const_usize,
db::{InternedClosureId, InternedCoroutineId},
diagnostics::BodyValidationDiagnostic,
@@ -1239,8 +1239,7 @@ impl TupleField {
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
let interner = DbInterner::new_no_crate(db);
- let ty = db
- .infer(self.owner)
+ let ty = InferenceResult::for_body(db, self.owner)
.tuple_field_access_type(self.tuple)
.as_slice()
.get(self.index as usize)
@@ -1956,7 +1955,7 @@ impl DefWithBody {
expr_store_diagnostics(db, acc, &source_map);
- let infer = db.infer(self.into());
+ let infer = InferenceResult::for_body(db, self.into());
for d in infer.diagnostics() {
acc.extend(AnyDiagnostic::inference_diagnostic(
db,
@@ -3844,7 +3843,7 @@ impl Local {
pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
let def = self.parent;
- let infer = db.infer(def);
+ let infer = InferenceResult::for_body(db, def);
let ty = infer[self.binding_id];
Type::new(db, def, ty)
}
@@ -4540,7 +4539,7 @@ impl<'db> Closure<'db> {
return Vec::new();
};
let owner = db.lookup_intern_closure(id).0;
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let info = infer.closure_info(id);
info.0
.iter()
@@ -4555,7 +4554,7 @@ impl<'db> Closure<'db> {
return Vec::new();
};
let owner = db.lookup_intern_closure(id).0;
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let (captures, _) = infer.closure_info(id);
let env = db.trait_environment_for_body(owner);
captures
@@ -4568,7 +4567,7 @@ impl<'db> Closure<'db> {
match self.id {
AnyClosureId::ClosureId(id) => {
let owner = db.lookup_intern_closure(id).0;
- let infer = db.infer(owner);
+ let infer = InferenceResult::for_body(db, owner);
let info = infer.closure_info(id);
info.1.into()
}
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 3d4859424f..82e60bff5e 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -28,6 +28,7 @@ use hir_expand::{
name::AsName,
};
use hir_ty::{
+ InferenceResult,
diagnostics::{unsafe_operations, unsafe_operations_for_body},
next_solver::DbInterner,
};
@@ -1777,9 +1778,9 @@ impl<'db> SemanticsImpl<'db> {
pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet<ExprOrPatSource> {
let def = DefWithBodyId::from(def);
let (body, source_map) = self.db.body_with_source_map(def);
- let infer = self.db.infer(def);
+ let infer = InferenceResult::for_body(self.db, def);
let mut res = FxHashSet::default();
- unsafe_operations_for_body(self.db, &infer, def, &body, &mut |node| {
+ unsafe_operations_for_body(self.db, infer, def, &body, &mut |node| {
if let Ok(node) = source_map.expr_or_pat_syntax(node) {
res.insert(node);
}
@@ -1793,12 +1794,12 @@ impl<'db> SemanticsImpl<'db> {
let Some(def) = self.body_for(block.syntax()) else { return Vec::new() };
let def = def.into();
let (body, source_map) = self.db.body_with_source_map(def);
- let infer = self.db.infer(def);
+ let infer = InferenceResult::for_body(self.db, def);
let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else {
return Vec::new();
};
let mut res = Vec::default();
- unsafe_operations(self.db, &infer, def, &body, block, &mut |node, _| {
+ unsafe_operations(self.db, infer, def, &body, block, &mut |node, _| {
if let Ok(node) = source_map.expr_or_pat_syntax(node) {
res.push(node);
}
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index f29e4ccf60..6def6774e1 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -78,7 +78,7 @@ pub(crate) enum BodyOrSig<'db> {
def: DefWithBodyId,
body: Arc<Body>,
source_map: Arc<BodySourceMap>,
- infer: Option<Arc<InferenceResult<'db>>>,
+ infer: Option<&'db InferenceResult<'db>>,
},
// To be folded into body once it is considered one
VariantFields {
@@ -101,7 +101,7 @@ impl<'db> SourceAnalyzer<'db> {
node: InFile<&SyntaxNode>,
offset: Option<TextSize>,
) -> SourceAnalyzer<'db> {
- Self::new_for_body_(db, def, node, offset, Some(db.infer(def)))
+ Self::new_for_body_(db, def, node, offset, Some(InferenceResult::for_body(db, def)))
}
pub(crate) fn new_for_body_no_infer(
@@ -118,7 +118,7 @@ impl<'db> SourceAnalyzer<'db> {
def: DefWithBodyId,
node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
offset: Option<TextSize>,
- infer: Option<Arc<InferenceResult<'db>>>,
+ infer: Option<&'db InferenceResult<'db>>,
) -> SourceAnalyzer<'db> {
let (body, source_map) = db.body_with_source_map(def);
let scopes = db.expr_scopes(def);
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index ef73b00db4..767672fc2f 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -20,6 +20,7 @@ use hir_def::{
expr_store::BodySourceMap,
hir::{ExprId, PatId},
};
+use hir_ty::InferenceResult;
use ide::{
Analysis, AnalysisHost, AnnotationConfig, DiagnosticsConfig, Edition, InlayFieldsToResolve,
InlayHintsConfig, LineCol, RootDatabase,
@@ -745,7 +746,7 @@ impl flags::AnalysisStats {
.par_iter()
.map_with(db.clone(), |snap, &body| {
snap.body(body.into());
- snap.infer(body.into());
+ InferenceResult::for_body(snap, body.into());
})
.count();
eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed());
@@ -802,7 +803,8 @@ impl flags::AnalysisStats {
}
bar.set_message(msg);
let body = db.body(body_id.into());
- let inference_result = catch_unwind(AssertUnwindSafe(|| db.infer(body_id.into())));
+ let inference_result =
+ catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_id.into())));
let inference_result = match inference_result {
Ok(inference_result) => inference_result,
Err(p) => {