summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/coherence/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/coherence/mod.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs66
1 files changed, 16 insertions, 50 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index ae9ebe590..1bf3768fe 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -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;
- }
-
- 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;
- }
-
- 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;
- }
+ "explicit impls for the `{trait_name}` trait are not permitted"
+ );
+ err.span_label(impl_header_span, format!("impl of `{trait_name}` not allowed"));
+
+ // 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 tcx.features().unboxed_closures {
- // the feature gate allows all Fn traits
+ err.emit();
return;
}