Add rustc_do_not_implement_via_object
This commit is contained in:
parent
5683791ebb
commit
657d3f43a9
11 changed files with 47 additions and 3 deletions
|
@ -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, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: false,
|
||||||
"#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
|
"#[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_attr!(
|
||||||
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
|
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
|
||||||
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
|
"#[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)
|
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 {
|
ty::TraitDef {
|
||||||
def_id: def_id.to_def_id(),
|
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,
|
skip_array_during_method_dispatch,
|
||||||
specialization_kind,
|
specialization_kind,
|
||||||
must_implement_one_of,
|
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
|
/// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
|
||||||
/// must be implemented.
|
/// must be implemented.
|
||||||
pub must_implement_one_of: Option<Box<[Ident]>>,
|
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
|
/// Whether this trait is treated specially by the standard library
|
||||||
|
|
|
@ -1270,6 +1270,7 @@ symbols! {
|
||||||
rustc_diagnostic_macros,
|
rustc_diagnostic_macros,
|
||||||
rustc_dirty,
|
rustc_dirty,
|
||||||
rustc_do_not_const_check,
|
rustc_do_not_const_check,
|
||||||
|
rustc_do_not_implement_via_object,
|
||||||
rustc_doc_primitive,
|
rustc_doc_primitive,
|
||||||
rustc_dummy,
|
rustc_dummy,
|
||||||
rustc_dump_env_program_clauses,
|
rustc_dump_env_program_clauses,
|
||||||
|
|
|
@ -631,6 +631,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
goal: Goal<'tcx, G>,
|
goal: Goal<'tcx, G>,
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
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 self_ty = goal.predicate.self_ty();
|
||||||
let bounds = match *self_ty.kind() {
|
let bounds = match *self_ty.kind() {
|
||||||
ty::Bool
|
ty::Bool
|
||||||
|
@ -663,7 +668,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
ty::Dynamic(bounds, ..) => bounds,
|
ty::Dynamic(bounds, ..) => bounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tcx = self.tcx();
|
|
||||||
let own_bounds: FxIndexSet<_> =
|
let own_bounds: FxIndexSet<_> =
|
||||||
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
|
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
|
||||||
for assumption in elaborate(tcx, own_bounds.iter().copied())
|
for assumption in elaborate(tcx, own_bounds.iter().copied())
|
||||||
|
|
|
@ -174,6 +174,7 @@ pub trait Sized {
|
||||||
#[unstable(feature = "unsize", issue = "18598")]
|
#[unstable(feature = "unsize", issue = "18598")]
|
||||||
#[lang = "unsize"]
|
#[lang = "unsize"]
|
||||||
#[rustc_deny_explicit_impl]
|
#[rustc_deny_explicit_impl]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
pub trait Unsize<T: ?Sized> {
|
pub trait Unsize<T: ?Sized> {
|
||||||
// Empty.
|
// Empty.
|
||||||
}
|
}
|
||||||
|
@ -855,6 +856,7 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
|
||||||
)]
|
)]
|
||||||
#[lang = "discriminant_kind"]
|
#[lang = "discriminant_kind"]
|
||||||
#[rustc_deny_explicit_impl]
|
#[rustc_deny_explicit_impl]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
pub trait DiscriminantKind {
|
pub trait DiscriminantKind {
|
||||||
/// The type of the discriminant, which must satisfy the trait
|
/// The type of the discriminant, which must satisfy the trait
|
||||||
/// bounds required by `mem::Discriminant`.
|
/// bounds required by `mem::Discriminant`.
|
||||||
|
@ -960,6 +962,7 @@ marker_impls! {
|
||||||
#[lang = "destruct"]
|
#[lang = "destruct"]
|
||||||
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
||||||
#[rustc_deny_explicit_impl]
|
#[rustc_deny_explicit_impl]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
pub trait Destruct {}
|
pub trait Destruct {}
|
||||||
|
|
||||||
|
@ -971,6 +974,7 @@ pub trait Destruct {}
|
||||||
#[lang = "tuple_trait"]
|
#[lang = "tuple_trait"]
|
||||||
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
|
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
|
||||||
#[rustc_deny_explicit_impl]
|
#[rustc_deny_explicit_impl]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
pub trait Tuple {}
|
pub trait Tuple {}
|
||||||
|
|
||||||
/// A marker for pointer-like types.
|
/// 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.
|
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
|
||||||
#[unstable(feature = "transmutability", issue = "99571")]
|
#[unstable(feature = "transmutability", issue = "99571")]
|
||||||
#[lang = "transmute_trait"]
|
#[lang = "transmute_trait"]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
|
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
|
||||||
where
|
where
|
||||||
Src: ?Sized,
|
Src: ?Sized,
|
||||||
|
|
|
@ -51,6 +51,7 @@ use crate::hash::{Hash, Hasher};
|
||||||
/// [`to_raw_parts`]: *const::to_raw_parts
|
/// [`to_raw_parts`]: *const::to_raw_parts
|
||||||
#[lang = "pointee_trait"]
|
#[lang = "pointee_trait"]
|
||||||
#[rustc_deny_explicit_impl]
|
#[rustc_deny_explicit_impl]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)]
|
||||||
pub trait Pointee {
|
pub trait Pointee {
|
||||||
/// The type for metadata in pointers and references to `Self`.
|
/// The type for metadata in pointers and references to `Self`.
|
||||||
#[lang = "metadata_type"]
|
#[lang = "metadata_type"]
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
|
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]>();
|
LL | let x = x.cast::<[i32]>();
|
||||||
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
||||||
|
|
|
|
||||||
note: required by a bound in `Cast::cast`
|
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
|
LL | fn cast<T: ?Sized>(&self) -> &T
|
||||||
| ---- required by a bound in this associated function
|
| ---- 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)]
|
#![feature(unsize)]
|
||||||
|
|
||||||
use std::marker::Unsize;
|
use std::marker::Unsize;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue