@@ -25,6 +25,7 @@ use rustc_middle::traits::ObligationCause;
25
25
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
26
26
use rustc_middle:: ty:: { self , TyCtxt , TypingMode } ;
27
27
use rustc_middle:: { bug, span_bug} ;
28
+ use rustc_session:: config:: CrateType ;
28
29
use rustc_session:: lint:: builtin:: {
29
30
CONFLICTING_REPR_HINTS , INVALID_DOC_ATTRIBUTES , INVALID_MACRO_EXPORT_ARGUMENTS ,
30
31
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES , UNUSED_ATTRIBUTES ,
@@ -2313,6 +2314,33 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
2313
2314
&& item. path == sym:: reason
2314
2315
{
2315
2316
errors:: UnusedNote :: NoLints { name : attr. name_or_empty ( ) }
2317
+ } else if matches ! (
2318
+ attr. name_or_empty( ) ,
2319
+ sym:: allow | sym:: warn | sym:: deny | sym:: forbid | sym:: expect
2320
+ ) && let Some ( meta) = attr. meta_item_list ( )
2321
+ && meta. iter ( ) . any ( |meta| {
2322
+ meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
2323
+ } )
2324
+ {
2325
+ if hir_id != CRATE_HIR_ID {
2326
+ let err = match attr. style {
2327
+ ast:: AttrStyle :: Outer => errors:: OuterCrateLevelAttr ,
2328
+ ast:: AttrStyle :: Inner => errors:: OuterCrateLevelAttr ,
2329
+ } ;
2330
+ self . tcx . emit_node_span_lint ( UNUSED_ATTRIBUTES , hir_id, attr. span , err) ;
2331
+ return ;
2332
+ } else {
2333
+ let never_needs_link = self
2334
+ . tcx
2335
+ . crate_types ( )
2336
+ . iter ( )
2337
+ . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
2338
+ if never_needs_link {
2339
+ errors:: UnusedNote :: LinkerWarningsBinaryCrateOnly
2340
+ } else {
2341
+ return ;
2342
+ }
2343
+ }
2316
2344
} else if attr. name_or_empty ( ) == sym:: default_method_body_is_const {
2317
2345
errors:: UnusedNote :: DefaultMethodBodyConst
2318
2346
} else {
0 commit comments