| 
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