Merge pull request #20921 from ChayimFriedman2/specialization-ns2
Avoid calling `specializes()` query on crates that do not define `#![feature(specialization)]`
diff --git a/crates/hir-ty/src/specialization.rs b/crates/hir-ty/src/specialization.rs
index 611947b..f4ee4de 100644
--- a/crates/hir-ty/src/specialization.rs
+++ b/crates/hir-ty/src/specialization.rs
@@ -20,7 +20,7 @@
// and indeed I was unable to cause cycles even with erroneous code. However, in r-a we can
// create a cycle if there is an error in the impl's where clauses. I believe well formed code
// cannot create a cycle, but a cycle handler is required nevertheless.
-fn specializes_cycle(
+fn specializes_query_cycle(
_db: &dyn HirDatabase,
_specializing_impl_def_id: ImplId,
_parent_impl_def_id: ImplId,
@@ -39,31 +39,14 @@
/// `parent_impl_def_id` is a const impl (conditionally based off of some `[const]`
/// bounds), then `specializing_impl_def_id` must also be const for the same
/// set of types.
-#[salsa::tracked(cycle_result = specializes_cycle)]
-pub(crate) fn specializes(
+#[salsa::tracked(cycle_result = specializes_query_cycle)]
+fn specializes_query(
db: &dyn HirDatabase,
specializing_impl_def_id: ImplId,
parent_impl_def_id: ImplId,
) -> bool {
- let module = specializing_impl_def_id.loc(db).container;
-
- // We check that the specializing impl comes from a crate that has specialization enabled.
- //
- // We don't really care if the specialized impl (the parent) is in a crate that has
- // specialization enabled, since it's not being specialized.
- //
- // rustc also checks whether the specializing impls comes from a macro marked
- // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]`
- // is an internal feature, std is not using it for specialization nor is likely to
- // ever use it, and we don't have the span information necessary to replicate that.
- let def_map = crate_def_map(db, module.krate());
- if !def_map.is_unstable_feature_enabled(&sym::specialization)
- && !def_map.is_unstable_feature_enabled(&sym::min_specialization)
- {
- return false;
- }
-
- let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
+ let trait_env = db.trait_environment(specializing_impl_def_id.into());
+ let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
let specializing_impl_signature = db.impl_signature(specializing_impl_def_id);
let parent_impl_signature = db.impl_signature(parent_impl_def_id);
@@ -87,7 +70,7 @@
// create a parameter environment corresponding to an identity instantiation of the specializing impl,
// i.e. the most generic instantiation of the specializing impl.
- let param_env = db.trait_environment(specializing_impl_def_id.into()).env;
+ let param_env = trait_env.env;
// Create an infcx, taking the predicates of the specializing impl as assumptions:
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
@@ -148,3 +131,31 @@
true
}
+
+// This function is used to avoid creating the query for crates that does not define `#![feature(specialization)]`,
+// as the solver is calling this a lot, and creating the query consumes a lot of memory.
+pub(crate) fn specializes(
+ db: &dyn HirDatabase,
+ specializing_impl_def_id: ImplId,
+ parent_impl_def_id: ImplId,
+) -> bool {
+ let module = specializing_impl_def_id.loc(db).container;
+
+ // We check that the specializing impl comes from a crate that has specialization enabled.
+ //
+ // We don't really care if the specialized impl (the parent) is in a crate that has
+ // specialization enabled, since it's not being specialized.
+ //
+ // rustc also checks whether the specializing impls comes from a macro marked
+ // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]`
+ // is an internal feature, std is not using it for specialization nor is likely to
+ // ever use it, and we don't have the span information necessary to replicate that.
+ let def_map = crate_def_map(db, module.krate());
+ if !def_map.is_unstable_feature_enabled(&sym::specialization)
+ && !def_map.is_unstable_feature_enabled(&sym::min_specialization)
+ {
+ return false;
+ }
+
+ specializes_query(db, specializing_impl_def_id, parent_impl_def_id)
+}