@@ -10,7 +10,7 @@ use std::collections::hash_map::Entry;
1010
1111use rustc_abi:: { Align , ExternAbi , Size } ;
1212use rustc_ast:: { AttrStyle , LitKind , MetaItemInner , MetaItemKind , MetaItemLit , ast} ;
13- use rustc_attr_data_structures:: { AttributeKind , ReprAttr , find_attr } ;
13+ use rustc_attr_data_structures:: { find_attr , AttributeKind , InlineAttr , ReprAttr } ;
1414use rustc_data_structures:: fx:: FxHashMap ;
1515use rustc_errors:: { Applicability , DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
1616use rustc_feature:: { AttributeDuplicates , AttributeType , BUILTIN_ATTRIBUTE_MAP , BuiltinAttribute } ;
@@ -124,6 +124,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
124124 AttributeKind :: Stability { span, .. }
125125 | AttributeKind :: ConstStability { span, .. } ,
126126 ) => self . check_stability_promotable ( * span, target) ,
127+ Attribute :: Parsed ( AttributeKind :: Inline ( kind, attr_span) ) => {
128+ self . check_inline ( hir_id, * attr_span, span, kind, target)
129+ }
127130 Attribute :: Parsed ( AttributeKind :: AllowInternalUnstable ( syms) ) => self
128131 . check_allow_internal_unstable (
129132 hir_id,
@@ -140,7 +143,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
140143 [ sym:: diagnostic, sym:: on_unimplemented, ..] => {
141144 self . check_diagnostic_on_unimplemented ( attr. span ( ) , hir_id, target)
142145 }
143- [ sym:: inline, ..] => self . check_inline ( hir_id, attr, span, target) ,
144146 [ sym:: coverage, ..] => self . check_coverage ( attr, span, target) ,
145147 [ sym:: optimize, ..] => self . check_optimize ( hir_id, attr, span, target) ,
146148 [ sym:: no_sanitize, ..] => {
@@ -357,11 +359,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
357359 self . check_rustc_force_inline ( hir_id, attrs, span, target) ;
358360 }
359361
360- fn inline_attr_str_error_with_macro_def ( & self , hir_id : HirId , attr : & Attribute , sym : & str ) {
362+ fn inline_attr_str_error_with_macro_def ( & self , hir_id : HirId , attr_span : Span , sym : & str ) {
361363 self . tcx . emit_node_span_lint (
362364 UNUSED_ATTRIBUTES ,
363365 hir_id,
364- attr . span ( ) ,
366+ attr_span ,
365367 errors:: IgnoredAttrWithMacro { sym } ,
366368 ) ;
367369 }
@@ -421,7 +423,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
421423 }
422424
423425 /// Checks if an `#[inline]` is applied to a function or a closure.
424- fn check_inline ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) {
426+ fn check_inline ( & self , hir_id : HirId , attr_span : Span , defn_span : Span , kind : & InlineAttr , target : Target ) {
425427 match target {
426428 Target :: Fn
427429 | Target :: Closure
@@ -430,7 +432,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
430432 self . tcx . emit_node_span_lint (
431433 UNUSED_ATTRIBUTES ,
432434 hir_id,
433- attr . span ( ) ,
435+ attr_span ,
434436 errors:: IgnoredInlineAttrFnProto ,
435437 )
436438 }
@@ -441,33 +443,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
441443 Target :: AssocConst => self . tcx . emit_node_span_lint (
442444 UNUSED_ATTRIBUTES ,
443445 hir_id,
444- attr . span ( ) ,
446+ attr_span ,
445447 errors:: IgnoredInlineAttrConstants ,
446448 ) ,
447449 // FIXME(#80564): Same for fields, arms, and macro defs
448450 Target :: Field | Target :: Arm | Target :: MacroDef => {
449- self . inline_attr_str_error_with_macro_def ( hir_id, attr , "inline" )
451+ self . inline_attr_str_error_with_macro_def ( hir_id, attr_span , "inline" )
450452 }
451453 _ => {
452- self . dcx ( ) . emit_err ( errors:: InlineNotFnOrClosure {
453- attr_span : attr. span ( ) ,
454- defn_span : span,
455- } ) ;
454+ self . dcx ( ) . emit_err ( errors:: InlineNotFnOrClosure { attr_span, defn_span } ) ;
456455 }
457456 }
458457
459458 // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
460459 if let Some ( did) = hir_id. as_owner ( )
461460 && self . tcx . def_kind ( did) . has_codegen_attrs ( )
462- && ! matches ! ( attr . meta_item_list ( ) . as_deref ( ) , Some ( [ item ] ) if item . has_name ( sym :: never ) )
461+ && kind != & InlineAttr :: Never
463462 {
464463 let attrs = self . tcx . codegen_fn_attrs ( did) ;
465464 // Not checking naked as `#[inline]` is forbidden for naked functions anyways.
466465 if attrs. contains_extern_indicator ( ) {
467466 self . tcx . emit_node_span_lint (
468467 UNUSED_ATTRIBUTES ,
469468 hir_id,
470- attr . span ( ) ,
469+ attr_span ,
471470 errors:: InlineIgnoredForExported { } ,
472471 ) ;
473472 }
@@ -701,6 +700,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
701700 }
702701 }
703702 }
703+ // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
704+ // `#[naked]` attribute with just a lint, because we previously
705+ // erroneously allowed it and some crates used it accidentally, to be compatible
706+ // with crates depending on them, we can't throw an error here.
707+ Target :: Field | Target :: Arm | Target :: MacroDef => {
708+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "naked" )
709+ }
704710 _ => {
705711 self . dcx ( ) . emit_err ( errors:: AttrShouldBeAppliedToFn {
706712 attr_span : attr. span ( ) ,
@@ -777,7 +783,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
777783 // with crates depending on them, we can't throw an error here.
778784 Target :: Field | Target :: Arm | Target :: MacroDef => {
779785 for attr in attrs {
780- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "track_caller" ) ;
786+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "track_caller" ) ;
781787 }
782788 }
783789 _ => {
@@ -820,7 +826,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
820826 // erroneously allowed it and some crates used it accidentally, to be compatible
821827 // with crates depending on them, we can't throw an error here.
822828 Target :: Field | Target :: Arm | Target :: MacroDef => {
823- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "non_exhaustive" ) ;
829+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "non_exhaustive" ) ;
824830 }
825831 _ => {
826832 self . dcx ( ) . emit_err ( errors:: NonExhaustiveWrongLocation {
@@ -840,7 +846,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
840846 // erroneously allowed it and some crates used it accidentally, to be compatible
841847 // with crates depending on them, we can't throw an error here.
842848 Target :: Field | Target :: Arm | Target :: MacroDef => {
843- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "marker" ) ;
849+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "marker" ) ;
844850 }
845851 _ => {
846852 self . dcx ( ) . emit_err ( errors:: AttrShouldBeAppliedToTrait {
@@ -894,7 +900,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
894900 // erroneously allowed it and some crates used it accidentally, to be compatible
895901 // with crates depending on them, we can't throw an error here.
896902 Target :: Field | Target :: Arm | Target :: MacroDef => {
897- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "target_feature" ) ;
903+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "target_feature" ) ;
898904 }
899905 _ => {
900906 self . dcx ( ) . emit_err ( errors:: AttrShouldBeAppliedToFn {
@@ -1609,7 +1615,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16091615 // erroneously allowed it and some crates used it accidentally, to be compatible
16101616 // with crates depending on them, we can't throw an error here.
16111617 Target :: Field | Target :: Arm | Target :: MacroDef => {
1612- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "cold" ) ;
1618+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "cold" ) ;
16131619 }
16141620 _ => {
16151621 // FIXME: #[cold] was previously allowed on non-functions and some crates used
@@ -1651,7 +1657,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16511657 // erroneously allowed it and some crates used it accidentally, to be compatible
16521658 // with crates depending on them, we can't throw an error here.
16531659 Target :: Field | Target :: Arm | Target :: MacroDef => {
1654- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "link_name" ) ;
1660+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "link_name" ) ;
16551661 }
16561662 _ => {
16571663 // FIXME: #[cold] was previously allowed on non-functions/statics and some crates
@@ -1685,7 +1691,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16851691 // erroneously allowed it and some crates used it accidentally, to be compatible
16861692 // with crates depending on them, we can't throw an error here.
16871693 Target :: Field | Target :: Arm | Target :: MacroDef => {
1688- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "no_link" ) ;
1694+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "no_link" ) ;
16891695 }
16901696 _ => {
16911697 self . dcx ( ) . emit_err ( errors:: NoLink { attr_span : attr. span ( ) , span } ) ;
@@ -1707,7 +1713,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17071713 // erroneously allowed it and some crates used it accidentally, to be compatible
17081714 // with crates depending on them, we can't throw an error here.
17091715 Target :: Field | Target :: Arm | Target :: MacroDef => {
1710- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "export_name" ) ;
1716+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "export_name" ) ;
17111717 }
17121718 _ => {
17131719 self . dcx ( ) . emit_err ( errors:: ExportName { attr_span : attr. span ( ) , span } ) ;
@@ -1881,7 +1887,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18811887 // erroneously allowed it and some crates used it accidentally, to be compatible
18821888 // with crates depending on them, we can't throw an error here.
18831889 Target :: Field | Target :: Arm | Target :: MacroDef => {
1884- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "link_section" ) ;
1890+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "link_section" ) ;
18851891 }
18861892 _ => {
18871893 // FIXME: #[link_section] was previously allowed on non-functions/statics and some
@@ -1906,7 +1912,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19061912 // erroneously allowed it and some crates used it accidentally, to be compatible
19071913 // with crates depending on them, we can't throw an error here.
19081914 Target :: Field | Target :: Arm | Target :: MacroDef => {
1909- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "no_mangle" ) ;
1915+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "no_mangle" ) ;
19101916 }
19111917 // FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19121918 // The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -2253,9 +2259,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22532259 // `#[allow_internal_unstable]` attribute with just a lint, because we previously
22542260 // erroneously allowed it and some crates used it accidentally, to be compatible
22552261 // with crates depending on them, we can't throw an error here.
2256- Target :: Field | Target :: Arm | Target :: MacroDef => {
2257- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "allow_internal_unstable" )
2258- }
2262+ Target :: Field | Target :: Arm | Target :: MacroDef => self
2263+ . inline_attr_str_error_with_macro_def (
2264+ hir_id,
2265+ attr. span ( ) ,
2266+ "allow_internal_unstable" ,
2267+ ) ,
22592268 _ => {
22602269 self . tcx
22612270 . dcx ( )
@@ -2628,8 +2637,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26282637 span : Span ,
26292638 target : Target ,
26302639 ) {
2631- let force_inline_attr = attrs. iter ( ) . find ( |attr| attr. has_name ( sym:: rustc_force_inline) ) ;
2632- match ( target, force_inline_attr) {
2640+ match (
2641+ target,
2642+ find_attr ! ( attrs, AttributeKind :: Inline ( InlineAttr :: Force { attr_span, .. } , _) => * attr_span) ,
2643+ ) {
26332644 ( Target :: Closure , None ) => {
26342645 let is_coro = matches ! (
26352646 self . tcx. hir_expect_expr( hir_id) . kind,
@@ -2641,20 +2652,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26412652 ) ;
26422653 let parent_did = self . tcx . hir_get_parent_item ( hir_id) . to_def_id ( ) ;
26432654 let parent_span = self . tcx . def_span ( parent_did) ;
2644- let parent_force_inline_attr =
2645- self . tcx . get_attr ( parent_did, sym:: rustc_force_inline) ;
2646- if let Some ( attr) = parent_force_inline_attr
2647- && is_coro
2655+
2656+ if let Some ( attr_span) = find_attr ! (
2657+ self . tcx. get_all_attrs( parent_did) ,
2658+ AttributeKind :: Inline ( InlineAttr :: Force { attr_span, .. } , _) => * attr_span
2659+ ) && is_coro
26482660 {
2649- self . dcx ( ) . emit_err ( errors:: RustcForceInlineCoro {
2650- attr_span : attr. span ( ) ,
2651- span : parent_span,
2652- } ) ;
2661+ self . dcx ( )
2662+ . emit_err ( errors:: RustcForceInlineCoro { attr_span, span : parent_span } ) ;
26532663 }
26542664 }
26552665 ( Target :: Fn , _) => ( ) ,
2656- ( _, Some ( attr ) ) => {
2657- self . dcx ( ) . emit_err ( errors:: RustcForceInline { attr_span : attr . span ( ) , span } ) ;
2666+ ( _, Some ( attr_span ) ) => {
2667+ self . dcx ( ) . emit_err ( errors:: RustcForceInline { attr_span, span } ) ;
26582668 }
26592669 ( _, None ) => ( ) ,
26602670 }
@@ -2875,10 +2885,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28752885fn check_non_exported_macro_for_invalid_attrs ( tcx : TyCtxt < ' _ > , item : & Item < ' _ > ) {
28762886 let attrs = tcx. hir_attrs ( item. hir_id ( ) ) ;
28772887
2878- for attr in attrs {
2879- if attr. has_name ( sym:: inline) {
2880- tcx. dcx ( ) . emit_err ( errors:: NonExportedMacroInvalidAttrs { attr_span : attr. span ( ) } ) ;
2881- }
2888+ if let Some ( attr_span) = find_attr ! ( attrs, AttributeKind :: Inline ( _, span) => * span) {
2889+ tcx. dcx ( ) . emit_err ( errors:: NonExportedMacroInvalidAttrs { attr_span } ) ;
28822890 }
28832891}
28842892
@@ -2898,6 +2906,7 @@ pub(crate) fn provide(providers: &mut Providers) {
28982906 * providers = Providers { check_mod_attrs, ..* providers } ;
28992907}
29002908
2909+ // FIXME(jdonszelmann): remove, check during parsing
29012910fn check_duplicates (
29022911 tcx : TyCtxt < ' _ > ,
29032912 attr : & Attribute ,
0 commit comments