Skip to content

Commit c8472a7

Browse files
Merge pull request #20921 from ChayimFriedman2/specialization-ns2
Avoid calling `specializes()` query on crates that do not define `#![feature(specialization)]`
2 parents 311d22c + 727d2aa commit c8472a7

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

crates/hir-ty/src/specialization.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
// and indeed I was unable to cause cycles even with erroneous code. However, in r-a we can
2121
// create a cycle if there is an error in the impl's where clauses. I believe well formed code
2222
// cannot create a cycle, but a cycle handler is required nevertheless.
23-
fn specializes_cycle(
23+
fn specializes_query_cycle(
2424
_db: &dyn HirDatabase,
2525
_specializing_impl_def_id: ImplId,
2626
_parent_impl_def_id: ImplId,
@@ -39,31 +39,14 @@ fn specializes_cycle(
3939
/// `parent_impl_def_id` is a const impl (conditionally based off of some `[const]`
4040
/// bounds), then `specializing_impl_def_id` must also be const for the same
4141
/// set of types.
42-
#[salsa::tracked(cycle_result = specializes_cycle)]
43-
pub(crate) fn specializes(
42+
#[salsa::tracked(cycle_result = specializes_query_cycle)]
43+
fn specializes_query(
4444
db: &dyn HirDatabase,
4545
specializing_impl_def_id: ImplId,
4646
parent_impl_def_id: ImplId,
4747
) -> bool {
48-
let module = specializing_impl_def_id.loc(db).container;
49-
50-
// We check that the specializing impl comes from a crate that has specialization enabled.
51-
//
52-
// We don't really care if the specialized impl (the parent) is in a crate that has
53-
// specialization enabled, since it's not being specialized.
54-
//
55-
// rustc also checks whether the specializing impls comes from a macro marked
56-
// `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]`
57-
// is an internal feature, std is not using it for specialization nor is likely to
58-
// ever use it, and we don't have the span information necessary to replicate that.
59-
let def_map = crate_def_map(db, module.krate());
60-
if !def_map.is_unstable_feature_enabled(&sym::specialization)
61-
&& !def_map.is_unstable_feature_enabled(&sym::min_specialization)
62-
{
63-
return false;
64-
}
65-
66-
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
48+
let trait_env = db.trait_environment(specializing_impl_def_id.into());
49+
let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
6750

6851
let specializing_impl_signature = db.impl_signature(specializing_impl_def_id);
6952
let parent_impl_signature = db.impl_signature(parent_impl_def_id);
@@ -87,7 +70,7 @@ pub(crate) fn specializes(
8770

8871
// create a parameter environment corresponding to an identity instantiation of the specializing impl,
8972
// i.e. the most generic instantiation of the specializing impl.
90-
let param_env = db.trait_environment(specializing_impl_def_id.into()).env;
73+
let param_env = trait_env.env;
9174

9275
// Create an infcx, taking the predicates of the specializing impl as assumptions:
9376
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
@@ -148,3 +131,31 @@ pub(crate) fn specializes(
148131

149132
true
150133
}
134+
135+
// This function is used to avoid creating the query for crates that does not define `#![feature(specialization)]`,
136+
// as the solver is calling this a lot, and creating the query consumes a lot of memory.
137+
pub(crate) fn specializes(
138+
db: &dyn HirDatabase,
139+
specializing_impl_def_id: ImplId,
140+
parent_impl_def_id: ImplId,
141+
) -> bool {
142+
let module = specializing_impl_def_id.loc(db).container;
143+
144+
// We check that the specializing impl comes from a crate that has specialization enabled.
145+
//
146+
// We don't really care if the specialized impl (the parent) is in a crate that has
147+
// specialization enabled, since it's not being specialized.
148+
//
149+
// rustc also checks whether the specializing impls comes from a macro marked
150+
// `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]`
151+
// is an internal feature, std is not using it for specialization nor is likely to
152+
// ever use it, and we don't have the span information necessary to replicate that.
153+
let def_map = crate_def_map(db, module.krate());
154+
if !def_map.is_unstable_feature_enabled(&sym::specialization)
155+
&& !def_map.is_unstable_feature_enabled(&sym::min_specialization)
156+
{
157+
return false;
158+
}
159+
160+
specializes_query(db, specializing_impl_def_id, parent_impl_def_id)
161+
}

0 commit comments

Comments
 (0)