Unnamed repository; edit this file 'description' to name the repository.
Introduce LoweringMode
| -rw-r--r-- | crates/hir-ty/src/consteval.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/db.rs | 11 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 12 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 35 | ||||
| -rw-r--r-- | crates/hir-ty/src/traits.rs | 4 | ||||
| -rw-r--r-- | crates/hir/src/semantics.rs | 3 | ||||
| -rw-r--r-- | crates/ide/src/predicate_eval.rs | 2 | ||||
| -rw-r--r-- | docs/book/src/contributing/lsp-extensions.md | 2 | ||||
| -rw-r--r-- | xtask/src/tidy.rs | 4 |
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(); |