Only compute specializes query if specialization is enabled in the crate of the specialized impl
This commit is contained in:
parent
1653a2d34a
commit
4b188d9d66
8 changed files with 39 additions and 37 deletions
|
@ -314,6 +314,7 @@ provide! { tcx, def_id, other, cdata,
|
||||||
extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) }
|
extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) }
|
||||||
is_no_builtins => { cdata.root.no_builtins }
|
is_no_builtins => { cdata.root.no_builtins }
|
||||||
symbol_mangling_version => { cdata.root.symbol_mangling_version }
|
symbol_mangling_version => { cdata.root.symbol_mangling_version }
|
||||||
|
specialization_enabled_in => { cdata.root.specialization_enabled_in }
|
||||||
reachable_non_generics => {
|
reachable_non_generics => {
|
||||||
let reachable_non_generics = tcx
|
let reachable_non_generics = tcx
|
||||||
.exported_symbols(cdata.cnum)
|
.exported_symbols(cdata.cnum)
|
||||||
|
|
|
@ -741,6 +741,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
expn_data,
|
expn_data,
|
||||||
expn_hashes,
|
expn_hashes,
|
||||||
def_path_hash_map,
|
def_path_hash_map,
|
||||||
|
specialization_enabled_in: tcx.specialization_enabled_in(LOCAL_CRATE),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,8 @@ pub(crate) struct CrateRoot {
|
||||||
panic_runtime: bool,
|
panic_runtime: bool,
|
||||||
profiler_runtime: bool,
|
profiler_runtime: bool,
|
||||||
symbol_mangling_version: SymbolManglingVersion,
|
symbol_mangling_version: SymbolManglingVersion,
|
||||||
|
|
||||||
|
specialization_enabled_in: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// On-disk representation of `DefId`.
|
/// On-disk representation of `DefId`.
|
||||||
|
|
|
@ -1494,6 +1494,11 @@ rustc_queries! {
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query specialization_enabled_in(cnum: CrateNum) -> bool {
|
||||||
|
desc { "checking whether the crate enabled `specialization`/`min_specialization`" }
|
||||||
|
separate_provide_extern
|
||||||
|
}
|
||||||
|
|
||||||
query specializes(_: (DefId, DefId)) -> bool {
|
query specializes(_: (DefId, DefId)) -> bool {
|
||||||
desc { "computing whether impls specialize one another" }
|
desc { "computing whether impls specialize one another" }
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,6 +623,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
specialization_graph_of: specialize::specialization_graph_provider,
|
specialization_graph_of: specialize::specialization_graph_provider,
|
||||||
specializes: specialize::specializes,
|
specializes: specialize::specializes,
|
||||||
|
specialization_enabled_in: specialize::specialization_enabled_in,
|
||||||
instantiate_and_check_impossible_predicates,
|
instantiate_and_check_impossible_predicates,
|
||||||
is_impossible_associated_item,
|
is_impossible_associated_item,
|
||||||
..*providers
|
..*providers
|
||||||
|
|
|
@ -24,6 +24,7 @@ use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_errors::{codes::*, Diag, EmissionGuarantee};
|
use rustc_errors::{codes::*, Diag, EmissionGuarantee};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
|
use rustc_middle::query::LocalCrate;
|
||||||
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||||
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
|
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
|
||||||
|
@ -136,6 +137,10 @@ pub fn translate_args_with_cause<'tcx>(
|
||||||
source_args.rebase_onto(infcx.tcx, source_impl, target_args)
|
source_args.rebase_onto(infcx.tcx, source_impl, target_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool {
|
||||||
|
tcx.features().specialization || tcx.features().min_specialization
|
||||||
|
}
|
||||||
|
|
||||||
/// Is `impl1` a specialization of `impl2`?
|
/// Is `impl1` a specialization of `impl2`?
|
||||||
///
|
///
|
||||||
/// Specialization is determined by the sets of types to which the impls apply;
|
/// Specialization is determined by the sets of types to which the impls apply;
|
||||||
|
@ -143,31 +148,18 @@ pub fn translate_args_with_cause<'tcx>(
|
||||||
/// to.
|
/// to.
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool {
|
pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool {
|
||||||
// The feature gate should prevent introducing new specializations, but not
|
// We check that the specializing impl comes from a crate that has specialization enabled,
|
||||||
// taking advantage of upstream ones.
|
// or if the specializing impl is marked with `allow_internal_unstable`.
|
||||||
// If specialization is enabled for this crate then no extra checks are needed.
|
//
|
||||||
// If it's not, and either of the `impl`s is local to this crate, then this definitely
|
// We don't really care if the specialized impl (the parent) is in a crate that has
|
||||||
// isn't specializing - unless specialization is enabled for the `impl` span,
|
// specialization enabled, since it's not being specialized, and it's already been checked
|
||||||
// e.g. if it comes from an `allow_internal_unstable` macro
|
// for coherence.
|
||||||
let features = tcx.features();
|
if !tcx.specialization_enabled_in(impl1_def_id.krate) {
|
||||||
let specialization_enabled = features.specialization || features.min_specialization;
|
let span = tcx.def_span(impl1_def_id);
|
||||||
if !specialization_enabled {
|
if !span.allows_unstable(sym::specialization)
|
||||||
if impl1_def_id.is_local() {
|
&& !span.allows_unstable(sym::min_specialization)
|
||||||
let span = tcx.def_span(impl1_def_id);
|
{
|
||||||
if !span.allows_unstable(sym::specialization)
|
return false;
|
||||||
&& !span.allows_unstable(sym::min_specialization)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if impl2_def_id.is_local() {
|
|
||||||
let span = tcx.def_span(impl2_def_id);
|
|
||||||
if !span.allows_unstable(sym::specialization)
|
|
||||||
&& !span.allows_unstable(sym::min_specialization)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
error[E0117]: only traits defined in the current crate can be implemented for primitive types
|
|
||||||
--> $DIR/coherence-impls-copy.rs:5:1
|
|
||||||
|
|
|
||||||
LL | impl Copy for i32 {}
|
|
||||||
| ^^^^^^^^^^^^^^---
|
|
||||||
| | |
|
|
||||||
| | `i32` is not defined in the current crate
|
|
||||||
| impl doesn't use only types from inside the current crate
|
|
||||||
|
|
|
||||||
= note: define and implement a trait or new type instead
|
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
|
error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
|
||||||
--> $DIR/coherence-impls-copy.rs:28:1
|
--> $DIR/coherence-impls-copy.rs:28:1
|
||||||
|
|
|
|
||||||
|
@ -30,6 +19,17 @@ LL | impl Copy for &'static [NotSync] {}
|
||||||
|
|
|
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
|
error[E0117]: only traits defined in the current crate can be implemented for primitive types
|
||||||
|
--> $DIR/coherence-impls-copy.rs:5:1
|
||||||
|
|
|
||||||
|
LL | impl Copy for i32 {}
|
||||||
|
| ^^^^^^^^^^^^^^---
|
||||||
|
| | |
|
||||||
|
| | `i32` is not defined in the current crate
|
||||||
|
| impl doesn't use only types from inside the current crate
|
||||||
|
|
|
||||||
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
error[E0206]: the trait `Copy` cannot be implemented for this type
|
error[E0206]: the trait `Copy` cannot be implemented for this type
|
||||||
--> $DIR/coherence-impls-copy.rs:21:15
|
--> $DIR/coherence-impls-copy.rs:21:15
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue