@@ -12,7 +12,7 @@ use rustc_ast::ptr::P;
12
12
use rustc_ast:: token;
13
13
use rustc_ast:: tokenstream:: TokenStream ;
14
14
use rustc_ast:: visit:: { self , AssocCtxt , Visitor } ;
15
- use rustc_ast:: { AstLike , Block , Inline , ItemKind , Local , MacArgs } ;
15
+ use rustc_ast:: { AstLike , Block , Inline , ItemKind , Local , MacArgs , MacCall } ;
16
16
use rustc_ast:: { MacCallStmt , MacStmtStyle , MetaItemKind , ModKind , NestedMetaItem } ;
17
17
use rustc_ast:: { NodeId , PatKind , Path , StmtKind , Unsafe } ;
18
18
use rustc_ast_pretty:: pprust;
@@ -26,7 +26,7 @@ use rustc_parse::parser::{
26
26
AttemptLocalParseRecovery , ForceCollect , Parser , RecoverColon , RecoverComma ,
27
27
} ;
28
28
use rustc_parse:: validate_attr;
29
- use rustc_session:: lint:: builtin:: UNUSED_DOC_COMMENTS ;
29
+ use rustc_session:: lint:: builtin:: { UNUSED_ATTRIBUTES , UNUSED_DOC_COMMENTS } ;
30
30
use rustc_session:: lint:: BuiltinLintDiagnostics ;
31
31
use rustc_session:: parse:: { feature_err, ParseSess } ;
32
32
use rustc_session:: Limit ;
@@ -1070,7 +1070,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
1070
1070
1071
1071
// Detect use of feature-gated or invalid attributes on macro invocations
1072
1072
// since they will not be detected after macro expansion.
1073
- fn check_attributes ( & mut self , attrs : & [ ast:: Attribute ] ) {
1073
+ fn check_attributes ( & mut self , attrs : & [ ast:: Attribute ] , call : & MacCall ) {
1074
1074
let features = self . cx . ecfg . features . unwrap ( ) ;
1075
1075
let mut attrs = attrs. iter ( ) . peekable ( ) ;
1076
1076
let mut span: Option < Span > = None ;
@@ -1085,14 +1085,31 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
1085
1085
continue ;
1086
1086
}
1087
1087
1088
- if attr. doc_str ( ) . is_some ( ) {
1088
+ if attr. is_doc_comment ( ) {
1089
1089
self . cx . sess . parse_sess . buffer_lint_with_diagnostic (
1090
1090
& UNUSED_DOC_COMMENTS ,
1091
1091
current_span,
1092
- ast :: CRATE_NODE_ID ,
1092
+ self . cx . current_expansion . lint_node_id ,
1093
1093
"unused doc comment" ,
1094
1094
BuiltinLintDiagnostics :: UnusedDocComment ( attr. span ) ,
1095
1095
) ;
1096
+ } else if rustc_attr:: is_builtin_attr ( attr) {
1097
+ let attr_name = attr. ident ( ) . unwrap ( ) . name ;
1098
+ // `#[cfg]` and `#[cfg_attr]` are special - they are
1099
+ // eagerly evaluated.
1100
+ if attr_name != sym:: cfg && attr_name != sym:: cfg_attr {
1101
+ self . cx . sess . parse_sess . buffer_lint_with_diagnostic (
1102
+ & UNUSED_ATTRIBUTES ,
1103
+ attr. span ,
1104
+ self . cx . current_expansion . lint_node_id ,
1105
+ & format ! ( "unused attribute `{}`" , attr_name) ,
1106
+ BuiltinLintDiagnostics :: UnusedBuiltinAttribute {
1107
+ attr_name,
1108
+ macro_name : pprust:: path_to_string ( & call. path ) ,
1109
+ invoc_span : call. path . span ,
1110
+ } ,
1111
+ ) ;
1112
+ }
1096
1113
}
1097
1114
}
1098
1115
}
@@ -1152,7 +1169,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1152
1169
}
1153
1170
1154
1171
if let ast:: ExprKind :: MacCall ( mac) = expr. kind {
1155
- self . check_attributes ( & expr. attrs ) ;
1172
+ self . check_attributes ( & expr. attrs , & mac ) ;
1156
1173
self . collect_bang ( mac, expr. span , AstFragmentKind :: Expr ) . make_expr ( ) . into_inner ( )
1157
1174
} else {
1158
1175
assign_id ! ( self , & mut expr. id, || {
@@ -1253,7 +1270,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1253
1270
}
1254
1271
1255
1272
if let ast:: ExprKind :: MacCall ( mac) = expr. kind {
1256
- self . check_attributes ( & expr. attrs ) ;
1273
+ self . check_attributes ( & expr. attrs , & mac ) ;
1257
1274
self . collect_bang ( mac, expr. span , AstFragmentKind :: OptExpr )
1258
1275
. make_opt_expr ( )
1259
1276
. map ( |expr| expr. into_inner ( ) )
@@ -1296,7 +1313,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1296
1313
1297
1314
if let StmtKind :: MacCall ( mac) = stmt. kind {
1298
1315
let MacCallStmt { mac, style, attrs, tokens : _ } = mac. into_inner ( ) ;
1299
- self . check_attributes ( & attrs) ;
1316
+ self . check_attributes ( & attrs, & mac ) ;
1300
1317
let mut placeholder =
1301
1318
self . collect_bang ( mac, stmt. span , AstFragmentKind :: Stmts ) . make_stmts ( ) ;
1302
1319
@@ -1344,9 +1361,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1344
1361
let span = item. span ;
1345
1362
1346
1363
match item. kind {
1347
- ast:: ItemKind :: MacCall ( ..) => {
1364
+ ast:: ItemKind :: MacCall ( ref mac) => {
1365
+ self . check_attributes ( & attrs, & mac) ;
1348
1366
item. attrs = attrs;
1349
- self . check_attributes ( & item. attrs ) ;
1350
1367
item. and_then ( |item| match item. kind {
1351
1368
ItemKind :: MacCall ( mac) => {
1352
1369
self . collect_bang ( mac, span, AstFragmentKind :: Items ) . make_items ( )
@@ -1455,8 +1472,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1455
1472
}
1456
1473
1457
1474
match item. kind {
1458
- ast:: AssocItemKind :: MacCall ( .. ) => {
1459
- self . check_attributes ( & item. attrs ) ;
1475
+ ast:: AssocItemKind :: MacCall ( ref mac ) => {
1476
+ self . check_attributes ( & item. attrs , & mac ) ;
1460
1477
item. and_then ( |item| match item. kind {
1461
1478
ast:: AssocItemKind :: MacCall ( mac) => self
1462
1479
. collect_bang ( mac, item. span , AstFragmentKind :: TraitItems )
@@ -1480,8 +1497,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1480
1497
}
1481
1498
1482
1499
match item. kind {
1483
- ast:: AssocItemKind :: MacCall ( .. ) => {
1484
- self . check_attributes ( & item. attrs ) ;
1500
+ ast:: AssocItemKind :: MacCall ( ref mac ) => {
1501
+ self . check_attributes ( & item. attrs , & mac ) ;
1485
1502
item. and_then ( |item| match item. kind {
1486
1503
ast:: AssocItemKind :: MacCall ( mac) => self
1487
1504
. collect_bang ( mac, item. span , AstFragmentKind :: ImplItems )
@@ -1526,8 +1543,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1526
1543
}
1527
1544
1528
1545
match foreign_item. kind {
1529
- ast:: ForeignItemKind :: MacCall ( .. ) => {
1530
- self . check_attributes ( & foreign_item. attrs ) ;
1546
+ ast:: ForeignItemKind :: MacCall ( ref mac ) => {
1547
+ self . check_attributes ( & foreign_item. attrs , & mac ) ;
1531
1548
foreign_item. and_then ( |item| match item. kind {
1532
1549
ast:: ForeignItemKind :: MacCall ( mac) => self
1533
1550
. collect_bang ( mac, item. span , AstFragmentKind :: ForeignItems )
0 commit comments