Unnamed repository; edit this file 'description' to name the repository.
Introduce LoweringMode
Lukas Wirth 6 weeks ago
parent 6218b30 · commit ede5dd0
-rw-r--r--crates/hir-ty/src/consteval.rs8
-rw-r--r--crates/hir-ty/src/db.rs11
-rw-r--r--crates/hir-ty/src/infer.rs12
-rw-r--r--crates/hir-ty/src/lib.rs4
-rw-r--r--crates/hir-ty/src/lower.rs35
-rw-r--r--crates/hir-ty/src/traits.rs4
-rw-r--r--crates/hir/src/semantics.rs3
-rw-r--r--crates/ide/src/predicate_eval.rs2
-rw-r--r--docs/book/src/contributing/lsp-extensions.md2
-rw-r--r--xtask/src/tidy.rs4
10 files changed, 74 insertions, 11 deletions
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 2c43feeb3b..d6580d3752 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -23,6 +23,7 @@ use crate::{
db::{AnonConstId, AnonConstLoc, GeneralConstId, HirDatabase},
display::DisplayTarget,
generics::Generics,
+ lower::LoweringMode,
mir::{MirEvalError, MirLowerError, pad16},
next_solver::{
Allocation, Const, ConstKind, Consts, DbInterner, DefaultAny, GenericArgs, ParamConst,
@@ -305,6 +306,7 @@ pub(crate) enum CreateConstError<'db> {
DoesNotResolve,
ConstHasGenerics,
UnderscoreExpr,
+ AnonConstInterningDisabled,
TypeMismatch {
#[expect(unused, reason = "will need this for diagnostics")]
actual: Ty<'db>,
@@ -355,6 +357,7 @@ pub(crate) fn create_anon_const<'a, 'db>(
expected_ty: Ty<'db>,
generics: &dyn Fn() -> &'a Generics<'db>,
create_var: Option<&mut dyn FnMut(Span) -> Const<'db>>,
+ lowering_mode: LoweringMode,
forbid_params_after: Option<u32>,
) -> Result<Const<'db>, CreateConstError<'db>> {
match &store[expr] {
@@ -374,6 +377,10 @@ pub(crate) fn create_anon_const<'a, 'db>(
konst
}
_ => {
+ let Some(token) = lowering_mode.allow_tracked_structs() else {
+ return Err(CreateConstError::AnonConstInterningDisabled);
+ };
+
let allow_using_generic_params = forbid_params_after.is_none();
let konst = AnonConstId::new(
interner.db,
@@ -383,6 +390,7 @@ pub(crate) fn create_anon_const<'a, 'db>(
ty: StoredEarlyBinder::bind(expected_ty.store()),
allow_using_generic_params,
},
+ token,
);
let args = if allow_using_generic_params {
GenericArgs::identity_for_item(interner, owner.generic_def(interner.db).into())
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index b8752e32c8..baf8bbd56f 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -27,7 +27,7 @@ use crate::{
consteval::ConstEvalError,
dyn_compatibility::DynCompatibilityViolation,
layout::{Layout, LayoutError},
- lower::{GenericDefaults, TypeAliasBounds},
+ lower::{GenericDefaults, TrackedStructToken, TypeAliasBounds},
mir::{BorrowckResult, MirBody, MirLowerError},
next_solver::{
Allocation, Clause, EarlyBinder, GenericArgs, ParamEnv, PolyFnSig, StoredClauses,
@@ -421,13 +421,20 @@ pub struct AnonConstLoc {
pub(crate) allow_using_generic_params: bool,
}
-#[salsa_macros::interned(debug, no_lifetime, revisions = usize::MAX)]
+#[salsa_macros::interned(debug, no_lifetime, revisions = usize::MAX, constructor = new_)]
#[derive(PartialOrd, Ord)]
pub struct AnonConstId {
#[returns(ref)]
pub loc: AnonConstLoc,
}
+impl AnonConstId {
+ pub(crate) fn new(db: &dyn DefDatabase, loc: AnonConstLoc, token: TrackedStructToken) -> Self {
+ _ = token;
+ AnonConstId::new_(db, loc)
+ }
+}
+
impl HasModule for AnonConstId {
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
self.loc(db).owner.module(db)
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 0a6e2635bb..616701f80c 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -91,7 +91,8 @@ use crate::{
unify::resolve_completely::WriteBackCtxt,
},
lower::{
- ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic,
+ ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, LoweringMode,
+ diagnostics::TyLoweringDiagnostic,
},
method_resolution::CandidateId,
next_solver::{
@@ -116,13 +117,14 @@ use cast::{CastCheck, CastError};
/// The entry point of type inference.
fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult {
- infer_query_with_inspect(db, def, None)
+ infer_query_with_inspect(db, def, None, LoweringMode::Analysis)
}
pub fn infer_query_with_inspect<'db>(
db: &'db dyn HirDatabase,
def: DefWithBodyId,
inspect: Option<ObligationInspector<'db>>,
+ lowering_mode: LoweringMode,
) -> InferenceResult {
let _p = tracing::info_span!("infer_query").entered();
let resolver = def.resolver(db);
@@ -135,6 +137,7 @@ pub fn infer_query_with_inspect<'db>(
&body.store,
resolver,
true,
+ lowering_mode,
);
if let Some(inspect) = inspect {
@@ -202,6 +205,7 @@ fn infer_anon_const_query(db: &dyn HirDatabase, def: AnonConstId) -> InferenceRe
store,
resolver,
loc.allow_using_generic_params,
+ LoweringMode::Analysis,
);
ctx.infer_expr(
@@ -1236,6 +1240,7 @@ pub(crate) struct InferenceContext<'body, 'db> {
pub(crate) store_owner: ExpressionStoreOwnerId,
pub(crate) generic_def: GenericDefId,
pub(crate) store: &'body ExpressionStore,
+ pub(crate) lowering_mode: LoweringMode,
/// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
/// and resolve the path via its methods. This will ensure proper error reporting.
pub(crate) resolver: Resolver<'db>,
@@ -1335,6 +1340,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
store: &'body ExpressionStore,
resolver: Resolver<'db>,
allow_using_generic_params: bool,
+ lowering_mode: LoweringMode,
) -> Self {
let trait_env = db.trait_environment(generic_def);
let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), store_owner);
@@ -1369,6 +1375,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
vars_emitted_type_must_be_known_for: FxHashSet::default(),
deferred_call_resolutions: FxHashMap::default(),
defined_anon_consts: RefCell::new(ThinVec::new()),
+ lowering_mode,
}
}
@@ -1969,6 +1976,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
expected_ty,
&|| self.generics(),
Some(&mut |span| self.table.next_const_var(span)),
+ self.lowering_mode,
(!(allow_using_generic_params && self.allow_using_generic_params)).then_some(0),
);
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 71140ec557..cc48ba06db 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -111,8 +111,8 @@ pub use infer::{
};
pub use lower::{
FieldType, GenericDefaults, GenericDefaultsRef, GenericPredicates, ImplTraits,
- LifetimeElisionKind, TyDefId, TyLoweringContext, TyLoweringInferVarsCtx, TyLoweringResult,
- ValueTyDefId, diagnostics::*,
+ LifetimeElisionKind, LoweringMode, TyDefId, TyLoweringContext, TyLoweringInferVarsCtx,
+ TyLoweringResult, ValueTyDefId, diagnostics::*,
};
pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db};
pub use target_feature::TargetFeatures;
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index a997ee5975..fae63ddc2d 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -199,6 +199,33 @@ pub trait TyLoweringInferVarsCtx<'db> {
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum LoweringMode {
+ Analysis,
+ Ide,
+}
+
+pub(crate) use self::tracked_struct_token::TrackedStructToken;
+mod tracked_struct_token {
+ use super::LoweringMode;
+
+ /// A token that is required to construct tracked structs.
+ /// This exists to prevent one from accidentally creating a tracked struct outside of a query which may happen for some codepaths.
+ pub(crate) struct TrackedStructToken {
+ // #[non_exhaustive] doesn't work for us here, we want it module focused.
+ _private: (),
+ }
+
+ impl LoweringMode {
+ pub(crate) fn allow_tracked_structs(self) -> Option<TrackedStructToken> {
+ match self {
+ LoweringMode::Analysis => Some(TrackedStructToken { _private: () }),
+ LoweringMode::Ide => None,
+ }
+ }
+ }
+}
+
pub struct TyLoweringContext<'db, 'a> {
pub db: &'db dyn HirDatabase,
pub(crate) interner: DbInterner<'db>,
@@ -211,6 +238,7 @@ pub struct TyLoweringContext<'db, 'a> {
generics: &'a OnceCell<Generics<'db>>,
in_binders: DebruijnIndex,
impl_trait_mode: ImplTraitLoweringState,
+ interning_mode: LoweringMode,
/// Tracks types with explicit `?Sized` bounds.
pub(crate) unsized_types: FxHashSet<Ty<'db>>,
pub(crate) diagnostics: ThinVec<TyLoweringDiagnostic>,
@@ -247,6 +275,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
store,
in_binders,
impl_trait_mode,
+ interning_mode: LoweringMode::Analysis,
unsized_types: FxHashSet::default(),
diagnostics: ThinVec::new(),
lifetime_elision,
@@ -261,6 +290,11 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
self.lifetime_elision = lifetime_elision;
}
+ pub(crate) fn with_interning_mode(mut self, interning_mode: LoweringMode) -> Self {
+ self.interning_mode = interning_mode;
+ self
+ }
+
pub(crate) fn with_debruijn<T>(
&mut self,
debruijn: DebruijnIndex,
@@ -390,6 +424,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
const_type,
&|| self.generics.get_or_init(|| generics(self.db, self.generic_def)),
create_var,
+ self.interning_mode,
self.forbid_params_after,
);
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs
index 446226c355..4c76ae901d 100644
--- a/crates/hir-ty/src/traits.rs
+++ b/crates/hir-ty/src/traits.rs
@@ -27,6 +27,7 @@ use crate::{
LifetimeElisionKind, Span, TyLoweringContext,
db::HirDatabase,
generics::Generics,
+ lower::LoweringMode,
next_solver::{
DbInterner, GenericArgs, ParamEnv, StoredClauses, Ty, TyKind,
infer::{
@@ -188,7 +189,8 @@ pub fn where_predicate_must_hold<'db>(
generic_def,
&generics,
LifetimeElisionKind::Infer,
- );
+ )
+ .with_interning_mode(LoweringMode::Ide);
let clauses =
ctx.lower_where_predicate(predicate, false).map(|(clause, _)| clause).collect::<Vec<_>>();
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 0277eb6219..dd4cc7b0df 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -32,7 +32,7 @@ use hir_expand::{
name::AsName,
};
use hir_ty::{
- InferBodyId, InferenceResult,
+ InferBodyId, InferenceResult, LoweringMode,
db::AnonConstId,
diagnostics::unsafe_operations,
infer_query_with_inspect,
@@ -2601,6 +2601,7 @@ impl<'db> SemanticsImpl<'db> {
RESULT.with(|ctx| ctx.borrow_mut().push(data));
}
}),
+ LoweringMode::Ide,
);
let data: Vec<ProofTreeData> =
RESULT.with(|data| data.borrow_mut().drain(..).collect());
diff --git a/crates/ide/src/predicate_eval.rs b/crates/ide/src/predicate_eval.rs
index 8ae340bd95..c6ec4ca18e 100644
--- a/crates/ide/src/predicate_eval.rs
+++ b/crates/ide/src/predicate_eval.rs
@@ -1,3 +1,5 @@
+//! Evaluates type predicates at a given position in the source code.
+
use hir::{PredicateEvaluationResult, Semantics};
use ide_db::{FilePosition, RootDatabase};
use syntax::{AstNode, SourceFile, ast};
diff --git a/docs/book/src/contributing/lsp-extensions.md b/docs/book/src/contributing/lsp-extensions.md
index b74c40c422..a3189402a9 100644
--- a/docs/book/src/contributing/lsp-extensions.md
+++ b/docs/book/src/contributing/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp/ext.rs hash: 57ae57d2a5c65b14
+lsp/ext.rs hash: cec81c987f189e83
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs
index 939a563afd..33145a8834 100644
--- a/xtask/src/tidy.rs
+++ b/xtask/src/tidy.rs
@@ -21,13 +21,13 @@ impl Tidy {
}
fn check_lsp_extensions_docs(sh: &Shell) {
- let expected_hash = {
+ let actual_hash = {
let lsp_ext_rs =
sh.read_file(project_root().join("crates/rust-analyzer/src/lsp/ext.rs")).unwrap();
stable_hash(lsp_ext_rs.as_str())
};
- let actual_hash = {
+ let expected_hash = {
let lsp_extensions_md = sh
.read_file(project_root().join("docs/book/src/contributing/lsp-extensions.md"))
.unwrap();