mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 10:18:25 +00:00
Auto merge of #126772 - cuviper:beta-next, r=cuviper
[beta] backports - Only compute `specializes` query if (min)specialization is enabled in the crate of the specializing impl #126139 - Add pub struct with allow(dead_code) into worklist #126315 - ci: Update centos:7 to use vault repos #126352 r? cuviper
This commit is contained in:
commit
64a1fe6711
@ -314,6 +314,7 @@ provide! { tcx, def_id, other, cdata,
|
||||
extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) }
|
||||
is_no_builtins => { cdata.root.no_builtins }
|
||||
symbol_mangling_version => { cdata.root.symbol_mangling_version }
|
||||
specialization_enabled_in => { cdata.root.specialization_enabled_in }
|
||||
reachable_non_generics => {
|
||||
let reachable_non_generics = tcx
|
||||
.exported_symbols(cdata.cnum)
|
||||
|
@ -741,6 +741,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
expn_data,
|
||||
expn_hashes,
|
||||
def_path_hash_map,
|
||||
specialization_enabled_in: tcx.specialization_enabled_in(LOCAL_CRATE),
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -290,6 +290,8 @@ pub(crate) struct CrateRoot {
|
||||
panic_runtime: bool,
|
||||
profiler_runtime: bool,
|
||||
symbol_mangling_version: SymbolManglingVersion,
|
||||
|
||||
specialization_enabled_in: bool,
|
||||
}
|
||||
|
||||
/// On-disk representation of `DefId`.
|
||||
|
@ -1494,6 +1494,11 @@ rustc_queries! {
|
||||
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 {
|
||||
desc { "computing whether impls specialize one another" }
|
||||
}
|
||||
|
@ -898,7 +898,7 @@ fn create_and_seed_worklist(
|
||||
match tcx.def_kind(id) {
|
||||
DefKind::Impl { .. } => false,
|
||||
DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
|
||||
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()),
|
||||
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
|
||||
_ => true
|
||||
})
|
||||
.map(|id| (id, ComesFromAllowExpect::No))
|
||||
|
@ -623,6 +623,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
specialization_graph_of: specialize::specialization_graph_provider,
|
||||
specializes: specialize::specializes,
|
||||
specialization_enabled_in: specialize::specialization_enabled_in,
|
||||
instantiate_and_check_impossible_predicates,
|
||||
is_impossible_associated_item,
|
||||
..*providers
|
||||
|
@ -24,6 +24,7 @@ use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{codes::*, Diag, EmissionGuarantee};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::query::LocalCrate;
|
||||
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||
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)
|
||||
}
|
||||
|
||||
pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool {
|
||||
tcx.features().specialization || tcx.features().min_specialization
|
||||
}
|
||||
|
||||
/// Is `impl1` a specialization of `impl2`?
|
||||
///
|
||||
/// 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.
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
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
|
||||
// taking advantage of upstream ones.
|
||||
// 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
|
||||
// isn't specializing - unless specialization is enabled for the `impl` span,
|
||||
// e.g. if it comes from an `allow_internal_unstable` macro
|
||||
let features = tcx.features();
|
||||
let specialization_enabled = features.specialization || features.min_specialization;
|
||||
if !specialization_enabled {
|
||||
if impl1_def_id.is_local() {
|
||||
let span = tcx.def_span(impl1_def_id);
|
||||
if !span.allows_unstable(sym::specialization)
|
||||
&& !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;
|
||||
}
|
||||
// We check that the specializing impl comes from a crate that has specialization enabled,
|
||||
// or if the specializing impl is marked with `allow_internal_unstable`.
|
||||
//
|
||||
// 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, and it's already been checked
|
||||
// for coherence.
|
||||
if !tcx.specialization_enabled_in(impl1_def_id.krate) {
|
||||
let span = tcx.def_span(impl1_def_id);
|
||||
if !span.allows_unstable(sym::specialization)
|
||||
&& !span.allows_unstable(sym::min_specialization)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,12 @@ FROM centos:7
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault.
|
||||
RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \
|
||||
-e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!'
|
||||
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
|
||||
|
||||
RUN yum upgrade -y && \
|
||||
yum install -y epel-release && \
|
||||
yum install -y \
|
||||
automake \
|
||||
bzip2 \
|
||||
|
@ -6,8 +6,12 @@ FROM centos:7
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault.
|
||||
RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \
|
||||
-e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!'
|
||||
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
|
||||
|
||||
RUN yum upgrade -y && \
|
||||
yum install -y epel-release && \
|
||||
yum install -y \
|
||||
automake \
|
||||
bzip2 \
|
||||
|
@ -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`
|
||||
--> $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
|
||||
|
||||
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
|
||||
--> $DIR/coherence-impls-copy.rs:21:15
|
||||
|
|
||||
|
33
tests/ui/lint/dead-code/allow-unconstructed-pub-struct.rs
Normal file
33
tests/ui/lint/dead-code/allow-unconstructed-pub-struct.rs
Normal file
@ -0,0 +1,33 @@
|
||||
//@ check-pass
|
||||
|
||||
mod ffi {
|
||||
use super::*;
|
||||
|
||||
extern "C" {
|
||||
pub fn DomPromise_AddRef(promise: *const Promise);
|
||||
pub fn DomPromise_Release(promise: *const Promise);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(unused)]
|
||||
pub struct Promise {
|
||||
private: [u8; 0],
|
||||
__nosync: ::std::marker::PhantomData<::std::rc::Rc<u8>>,
|
||||
}
|
||||
|
||||
pub unsafe trait RefCounted {
|
||||
unsafe fn addref(&self);
|
||||
unsafe fn release(&self);
|
||||
}
|
||||
|
||||
unsafe impl RefCounted for Promise {
|
||||
unsafe fn addref(&self) {
|
||||
ffi::DomPromise_AddRef(self)
|
||||
}
|
||||
unsafe fn release(&self) {
|
||||
ffi::DomPromise_Release(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
17
tests/ui/specialization/anyid-repro-125197.rs
Normal file
17
tests/ui/specialization/anyid-repro-125197.rs
Normal file
@ -0,0 +1,17 @@
|
||||
//@ aux-build: anyid-repro-125197.rs
|
||||
//@ check-pass
|
||||
|
||||
// Makes sure that we don't check `specializes(impl1, impl2)` for a pair of impls that don't
|
||||
// actually participate in specialization. Since <https://github.com/rust-lang/rust/pull/122791>,
|
||||
// we don't treat inductive cycles as errors -- so we may need to winnow more pairs of impls, and
|
||||
// we try to winnow impls in favor of other impls. However, if we're *inside* the `specializes`
|
||||
// query, then may have a query cycle if we call `specializes` again!
|
||||
|
||||
extern crate anyid_repro_125197;
|
||||
use anyid_repro_125197::AnyId;
|
||||
|
||||
fn main() {
|
||||
let x = "hello, world";
|
||||
let y: AnyId = x.into();
|
||||
let _ = y == x;
|
||||
}
|
26
tests/ui/specialization/auxiliary/anyid-repro-125197.rs
Normal file
26
tests/ui/specialization/auxiliary/anyid-repro-125197.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use std::fmt::Display;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct AnyId(());
|
||||
|
||||
impl PartialEq<Self> for AnyId {
|
||||
fn eq(&self, _: &Self) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Identifier> PartialEq<T> for AnyId {
|
||||
fn eq(&self, _: &T) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Identifier> From<T> for AnyId {
|
||||
fn from(_: T) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Identifier: Display + 'static {}
|
||||
|
||||
impl<T> Identifier for T where T: PartialEq + Display + 'static {}
|
Loading…
x
Reference in New Issue
Block a user