|
5 | 5 | // done by the orphan and overlap modules. Then we build up various
|
6 | 6 | // mappings. That mapping code resides here.
|
7 | 7 |
|
8 |
| -use rustc_errors::struct_span_err; |
| 8 | +use rustc_errors::{error_code, struct_span_err}; |
9 | 9 | use rustc_hir::def_id::{DefId, LocalDefId};
|
10 | 10 | use rustc_middle::ty::query::Providers;
|
11 | 11 | use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
| 12 | +use rustc_span::sym; |
12 | 13 | use rustc_trait_selection::traits;
|
13 | 14 |
|
14 | 15 | mod builtin;
|
@@ -39,61 +40,26 @@ fn enforce_trait_manually_implementable(
|
39 | 40 | impl_def_id: LocalDefId,
|
40 | 41 | trait_def_id: DefId,
|
41 | 42 | ) {
|
42 |
| - let did = Some(trait_def_id); |
43 |
| - let li = tcx.lang_items(); |
44 | 43 | let impl_header_span = tcx.def_span(impl_def_id);
|
45 | 44 |
|
46 |
| - // Disallow *all* explicit impls of `Pointee`, `DiscriminantKind`, `Sized` and `Unsize` for now. |
47 |
| - if did == li.pointee_trait() { |
48 |
| - struct_span_err!( |
| 45 | + // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]` |
| 46 | + if tcx.has_attr(trait_def_id, sym::rustc_deny_explicit_impl) { |
| 47 | + let trait_name = tcx.item_name(trait_def_id); |
| 48 | + let mut err = struct_span_err!( |
49 | 49 | tcx.sess,
|
50 | 50 | impl_header_span,
|
51 | 51 | E0322,
|
52 |
| - "explicit impls for the `Pointee` trait are not permitted" |
53 |
| - ) |
54 |
| - .span_label(impl_header_span, "impl of `Pointee` not allowed") |
55 |
| - .emit(); |
56 |
| - return; |
57 |
| - } |
58 |
| - |
59 |
| - if did == li.discriminant_kind_trait() { |
60 |
| - struct_span_err!( |
61 |
| - tcx.sess, |
62 |
| - impl_header_span, |
63 |
| - E0322, |
64 |
| - "explicit impls for the `DiscriminantKind` trait are not permitted" |
65 |
| - ) |
66 |
| - .span_label(impl_header_span, "impl of `DiscriminantKind` not allowed") |
67 |
| - .emit(); |
68 |
| - return; |
69 |
| - } |
70 |
| - |
71 |
| - if did == li.sized_trait() { |
72 |
| - struct_span_err!( |
73 |
| - tcx.sess, |
74 |
| - impl_header_span, |
75 |
| - E0322, |
76 |
| - "explicit impls for the `Sized` trait are not permitted" |
77 |
| - ) |
78 |
| - .span_label(impl_header_span, "impl of `Sized` not allowed") |
79 |
| - .emit(); |
80 |
| - return; |
81 |
| - } |
82 |
| - |
83 |
| - if did == li.unsize_trait() { |
84 |
| - struct_span_err!( |
85 |
| - tcx.sess, |
86 |
| - impl_header_span, |
87 |
| - E0328, |
88 |
| - "explicit impls for the `Unsize` trait are not permitted" |
89 |
| - ) |
90 |
| - .span_label(impl_header_span, "impl of `Unsize` not allowed") |
91 |
| - .emit(); |
92 |
| - return; |
93 |
| - } |
| 52 | + "explicit impls for the `{trait_name}` trait are not permitted" |
| 53 | + ); |
| 54 | + err.span_label(impl_header_span, format!("impl of `{trait_name}` not allowed")); |
| 55 | + |
| 56 | + // Maintain explicit error code for `Unsize`, since it has a useful |
| 57 | + // explanation about using `CoerceUnsized` instead. |
| 58 | + if Some(trait_def_id) == tcx.lang_items().unsize_trait() { |
| 59 | + err.code(error_code!(E0328)); |
| 60 | + } |
94 | 61 |
|
95 |
| - if tcx.features().unboxed_closures { |
96 |
| - // the feature gate allows all Fn traits |
| 62 | + err.emit(); |
97 | 63 | return;
|
98 | 64 | }
|
99 | 65 |
|
|
0 commit comments