Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ impl<S: Stage> NoArgsAttributeParser<S> for DenyExplicitImplParser {
const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl;
}

pub(crate) struct DoNotImplementViaObjectParser;
impl<S: Stage> NoArgsAttributeParser<S> for DoNotImplementViaObjectParser {
const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object];
pub(crate) struct DynIncompatibleTraitParser;
impl<S: Stage> NoArgsAttributeParser<S> for DynIncompatibleTraitParser {
const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::DynIncompatibleTrait;
}

// Specialization
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ use crate::attributes::stability::{
use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser};
use crate::attributes::traits::{
AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser,
DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser,
PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser,
DynIncompatibleTraitParser, FundamentalParser, MarkerParser, ParenSugarParser, PointeeParser,
SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser,
UnsafeSpecializationMarkerParser,
};
use crate::attributes::transparency::TransparencyParser;
Expand Down Expand Up @@ -220,7 +220,7 @@ attribute_parsers!(
Single<WithoutArgs<ConstStabilityIndirectParser>>,
Single<WithoutArgs<CoroutineParser>>,
Single<WithoutArgs<DenyExplicitImplParser>>,
Single<WithoutArgs<DoNotImplementViaObjectParser>>,
Single<WithoutArgs<DynIncompatibleTraitParser>>,
Single<WithoutArgs<ExportStableParser>>,
Single<WithoutArgs<FfiConstParser>>,
Single<WithoutArgs<FfiPureParser>>,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,13 +1289,13 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls"
),
rustc_attr!(
rustc_do_not_implement_via_object,
rustc_dyn_incompatible_trait,
AttributeType::Normal,
template!(Word),
ErrorFollowing,
EncodeCrossCrate::No,
"`#[rustc_do_not_implement_via_object]` opts out of the automatic trait impl for trait objects \
(`impl Trait for dyn Trait`)"
"`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \
even if it otherwise satisfies the requirements to be dyn-compatible."
),
rustc_attr!(
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word),
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,15 +520,15 @@ pub enum AttributeKind {
/// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
Deprecation { deprecation: Deprecation, span: Span },

/// Represents `#[rustc_do_not_implement_via_object]`.
DoNotImplementViaObject(Span),

/// Represents [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },

/// Represents `#[rustc_dummy]`.
Dummy,

/// Represents `#[rustc_dyn_incompatible_trait]`.
DynIncompatibleTrait(Span),

/// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute).
ExportName {
/// The name to export this item with.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ impl AttributeKind {
DebuggerVisualizer(..) => No,
DenyExplicitImpl(..) => No,
Deprecation { .. } => Yes,
DoNotImplementViaObject(..) => No,
DocComment { .. } => Yes,
Dummy => No,
DynIncompatibleTrait(..) => Yes, // FIXME: is this needed?
ExportName { .. } => Yes,
ExportStable => No,
FfiConst(..) => No,
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,7 @@ fn check_object_overlap<'tcx>(
// This is a WF error tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
} else {
let mut supertrait_def_ids = elaborate::supertrait_def_ids(tcx, component_def_id);
if supertrait_def_ids
.any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object)
{
if supertrait_def_ids.any(|d| d == trait_def_id) {
let span = tcx.def_span(impl_def_id);
return Err(struct_span_code_err!(
tcx.dcx(),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
});

let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_));
let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_));
let force_dyn_incompatible =
find_attr!(attrs, AttributeKind::DynIncompatibleTrait(span) => *span);

ty::TraitDef {
def_id: def_id.to_def_id(),
Expand All @@ -1011,7 +1012,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
skip_boxed_slice_during_method_dispatch,
specialization_kind,
must_implement_one_of,
implement_via_object,
force_dyn_incompatible,
deny_explicit_impl,
}
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ pub enum DynCompatibilityViolation {
/// `Self: Sized` declared on the trait.
SizedSelf(SmallVec<[Span; 1]>),

/// Trait is marked `#[rustc_dyn_incompatible_trait]`.
ExplicitlyDynIncompatible(SmallVec<[Span; 1]>),

/// Supertrait reference references `Self` an in illegal location
/// (e.g., `trait Foo : Bar<Self>`).
SupertraitSelf(SmallVec<[Span; 1]>),
Expand All @@ -781,6 +784,9 @@ impl DynCompatibilityViolation {
pub fn error_msg(&self) -> Cow<'static, str> {
match self {
DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
DynCompatibilityViolation::ExplicitlyDynIncompatible(_) => {
"it opted out of dyn-compatibility".into()
}
DynCompatibilityViolation::SupertraitSelf(spans) => {
if spans.iter().any(|sp| *sp != DUMMY_SP) {
"it uses `Self` as a type parameter".into()
Expand Down Expand Up @@ -854,6 +860,7 @@ impl DynCompatibilityViolation {
pub fn solution(&self) -> DynCompatibilityViolationSolution {
match self {
DynCompatibilityViolation::SizedSelf(_)
| DynCompatibilityViolation::ExplicitlyDynIncompatible(_)
| DynCompatibilityViolation::SupertraitSelf(_)
| DynCompatibilityViolation::SupertraitNonLifetimeBinder(..)
| DynCompatibilityViolation::SupertraitConst(_) => {
Expand Down Expand Up @@ -887,6 +894,7 @@ impl DynCompatibilityViolation {
match self {
DynCompatibilityViolation::SupertraitSelf(spans)
| DynCompatibilityViolation::SizedSelf(spans)
| DynCompatibilityViolation::ExplicitlyDynIncompatible(spans)
| DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans)
| DynCompatibilityViolation::SupertraitConst(spans) => spans.clone(),
DynCompatibilityViolation::AssocConst(_, span)
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.trait_def(def_id).is_fundamental
}

fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).implement_via_object
}

fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
self.trait_def(trait_def_id).safety.is_unsafe()
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_span::Span;
use rustc_span::symbol::sym;
use tracing::debug;

Expand Down Expand Up @@ -69,10 +70,9 @@ pub struct TraitDef {
/// must be implemented.
pub must_implement_one_of: Option<Box<[Ident]>>,

/// Whether to add a builtin `dyn Trait: Trait` implementation.
/// This is enabled for all traits except ones marked with
/// `#[rustc_do_not_implement_via_object]`.
pub implement_via_object: bool,
/// Whether the trait should be considered dyn-incompatible, even if it otherwise
/// satisfies the requirements to be dyn-compatible.
pub force_dyn_incompatible: Option<Span>,

/// Whether a trait is fully built-in, and any implementation is disallowed.
/// This only applies to built-in traits, and is marked via
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,6 @@ where
candidates: &mut Vec<Candidate<I>>,
) {
let cx = self.cx();
if !cx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(cx)) {
return;
}

let self_ty = goal.predicate.self_ty();
let bounds = match self_ty.kind() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::SkipDuringMethodDispatch { .. }
| AttributeKind::Coinductive(..)
| AttributeKind::DenyExplicitImpl(..)
| AttributeKind::DoNotImplementViaObject(..)
| AttributeKind::DynIncompatibleTrait(..)
| AttributeKind::SpecializationTrait(..)
| AttributeKind::UnsafeSpecializationMarker(..)
| AttributeKind::ParenSugar(..)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_public/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ pub struct TraitDecl {
pub skip_boxed_slice_during_method_dispatch: bool,
pub specialization_kind: TraitSpecializationKind,
pub must_implement_one_of: Option<Vec<Ident>>,
pub implement_via_object: bool,
pub force_dyn_incompatible: Option<Span>,
pub deny_explicit_impl: bool,
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_public/src/unstable/convert/stable/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
.must_implement_one_of
.as_ref()
.map(|idents| idents.iter().map(|ident| opaque(ident)).collect()),
implement_via_object: self.implement_via_object,
force_dyn_incompatible: self.force_dyn_incompatible.stable(tables, cx),
deny_explicit_impl: self.deny_explicit_impl,
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1921,7 +1921,6 @@ symbols! {
rustc_diagnostic_macros,
rustc_dirty,
rustc_do_not_const_check,
rustc_do_not_implement_via_object,
rustc_doc_primitive,
rustc_driver,
rustc_dummy,
Expand All @@ -1930,6 +1929,7 @@ symbols! {
rustc_dump_predicates,
rustc_dump_user_args,
rustc_dump_vtable,
rustc_dyn_incompatible_trait,
rustc_effective_visibility,
rustc_evaluate_where_clauses,
rustc_expected_cgu_reuse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,18 @@ fn dyn_compatibility_violations_for_trait(
.collect();

// Check the trait itself.
if trait_has_sized_self(tcx, trait_def_id) {
let has_sized_self = trait_has_sized_self(tcx, trait_def_id);
if has_sized_self {
// We don't want to include the requirement from `Sized` itself to be `Sized` in the list.
let spans = get_sized_bounds(tcx, trait_def_id);
violations.push(DynCompatibilityViolation::SizedSelf(spans));
}
// only report dyn-incompatible supertraits if there is no `Self: Sized`,
// to avoid duplicate notes about `Sized`.
let trait_def = tcx.trait_def(trait_def_id);
if !has_sized_self && let Some(span) = trait_def.force_dyn_incompatible {
violations.push(DynCompatibilityViolation::ExplicitlyDynIncompatible([span].into()));
}
let spans = predicates_reference_self(tcx, trait_def_id, false);
if !spans.is_empty() {
violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,10 +799,6 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(

let tcx = selcx.tcx();

if !tcx.trait_def(obligation.predicate.trait_def_id(tcx)).implement_via_object {
return;
}

let self_ty = obligation.predicate.self_ty();
let object_ty = selcx.infcx.shallow_resolve(self_ty);
let data = match object_ty.kind() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -904,10 +904,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
"assemble_candidates_from_object_ty",
);

if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object {
return;
}

self.infcx.probe(|_snapshot| {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,6 @@ pub trait Interner:

fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool;

fn trait_may_be_implemented_via_object(self, trait_def_id: Self::TraitId) -> bool;

/// Returns `true` if this is an `unsafe trait`.
fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool;

Expand Down
16 changes: 7 additions & 9 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ unsafe impl<T: Sync + PointeeSized> Send for &T {}
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
#[rustc_specialization_trait]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
// `Sized` being coinductive, despite having supertraits, is okay as there are no user-written impls,
// and we know that the supertraits are always implemented if the subtrait is just by looking at
// the builtin impls.
Expand All @@ -171,7 +171,6 @@ pub trait Sized: MetaSized {
#[fundamental]
#[rustc_specialization_trait]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
// `MetaSized` being coinductive, despite having supertraits, is okay for the same reasons as
// `Sized` above.
#[rustc_coinductive]
Expand All @@ -189,7 +188,6 @@ pub trait MetaSized: PointeeSized {
#[fundamental]
#[rustc_specialization_trait]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_coinductive]
pub trait PointeeSized {
// Empty
Expand Down Expand Up @@ -235,7 +233,7 @@ pub trait PointeeSized {
#[unstable(feature = "unsize", issue = "18598")]
#[lang = "unsize"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub trait Unsize<T: PointeeSized>: PointeeSized {
// Empty.
}
Expand Down Expand Up @@ -515,7 +513,7 @@ impl<T: PointeeSized> Copy for &T {}
#[unstable(feature = "bikeshed_guaranteed_no_drop", issue = "none")]
#[lang = "bikeshed_guaranteed_no_drop"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
#[doc(hidden)]
pub trait BikeshedGuaranteedNoDrop {}

Expand Down Expand Up @@ -886,7 +884,7 @@ impl<T: PointeeSized> StructuralPartialEq for PhantomData<T> {}
)]
#[lang = "discriminant_kind"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub trait DiscriminantKind {
/// The type of the discriminant, which must satisfy the trait
/// bounds required by `mem::Discriminant`.
Expand Down Expand Up @@ -1056,7 +1054,7 @@ marker_impls! {
#[lang = "destruct"]
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub const trait Destruct: PointeeSized {}

/// A marker for tuple types.
Expand All @@ -1067,7 +1065,7 @@ pub const trait Destruct: PointeeSized {}
#[lang = "tuple_trait"]
#[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple")]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub trait Tuple {}

/// A marker for types which can be used as types of `const` generic parameters.
Expand Down Expand Up @@ -1125,7 +1123,7 @@ marker_impls! {
)]
#[lang = "fn_ptr_trait"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub trait FnPtr: Copy + Clone {
/// Returns the address of the function pointer.
#[lang = "fn_ptr_addr"]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/mem/transmutability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ use crate::marker::ConstParamTy_;
#[unstable_feature_bound(transmutability)]
#[lang = "transmute_trait"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
#[rustc_coinductive]
pub unsafe trait TransmuteFrom<Src, const ASSUME: Assume = { Assume::NOTHING }>
where
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use crate::ptr::NonNull;
/// [`to_raw_parts`]: *const::to_raw_parts
#[lang = "pointee_trait"]
#[rustc_deny_explicit_impl]
#[rustc_do_not_implement_via_object]
#[rustc_dyn_incompatible_trait]
pub trait Pointee: PointeeSized {
/// The type for metadata in pointers and references to `Self`.
#[lang = "metadata_type"]
Expand Down
Loading
Loading