mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Add rustc_deny_explicit_impl
This commit is contained in:
parent
742d3f02c2
commit
b5b6467810
@ -1,4 +1,5 @@
|
||||
The `Sized` trait was implemented explicitly.
|
||||
A built-in trait was implemented explicitly. All implementations of the trait
|
||||
are provided automatically by the compiler.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
@ -691,6 +691,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true,
|
||||
"#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl."
|
||||
),
|
||||
rustc_attr!(
|
||||
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_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing,
|
||||
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
|
||||
|
@ -5,10 +5,11 @@
|
||||
// done by the orphan and overlap modules. Then we build up various
|
||||
// mappings. That mapping code resides here.
|
||||
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_errors::{error_code, struct_span_err};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
||||
use rustc_span::sym;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
mod builtin;
|
||||
@ -39,61 +40,26 @@ fn enforce_trait_manually_implementable(
|
||||
impl_def_id: LocalDefId,
|
||||
trait_def_id: DefId,
|
||||
) {
|
||||
let did = Some(trait_def_id);
|
||||
let li = tcx.lang_items();
|
||||
let impl_header_span = tcx.def_span(impl_def_id);
|
||||
|
||||
// Disallow *all* explicit impls of `Pointee`, `DiscriminantKind`, `Sized` and `Unsize` for now.
|
||||
if did == li.pointee_trait() {
|
||||
struct_span_err!(
|
||||
// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
|
||||
if tcx.has_attr(trait_def_id, sym::rustc_deny_explicit_impl) {
|
||||
let trait_name = tcx.item_name(trait_def_id);
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Pointee` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Pointee` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
"explicit impls for the `{trait_name}` trait are not permitted"
|
||||
);
|
||||
err.span_label(impl_header_span, format!("impl of `{trait_name}` not allowed"));
|
||||
|
||||
if did == li.discriminant_kind_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `DiscriminantKind` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `DiscriminantKind` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
// Maintain explicit error code for `Unsize`, since it has a useful
|
||||
// explanation about using `CoerceUnsized` instead.
|
||||
if Some(trait_def_id) == tcx.lang_items().unsize_trait() {
|
||||
err.code(error_code!(E0328));
|
||||
}
|
||||
|
||||
if did == li.sized_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Sized` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Sized` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if did == li.unsize_trait() {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_header_span,
|
||||
E0328,
|
||||
"explicit impls for the `Unsize` trait are not permitted"
|
||||
)
|
||||
.span_label(impl_header_span, "impl of `Unsize` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if tcx.features().unboxed_closures {
|
||||
// the feature gate allows all Fn traits
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1251,6 +1251,7 @@ symbols! {
|
||||
rustc_deallocator,
|
||||
rustc_def_path,
|
||||
rustc_default_body_unstable,
|
||||
rustc_deny_explicit_impl,
|
||||
rustc_diagnostic_item,
|
||||
rustc_diagnostic_macros,
|
||||
rustc_dirty,
|
||||
|
@ -96,6 +96,7 @@ unsafe impl<T: Sync + ?Sized> Send for &T {}
|
||||
)]
|
||||
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
|
||||
#[rustc_specialization_trait]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Sized {
|
||||
// Empty.
|
||||
}
|
||||
@ -127,6 +128,7 @@ pub trait Sized {
|
||||
/// [nomicon-coerce]: ../../nomicon/coercions.html
|
||||
#[unstable(feature = "unsize", issue = "27732")]
|
||||
#[lang = "unsize"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Unsize<T: ?Sized> {
|
||||
// Empty.
|
||||
}
|
||||
@ -693,6 +695,7 @@ impl<T: ?Sized> StructuralEq for PhantomData<T> {}
|
||||
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
|
||||
)]
|
||||
#[lang = "discriminant_kind"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait DiscriminantKind {
|
||||
/// The type of the discriminant, which must satisfy the trait
|
||||
/// bounds required by `mem::Discriminant`.
|
||||
@ -793,6 +796,7 @@ impl<T: ?Sized> Unpin for *mut T {}
|
||||
#[lang = "destruct"]
|
||||
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
||||
#[const_trait]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Destruct {}
|
||||
|
||||
/// A marker for tuple types.
|
||||
@ -802,6 +806,7 @@ pub trait Destruct {}
|
||||
#[unstable(feature = "tuple_trait", issue = "none")]
|
||||
#[lang = "tuple_trait"]
|
||||
#[rustc_on_unimplemented(message = "`{Self}` is not a tuple")]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Tuple {}
|
||||
|
||||
/// Implementations of `Copy` for primitive types.
|
||||
|
@ -50,6 +50,7 @@ use crate::hash::{Hash, Hasher};
|
||||
///
|
||||
/// [`to_raw_parts`]: *const::to_raw_parts
|
||||
#[lang = "pointee_trait"]
|
||||
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
|
||||
pub trait Pointee {
|
||||
/// The type for metadata in pointers and references to `Self`.
|
||||
#[lang = "metadata_type"]
|
||||
|
Loading…
Reference in New Issue
Block a user