Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
8 changes: 4 additions & 4 deletions crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down
6 changes: 1 addition & 5 deletions crates/hir-ty/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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`
Expand Down
12 changes: 6 additions & 6 deletions crates/hir-ty/src/diagnostics/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/diagnostics/unsafe_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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:?}(")?,
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
49 changes: 31 additions & 18 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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>>,
Expand All @@ -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>>,

Expand All @@ -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.
///
Expand All @@ -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 {
Expand Down Expand Up @@ -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>]> {
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 4 additions & 3 deletions crates/hir-ty/src/infer/closure/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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,
Expand All @@ -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>>,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_type_ir::{
use triomphe::Arc;

use crate::{
TraitEnvironment,
InferenceResult, TraitEnvironment,
consteval::try_const_usize,
db::HirDatabase,
next_solver::{
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-ty/src/layout/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use test_fixture::WithFixture;
use triomphe::Arc;

use crate::{
InferenceResult,
db::HirDatabase,
layout::{Layout, LayoutError},
next_solver::{DbInterner, GenericArgs},
Expand Down Expand Up @@ -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()))
})
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Loading