|
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