@@ -10,7 +10,7 @@ use rustc_errors::{Applicability, Diag, SuggestionStyle};
10
10
use rustc_lexer:: TokenKind ;
11
11
use rustc_lint:: { EarlyContext , EarlyLintPass , LintContext } ;
12
12
use rustc_session:: impl_lint_pass;
13
- use rustc_span:: { BytePos , ExpnKind , Ident , InnerSpan , Span , SpanData , Symbol , kw} ;
13
+ use rustc_span:: { BytePos , ExpnKind , Ident , InnerSpan , Span , SpanData , Symbol , kw, sym } ;
14
14
15
15
declare_clippy_lint ! {
16
16
/// ### What it does
@@ -129,18 +129,54 @@ struct Stop {
129
129
kind : StopKind ,
130
130
first : usize ,
131
131
last : usize ,
132
+ ident : Option < Ident > ,
132
133
}
133
134
134
135
impl Stop {
135
- fn convert_to_inner ( & self ) -> ( Span , String ) {
136
+ fn could_only_be_outer_attr ( & self ) -> bool {
137
+ if let Some ( ident) = self . ident {
138
+ return matches ! (
139
+ ident. name,
140
+ // Cannot be used at crate level
141
+ sym:: repr | sym:: test | sym:: derive | sym:: automatically_derived | sym:: macro_export |
142
+ sym:: on_unimplemented | sym:: do_not_recommend | sym:: path | sym:: panic_handler | sym:: global_allocator |
143
+ // Only has an effect on items but not throgh compile errors
144
+ sym:: ignore | sym:: should_panic | sym:: proc_macro | sym:: proc_macro_derive | sym:: proc_macro_attribute |
145
+ // Has no effect when applied to a module
146
+ sym:: must_use |
147
+ // Should be applied to a foreign function or static
148
+ sym:: link_name | sym:: link_ordinal | sym:: link_section |
149
+ // Should be applied to an `extern crate` item
150
+ sym:: no_link |
151
+ // Should be applied to a free function, impl method or static
152
+ sym:: export_name | sym:: no_mangle |
153
+ // Should be applied to a `static` variable
154
+ sym:: used |
155
+ // Should be applied to function or closure
156
+ sym:: inline |
157
+ // Should be applied to a function definition
158
+ sym:: cold | sym:: target_feature | sym:: track_caller | sym:: instruction_set |
159
+ // Only has an effect on modules
160
+ sym:: no_implicit_prelude | sym:: debugger_visualizer |
161
+ // Should be applied to a struct or enum
162
+ sym:: non_exhaustive
163
+ ) ;
164
+ }
165
+ false
166
+ }
167
+
168
+ fn convert_to_inner ( & self ) -> Option < ( Span , String ) > {
169
+ if self . could_only_be_outer_attr ( ) {
170
+ return None ;
171
+ }
136
172
let inner = match self . kind {
137
173
// #![...]
138
174
StopKind :: Attr => InnerSpan :: new ( 1 , 1 ) ,
139
175
// /// or /**
140
176
// ^ ^
141
177
StopKind :: Doc ( _) => InnerSpan :: new ( 2 , 3 ) ,
142
178
} ;
143
- ( self . span . from_inner ( inner) , "!" . into ( ) )
179
+ Some ( ( self . span . from_inner ( inner) , "!" . into ( ) ) )
144
180
}
145
181
146
182
fn comment_out ( & self , cx : & EarlyContext < ' _ > , suggestions : & mut Vec < ( Span , String ) > ) {
@@ -177,6 +213,7 @@ impl Stop {
177
213
} ,
178
214
first : file. lookup_line ( file. relative_position ( lo) ) ?,
179
215
last : file. lookup_line ( file. relative_position ( hi) ) ?,
216
+ ident : attr. ident ( ) ,
180
217
} )
181
218
}
182
219
}
@@ -356,6 +393,12 @@ impl EmptyLineAfter {
356
393
if let Some ( parent) = self . items . iter ( ) . rev ( ) . nth ( 1 )
357
394
&& ( parent. kind == "module" || parent. kind == "crate" )
358
395
&& parent. mod_items == Some ( id)
396
+ && let suggestions = gaps
397
+ . iter ( )
398
+ . flat_map ( |gap| gap. prev_chunk )
399
+ . filter_map ( Stop :: convert_to_inner)
400
+ . collect :: < Vec < ( Span , String ) > > ( )
401
+ && !suggestions. is_empty ( )
359
402
{
360
403
let desc = if parent. kind == "module" {
361
404
"parent module"
@@ -367,10 +410,7 @@ impl EmptyLineAfter {
367
410
StopKind :: Attr => format ! ( "if the attribute should apply to the {desc} use an inner attribute" ) ,
368
411
StopKind :: Doc ( _) => format ! ( "if the comment should document the {desc} use an inner doc comment" ) ,
369
412
} ,
370
- gaps. iter ( )
371
- . flat_map ( |gap| gap. prev_chunk )
372
- . map ( Stop :: convert_to_inner)
373
- . collect ( ) ,
413
+ suggestions,
374
414
Applicability :: MaybeIncorrect ,
375
415
) ;
376
416
}
@@ -425,6 +465,7 @@ impl EmptyLineAfter {
425
465
first : line. line ,
426
466
// last doesn't need to be accurate here, we don't compare it with anything
427
467
last : line. line ,
468
+ ident : None ,
428
469
} ) ;
429
470
}
430
471
0 commit comments