mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-19 11:12:43 +00:00
Add rustc_do_not_implement_via_object
This commit is contained in:
parent
5683791ebb
commit
657d3f43a9
@ -708,6 +708,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
rustc_deny_explicit_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: false,
|
||||
"#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_do_not_implement_via_object, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true,
|
||||
"#[rustc_do_not_implement_via_object] marks a trait so that `dyn Trait` does not \
|
||||
implement `Trait` (without requiring `Sized` as a supertrait)"
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
|
||||
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
|
||||
|
@ -985,6 +985,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
||||
|
||||
no_dups.then_some(list)
|
||||
});
|
||||
let do_not_implement_via_object = tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
|
||||
|
||||
ty::TraitDef {
|
||||
def_id: def_id.to_def_id(),
|
||||
@ -996,6 +997,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
||||
skip_array_during_method_dispatch,
|
||||
specialization_kind,
|
||||
must_implement_one_of,
|
||||
do_not_implement_via_object,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,11 @@ pub struct TraitDef {
|
||||
/// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
|
||||
/// must be implemented.
|
||||
pub must_implement_one_of: Option<Box<[Ident]>>,
|
||||
|
||||
/// Whether a type's built-in `dyn Trait: Trait` implementation is explicitly
|
||||
/// denied. This only applies to built-in trait, and is marked via
|
||||
/// `#[rustc_do_not_implement_via_object]`.
|
||||
pub do_not_implement_via_object: bool,
|
||||
}
|
||||
|
||||
/// Whether this trait is treated specially by the standard library
|
||||
|
@ -1270,6 +1270,7 @@ symbols! {
|
||||
rustc_diagnostic_macros,
|
||||
rustc_dirty,
|
||||
rustc_do_not_const_check,
|
||||
rustc_do_not_implement_via_object,
|
||||
rustc_doc_primitive,
|
||||
rustc_dummy,
|
||||
rustc_dump_env_program_clauses,
|
||||
|
@ -631,6 +631,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
|
||||
return;
|
||||
}
|
||||
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let bounds = match *self_ty.kind() {
|
||||
ty::Bool
|
||||
@ -663,7 +668,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
ty::Dynamic(bounds, ..) => bounds,
|
||||
};
|
||||
|
||||
let tcx = self.tcx();
|
||||
let own_bounds: FxIndexSet<_> =
|
||||
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
|
||||
for assumption in elaborate(tcx, own_bounds.iter().copied())
|
||||
|
@ -174,6 +174,7 @@ pub trait Sized {
|
||||
#[unstable(feature = "unsize", issue = "18598")]
|
||||
#[lang = "unsize"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
pub trait Unsize<T: ?Sized> {
|
||||
// Empty.
|
||||
}
|
||||
@ -855,6 +856,7 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
|
||||
)]
|
||||
#[lang = "discriminant_kind"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
pub trait DiscriminantKind {
|
||||
/// The type of the discriminant, which must satisfy the trait
|
||||
/// bounds required by `mem::Discriminant`.
|
||||
@ -960,6 +962,7 @@ marker_impls! {
|
||||
#[lang = "destruct"]
|
||||
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
#[const_trait]
|
||||
pub trait Destruct {}
|
||||
|
||||
@ -971,6 +974,7 @@ pub trait Destruct {}
|
||||
#[lang = "tuple_trait"]
|
||||
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
pub trait Tuple {}
|
||||
|
||||
/// A marker for pointer-like types.
|
||||
|
@ -7,6 +7,7 @@ use crate::marker::ConstParamTy;
|
||||
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[lang = "transmute_trait"]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
|
||||
where
|
||||
Src: ?Sized,
|
||||
|
@ -51,6 +51,7 @@ use crate::hash::{Hash, Hasher};
|
||||
/// [`to_raw_parts`]: *const::to_raw_parts
|
||||
#[lang = "pointee_trait"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||
pub trait Pointee {
|
||||
/// The type for metadata in pointers and references to `Self`.
|
||||
#[lang = "metadata_type"]
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
|
||||
--> $DIR/issue-71659.rs:30:15
|
||||
--> $DIR/issue-71659.rs:33:15
|
||||
|
|
||||
LL | let x = x.cast::<[i32]>();
|
||||
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
||||
|
|
||||
note: required by a bound in `Cast::cast`
|
||||
--> $DIR/issue-71659.rs:19:15
|
||||
--> $DIR/issue-71659.rs:22:15
|
||||
|
|
||||
LL | fn cast<T: ?Sized>(&self) -> &T
|
||||
| ---- required by a bound in this associated function
|
18
tests/ui/unsized/issue-71659.next.stderr
Normal file
18
tests/ui/unsized/issue-71659.next.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
|
||||
--> $DIR/issue-71659.rs:33:15
|
||||
|
|
||||
LL | let x = x.cast::<[i32]>();
|
||||
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
||||
|
|
||||
note: required by a bound in `Cast::cast`
|
||||
--> $DIR/issue-71659.rs:22:15
|
||||
|
|
||||
LL | fn cast<T: ?Sized>(&self) -> &T
|
||||
| ---- required by a bound in this associated function
|
||||
LL | where
|
||||
LL | Self: CastTo<T>,
|
||||
| ^^^^^^^^^ required by this bound in `Cast::cast`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -1,3 +1,6 @@
|
||||
// revisions: current next
|
||||
//[next] compile-flags: -Ztrait-solver=next
|
||||
|
||||
#![feature(unsize)]
|
||||
|
||||
use std::marker::Unsize;
|
||||
|
Loading…
Reference in New Issue
Block a user