Skip to content

Commit 0cea2e8

Browse files
committed
Auto merge of rust-lang#112320 - compiler-errors:do-not-impl-via-obj, r=lcnr
Add `implement_via_object` to `rustc_deny_explicit_impl` to control object candidate assembly Some built-in traits are special, since they are used to prove facts about the program that are important for later phases of compilation such as codegen and CTFE. For example, the `Unsize` trait is used to assert to the compiler that we are able to unsize a type into another type. It doesn't have any methods because it doesn't actually *instruct* the compiler how to do this unsizing, but this is later used (alongside an exhaustive match of combinations of unsizeable types) during codegen to generate unsize coercion code. Due to this, these built-in traits are incompatible with the type erasure provided by object types. For example, the existence of `dyn Unsize<T>` does not mean that the compiler is able to unsize `Box<dyn Unsize<T>>` into `Box<T>`, since `Unsize` is a *witness* to the fact that a type can be unsized, and it doesn't actually encode that unsizing operation in its vtable as mentioned above. The old trait solver gets around this fact by having complex control flow that never considers object bounds for certain built-in traits: https://github.com/rust-lang/rust/blob/2f896da247e0ee8f0bef7cd7c54cfbea255b9f68/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L61-L132 However, candidate assembly in the new solver is much more lovely, and I'd hate to add this list of opt-out cases into the new solver. Instead of maintaining this complex and hard-coded control flow, instead we can make this a property of the trait via a built-in attribute. We already have such a build attribute that's applied to every single trait that we care about: `rustc_deny_explicit_impl`. This PR adds `implement_via_object` as a meta-item to that attribute that allows us to opt a trait out of object-bound candidate assembly as well. r? `@lcnr`
2 parents 4ced0db + 2c3ef77 commit 0cea2e8

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

core/src/marker.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ unsafe impl<T: Sync + ?Sized> Send for &T {}
140140
)]
141141
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
142142
#[rustc_specialization_trait]
143-
#[rustc_deny_explicit_impl]
143+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
144+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
144145
#[rustc_coinductive]
145146
pub trait Sized {
146147
// Empty.
@@ -173,7 +174,8 @@ pub trait Sized {
173174
/// [nomicon-coerce]: ../../nomicon/coercions.html
174175
#[unstable(feature = "unsize", issue = "18598")]
175176
#[lang = "unsize"]
176-
#[rustc_deny_explicit_impl]
177+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
178+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
177179
pub trait Unsize<T: ?Sized> {
178180
// Empty.
179181
}
@@ -854,7 +856,8 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
854856
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
855857
)]
856858
#[lang = "discriminant_kind"]
857-
#[rustc_deny_explicit_impl]
859+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
860+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
858861
pub trait DiscriminantKind {
859862
/// The type of the discriminant, which must satisfy the trait
860863
/// bounds required by `mem::Discriminant`.
@@ -959,7 +962,8 @@ marker_impls! {
959962
#[unstable(feature = "const_trait_impl", issue = "67792")]
960963
#[lang = "destruct"]
961964
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
962-
#[rustc_deny_explicit_impl]
965+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
966+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
963967
#[const_trait]
964968
pub trait Destruct {}
965969

@@ -970,7 +974,8 @@ pub trait Destruct {}
970974
#[unstable(feature = "tuple_trait", issue = "none")]
971975
#[lang = "tuple_trait"]
972976
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
973-
#[rustc_deny_explicit_impl]
977+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
978+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
974979
pub trait Tuple {}
975980

976981
/// A marker for pointer-like types.
@@ -1025,7 +1030,8 @@ impl ConstParamTy for () {}
10251030
reason = "internal trait for implementing various traits for all function pointers"
10261031
)]
10271032
#[lang = "fn_ptr_trait"]
1028-
#[rustc_deny_explicit_impl]
1033+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
1034+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
10291035
pub trait FnPtr: Copy + Clone {
10301036
/// Returns the address of the function pointer.
10311037
#[lang = "fn_ptr_addr"]

core/src/mem/transmutability.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::marker::ConstParamTy;
77
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
88
#[unstable(feature = "transmutability", issue = "99571")]
99
#[lang = "transmute_trait"]
10+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
11+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
1012
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
1113
where
1214
Src: ?Sized,

core/src/ptr/metadata.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ use crate::hash::{Hash, Hasher};
5050
///
5151
/// [`to_raw_parts`]: *const::to_raw_parts
5252
#[lang = "pointee_trait"]
53-
#[rustc_deny_explicit_impl]
53+
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
54+
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
5455
pub trait Pointee {
5556
/// The type for metadata in pointers and references to `Self`.
5657
#[lang = "metadata_type"]

0 commit comments

Comments
 (0)