@@ -16,6 +16,7 @@ use rustc_hir::{
16
16
self , FnSig , ForeignItem , HirId , Item , ItemKind , TraitItem , CRATE_HIR_ID , CRATE_OWNER_ID ,
17
17
} ;
18
18
use rustc_hir:: { MethodKind , Target , Unsafety } ;
19
+ use rustc_macros:: LintDiagnostic ;
19
20
use rustc_middle:: hir:: nested_filter;
20
21
use rustc_middle:: middle:: resolve_bound_vars:: ObjectLifetimeDefault ;
21
22
use rustc_middle:: query:: Providers ;
@@ -24,7 +25,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
24
25
use rustc_middle:: ty:: { self , TyCtxt } ;
25
26
use rustc_session:: lint:: builtin:: {
26
27
CONFLICTING_REPR_HINTS , INVALID_DOC_ATTRIBUTES , INVALID_MACRO_EXPORT_ARGUMENTS ,
27
- UNUSED_ATTRIBUTES ,
28
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES , UNUSED_ATTRIBUTES ,
28
29
} ;
29
30
use rustc_session:: parse:: feature_err;
30
31
use rustc_span:: symbol:: { kw, sym, Symbol } ;
@@ -36,6 +37,10 @@ use rustc_trait_selection::traits::ObligationCtxt;
36
37
use std:: cell:: Cell ;
37
38
use std:: collections:: hash_map:: Entry ;
38
39
40
+ #[ derive( LintDiagnostic ) ]
41
+ #[ diag( passes_diagnostic_diagnostic_on_unimplemented_only_for_traits) ]
42
+ pub struct DiagnosticOnUnimplementedOnlyForTraits ;
43
+
39
44
pub ( crate ) fn target_from_impl_item < ' tcx > (
40
45
tcx : TyCtxt < ' tcx > ,
41
46
impl_item : & hir:: ImplItem < ' _ > ,
@@ -104,6 +109,9 @@ impl CheckAttrVisitor<'_> {
104
109
let mut seen = FxHashMap :: default ( ) ;
105
110
let attrs = self . tcx . hir ( ) . attrs ( hir_id) ;
106
111
for attr in attrs {
112
+ if attr. path_matches ( & [ sym:: diagnostic, sym:: on_unimplemented] ) {
113
+ self . check_diagnostic_on_unimplemented ( attr. span , hir_id, target) ;
114
+ }
107
115
match attr. name_or_empty ( ) {
108
116
sym:: do_not_recommend => self . check_do_not_recommend ( attr. span , target) ,
109
117
sym:: inline => self . check_inline ( hir_id, attr, span, target) ,
@@ -284,6 +292,18 @@ impl CheckAttrVisitor<'_> {
284
292
}
285
293
}
286
294
295
+ /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition
296
+ fn check_diagnostic_on_unimplemented ( & self , attr_span : Span , hir_id : HirId , target : Target ) {
297
+ if !matches ! ( target, Target :: Trait ) {
298
+ self . tcx . emit_spanned_lint (
299
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
300
+ hir_id,
301
+ attr_span,
302
+ DiagnosticOnUnimplementedOnlyForTraits ,
303
+ ) ;
304
+ }
305
+ }
306
+
287
307
/// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
288
308
fn check_inline ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) -> bool {
289
309
match target {
0 commit comments