@@ -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