Skip to content

Commit 657d3f4

Browse files
Add rustc_do_not_implement_via_object
1 parent 5683791 commit 657d3f4

File tree

11 files changed

+47
-3
lines changed

11 files changed

+47
-3
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+5
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
708708
rustc_deny_explicit_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: false,
709709
"#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
710710
),
711+
rustc_attr!(
712+
rustc_do_not_implement_via_object, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true,
713+
"#[rustc_do_not_implement_via_object] marks a trait so that `dyn Trait` does not \
714+
implement `Trait` (without requiring `Sized` as a supertrait)"
715+
),
711716
rustc_attr!(
712717
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
713718
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \

compiler/rustc_hir_analysis/src/collect.rs

+2
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
985985

986986
no_dups.then_some(list)
987987
});
988+
let do_not_implement_via_object = tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
988989

989990
ty::TraitDef {
990991
def_id: def_id.to_def_id(),
@@ -996,6 +997,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
996997
skip_array_during_method_dispatch,
997998
specialization_kind,
998999
must_implement_one_of,
1000+
do_not_implement_via_object,
9991001
}
10001002
}
10011003

compiler/rustc_middle/src/ty/trait_def.rs

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ pub struct TraitDef {
5252
/// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
5353
/// must be implemented.
5454
pub must_implement_one_of: Option<Box<[Ident]>>,
55+
56+
/// Whether a type's built-in `dyn Trait: Trait` implementation is explicitly
57+
/// denied. This only applies to built-in trait, and is marked via
58+
/// `#[rustc_do_not_implement_via_object]`.
59+
pub do_not_implement_via_object: bool,
5560
}
5661

5762
/// Whether this trait is treated specially by the standard library

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,7 @@ symbols! {
12701270
rustc_diagnostic_macros,
12711271
rustc_dirty,
12721272
rustc_do_not_const_check,
1273+
rustc_do_not_implement_via_object,
12731274
rustc_doc_primitive,
12741275
rustc_dummy,
12751276
rustc_dump_env_program_clauses,

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
631631
goal: Goal<'tcx, G>,
632632
candidates: &mut Vec<Candidate<'tcx>>,
633633
) {
634+
let tcx = self.tcx();
635+
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
636+
return;
637+
}
638+
634639
let self_ty = goal.predicate.self_ty();
635640
let bounds = match *self_ty.kind() {
636641
ty::Bool
@@ -663,7 +668,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
663668
ty::Dynamic(bounds, ..) => bounds,
664669
};
665670

666-
let tcx = self.tcx();
667671
let own_bounds: FxIndexSet<_> =
668672
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
669673
for assumption in elaborate(tcx, own_bounds.iter().copied())

library/core/src/marker.rs

+4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ pub trait Sized {
174174
#[unstable(feature = "unsize", issue = "18598")]
175175
#[lang = "unsize"]
176176
#[rustc_deny_explicit_impl]
177+
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
177178
pub trait Unsize<T: ?Sized> {
178179
// Empty.
179180
}
@@ -855,6 +856,7 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
855856
)]
856857
#[lang = "discriminant_kind"]
857858
#[rustc_deny_explicit_impl]
859+
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
858860
pub trait DiscriminantKind {
859861
/// The type of the discriminant, which must satisfy the trait
860862
/// bounds required by `mem::Discriminant`.
@@ -960,6 +962,7 @@ marker_impls! {
960962
#[lang = "destruct"]
961963
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
962964
#[rustc_deny_explicit_impl]
965+
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
963966
#[const_trait]
964967
pub trait Destruct {}
965968

@@ -971,6 +974,7 @@ pub trait Destruct {}
971974
#[lang = "tuple_trait"]
972975
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
973976
#[rustc_deny_explicit_impl]
977+
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
974978
pub trait Tuple {}
975979

976980
/// A marker for pointer-like types.

library/core/src/mem/transmutability.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ 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_do_not_implement_via_object)]
1011
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
1112
where
1213
Src: ?Sized,

library/core/src/ptr/metadata.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::hash::{Hash, Hasher};
5151
/// [`to_raw_parts`]: *const::to_raw_parts
5252
#[lang = "pointee_trait"]
5353
#[rustc_deny_explicit_impl]
54+
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
5455
pub trait Pointee {
5556
/// The type for metadata in pointers and references to `Self`.
5657
#[lang = "metadata_type"]

tests/ui/unsized/issue-71659.stderr renamed to tests/ui/unsized/issue-71659.current.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
2-
--> $DIR/issue-71659.rs:30:15
2+
--> $DIR/issue-71659.rs:33:15
33
|
44
LL | let x = x.cast::<[i32]>();
55
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
66
|
77
note: required by a bound in `Cast::cast`
8-
--> $DIR/issue-71659.rs:19:15
8+
--> $DIR/issue-71659.rs:22:15
99
|
1010
LL | fn cast<T: ?Sized>(&self) -> &T
1111
| ---- required by a bound in this associated function
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
2+
--> $DIR/issue-71659.rs:33:15
3+
|
4+
LL | let x = x.cast::<[i32]>();
5+
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
6+
|
7+
note: required by a bound in `Cast::cast`
8+
--> $DIR/issue-71659.rs:22:15
9+
|
10+
LL | fn cast<T: ?Sized>(&self) -> &T
11+
| ---- required by a bound in this associated function
12+
LL | where
13+
LL | Self: CastTo<T>,
14+
| ^^^^^^^^^ required by this bound in `Cast::cast`
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0277`.

tests/ui/unsized/issue-71659.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// revisions: current next
2+
//[next] compile-flags: -Ztrait-solver=next
3+
14
#![feature(unsize)]
25

36
use std::marker::Unsize;

0 commit comments

Comments
 (0)