@@ -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 {
@@ -1607,7 +1613,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16071613 // erroneously allowed it and some crates used it accidentally, to be compatible
16081614 // with crates depending on them, we can't throw an error here.
16091615 Target :: Field | Target :: Arm | Target :: MacroDef => {
1610- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "cold" ) ;
1616+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "cold" ) ;
16111617 }
16121618 _ => {
16131619 // FIXME: #[cold] was previously allowed on non-functions and some crates used
@@ -1649,7 +1655,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16491655 // erroneously allowed it and some crates used it accidentally, to be compatible
16501656 // with crates depending on them, we can't throw an error here.
16511657 Target :: Field | Target :: Arm | Target :: MacroDef => {
1652- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "link_name" ) ;
1658+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "link_name" ) ;
16531659 }
16541660 _ => {
16551661 // FIXME: #[cold] was previously allowed on non-functions/statics and some crates
@@ -1683,7 +1689,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16831689 // erroneously allowed it and some crates used it accidentally, to be compatible
16841690 // with crates depending on them, we can't throw an error here.
16851691 Target :: Field | Target :: Arm | Target :: MacroDef => {
1686- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "no_link" ) ;
1692+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "no_link" ) ;
16871693 }
16881694 _ => {
16891695 self . dcx ( ) . emit_err ( errors:: NoLink { attr_span : attr. span ( ) , span } ) ;
@@ -1705,7 +1711,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17051711 // erroneously allowed it and some crates used it accidentally, to be compatible
17061712 // with crates depending on them, we can't throw an error here.
17071713 Target :: Field | Target :: Arm | Target :: MacroDef => {
1708- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "export_name" ) ;
1714+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "export_name" ) ;
17091715 }
17101716 _ => {
17111717 self . dcx ( ) . emit_err ( errors:: ExportName { attr_span : attr. span ( ) , span } ) ;
@@ -1879,7 +1885,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18791885 // erroneously allowed it and some crates used it accidentally, to be compatible
18801886 // with crates depending on them, we can't throw an error here.
18811887 Target :: Field | Target :: Arm | Target :: MacroDef => {
1882- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "link_section" ) ;
1888+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "link_section" ) ;
18831889 }
18841890 _ => {
18851891 // FIXME: #[link_section] was previously allowed on non-functions/statics and some
@@ -1904,7 +1910,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19041910 // erroneously allowed it and some crates used it accidentally, to be compatible
19051911 // with crates depending on them, we can't throw an error here.
19061912 Target :: Field | Target :: Arm | Target :: MacroDef => {
1907- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "no_mangle" ) ;
1913+ self . inline_attr_str_error_with_macro_def ( hir_id, attr. span ( ) , "no_mangle" ) ;
19081914 }
19091915 // FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19101916 // The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -2251,9 +2257,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22512257 // `#[allow_internal_unstable]` attribute with just a lint, because we previously
22522258 // erroneously allowed it and some crates used it accidentally, to be compatible
22532259 // with crates depending on them, we can't throw an error here.
2254- Target :: Field | Target :: Arm | Target :: MacroDef => {
2255- self . inline_attr_str_error_with_macro_def ( hir_id, attr, "allow_internal_unstable" )
2256- }
2260+ Target :: Field | Target :: Arm | Target :: MacroDef => self
2261+ . inline_attr_str_error_with_macro_def (
2262+ hir_id,
2263+ attr. span ( ) ,
2264+ "allow_internal_unstable" ,
2265+ ) ,
22572266 _ => {
22582267 self . tcx
22592268 . dcx ( )
@@ -2624,8 +2633,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26242633 span : Span ,
26252634 target : Target ,
26262635 ) {
2627- let force_inline_attr = attrs. iter ( ) . find ( |attr| attr. has_name ( sym:: rustc_force_inline) ) ;
2628- match ( target, force_inline_attr) {
2636+ match (
2637+ target,
2638+ find_attr ! ( attrs, AttributeKind :: Inline ( InlineAttr :: Force { attr_span, .. } , _) => * attr_span) ,
2639+ ) {
26292640 ( Target :: Closure , None ) => {
26302641 let is_coro = matches ! (
26312642 self . tcx. hir_expect_expr( hir_id) . kind,
@@ -2637,20 +2648,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26372648 ) ;
26382649 let parent_did = self . tcx . hir_get_parent_item ( hir_id) . to_def_id ( ) ;
26392650 let parent_span = self . tcx . def_span ( parent_did) ;
2640- let parent_force_inline_attr =
2641- self . tcx . get_attr ( parent_did, sym:: rustc_force_inline) ;
2642- if let Some ( attr) = parent_force_inline_attr
2643- && is_coro
2651+
2652+ if let Some ( attr_span) = find_attr ! (
2653+ self . tcx. get_all_attrs( parent_did) ,
2654+ AttributeKind :: Inline ( InlineAttr :: Force { attr_span, .. } , _) => * attr_span
2655+ ) && is_coro
26442656 {
2645- self . dcx ( ) . emit_err ( errors:: RustcForceInlineCoro {
2646- attr_span : attr. span ( ) ,
2647- span : parent_span,
2648- } ) ;
2657+ self . dcx ( )
2658+ . emit_err ( errors:: RustcForceInlineCoro { attr_span, span : parent_span } ) ;
26492659 }
26502660 }
26512661 ( Target :: Fn , _) => ( ) ,
2652- ( _, Some ( attr ) ) => {
2653- self . dcx ( ) . emit_err ( errors:: RustcForceInline { attr_span : attr . span ( ) , span } ) ;
2662+ ( _, Some ( attr_span ) ) => {
2663+ self . dcx ( ) . emit_err ( errors:: RustcForceInline { attr_span, span } ) ;
26542664 }
26552665 ( _, None ) => ( ) ,
26562666 }
@@ -2871,10 +2881,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28712881fn check_non_exported_macro_for_invalid_attrs ( tcx : TyCtxt < ' _ > , item : & Item < ' _ > ) {
28722882 let attrs = tcx. hir_attrs ( item. hir_id ( ) ) ;
28732883
2874- for attr in attrs {
2875- if attr. has_name ( sym:: inline) {
2876- tcx. dcx ( ) . emit_err ( errors:: NonExportedMacroInvalidAttrs { attr_span : attr. span ( ) } ) ;
2877- }
2884+ if let Some ( attr_span) = find_attr ! ( attrs, AttributeKind :: Inline ( _, span) => * span) {
2885+ tcx. dcx ( ) . emit_err ( errors:: NonExportedMacroInvalidAttrs { attr_span } ) ;
28782886 }
28792887}
28802888
@@ -2894,6 +2902,7 @@ pub(crate) fn provide(providers: &mut Providers) {
28942902 * providers = Providers { check_mod_attrs, ..* providers } ;
28952903}
28962904
2905+ // FIXME(jdonszelmann): remove, check during parsing
28972906fn check_duplicates (
28982907 tcx : TyCtxt < ' _ > ,
28992908 attr : & Attribute ,
0 commit comments