File tree Expand file tree Collapse file tree 8 files changed +96
-6
lines changed Expand file tree Collapse file tree 8 files changed +96
-6
lines changed Original file line number Diff line number Diff line change @@ -172,6 +172,8 @@ impl CodegenFnAttrs {
172172 /// * `#[no_mangle]` is present
173173 /// * `#[export_name(...)]` is present
174174 /// * `#[linkage]` is present
175+ ///
176+ /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
175177 pub fn contains_extern_indicator ( & self ) -> bool {
176178 self . flags . contains ( CodegenFnAttrFlags :: NO_MANGLE )
177179 || self . export_name . is_some ( )
Original file line number Diff line number Diff line change @@ -117,6 +117,7 @@ impl<'tcx> MonoItem<'tcx> {
117117
118118 // If the function is #[naked] or contains any other attribute that requires exactly-once
119119 // instantiation:
120+ // We emit an unused_attributes lint for this case, which should be kept in sync if possible.
120121 let codegen_fn_attrs = tcx. codegen_fn_attrs ( instance. def_id ( ) ) ;
121122 if codegen_fn_attrs. contains_extern_indicator ( )
122123 || codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: NAKED )
Original file line number Diff line number Diff line change @@ -383,6 +383,10 @@ passes_inline_ignored_constants =
383383 .warn = { -passes_previously_accepted }
384384 .note = { -passes_see_issue (issue : " 65833 " )}
385385
386+ passes_inline_ignored_for_exported =
387+ `#[inline]` is ignored on externally exported functions
388+ .help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
389+
386390passes_inline_ignored_function_prototype =
387391 `#[inline]` is ignored on function prototypes
388392
Original file line number Diff line number Diff line change @@ -445,6 +445,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
445445 } ) ;
446446 }
447447 }
448+
449+ // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
450+ if let Some ( did) = hir_id. as_owner ( )
451+ && self . tcx . def_kind ( did) . has_codegen_attrs ( )
452+ && !matches ! ( attr. meta_item_list( ) . as_deref( ) , Some ( [ item] ) if item. has_name( sym:: never) )
453+ {
454+ let attrs = self . tcx . codegen_fn_attrs ( did) ;
455+ // Not checking naked as `#[inline]` is forbidden for naked functions anyways.
456+ if attrs. contains_extern_indicator ( ) {
457+ self . tcx . emit_node_span_lint (
458+ UNUSED_ATTRIBUTES ,
459+ hir_id,
460+ attr. span ( ) ,
461+ errors:: InlineIgnoredForExported { } ,
462+ ) ;
463+ }
464+ }
448465 }
449466
450467 /// Checks that `#[coverage(..)]` is applied to a function/closure/method,
Original file line number Diff line number Diff line change @@ -1435,6 +1435,11 @@ pub(crate) struct OnlyHasEffectOn {
14351435 pub target_name : String ,
14361436}
14371437
1438+ #[ derive( LintDiagnostic ) ]
1439+ #[ diag( passes_inline_ignored_for_exported) ]
1440+ #[ help]
1441+ pub ( crate ) struct InlineIgnoredForExported { }
1442+
14381443#[ derive( Diagnostic ) ]
14391444#[ diag( passes_object_lifetime_err) ]
14401445pub ( crate ) struct ObjectLifetimeErr {
Original file line number Diff line number Diff line change 1+ //! Ensure the unused_attributes lint fires for externally exported functions with `#[inline]`,
2+ //! because `#[inline]` is ignored for such functions.
3+
4+ #![ crate_type = "lib" ]
5+
6+ #![ feature( linkage) ]
7+ #![ feature( naked_functions) ]
8+ #![ deny( unused_attributes) ]
9+
10+ #[ inline]
11+ //~^ ERROR: `#[inline]` is ignored on externally exported functions
12+ #[ no_mangle]
13+ fn no_mangle ( ) { }
14+
15+ #[ inline]
16+ //~^ ERROR: `#[inline]` is ignored on externally exported functions
17+ #[ export_name = "export_name" ]
18+ fn export_name ( ) { }
19+
20+ #[ inline]
21+ //~^ ERROR: `#[inline]` is ignored on externally exported functions
22+ #[ linkage = "external" ]
23+ fn external_linkage ( ) { }
24+
25+ #[ inline]
26+ fn normal ( ) { }
27+
28+ #[ inline]
29+ #[ linkage = "internal" ] // not exported
30+ fn internal_linkage ( ) { }
Original file line number Diff line number Diff line change 1+ error: `#[inline]` is ignored on externally exported functions
2+ --> $DIR/inline-exported.rs:10:1
3+ |
4+ LL | #[inline]
5+ | ^^^^^^^^^
6+ |
7+ = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
8+ note: the lint level is defined here
9+ --> $DIR/inline-exported.rs:8:9
10+ |
11+ LL | #![deny(unused_attributes)]
12+ | ^^^^^^^^^^^^^^^^^
13+
14+ error: `#[inline]` is ignored on externally exported functions
15+ --> $DIR/inline-exported.rs:15:1
16+ |
17+ LL | #[inline]
18+ | ^^^^^^^^^
19+ |
20+ = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
21+
22+ error: `#[inline]` is ignored on externally exported functions
23+ --> $DIR/inline-exported.rs:20:1
24+ |
25+ LL | #[inline]
26+ | ^^^^^^^^^
27+ |
28+ = help: externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
29+
30+ error: aborting due to 3 previous errors
31+
Original file line number Diff line number Diff line change 9898LL | trait Baz {}
9999 | ------------ not a function definition
100100
101+ error: cannot use `#[inline(always)]` with `#[target_feature]`
102+ --> $DIR/invalid-attribute.rs:69:1
103+ |
104+ LL | #[inline(always)]
105+ | ^^^^^^^^^^^^^^^^^
106+
101107error: attribute should be applied to a function definition
102108 --> $DIR/invalid-attribute.rs:74:1
103109 |
@@ -163,12 +169,6 @@ error: malformed `target_feature` attribute input
163169LL | #[target_feature(disable = "baz")]
164170 | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
165171
166- error: cannot use `#[inline(always)]` with `#[target_feature]`
167- --> $DIR/invalid-attribute.rs:69:1
168- |
169- LL | #[inline(always)]
170- | ^^^^^^^^^^^^^^^^^
171-
172172error[E0046]: not all trait items implemented, missing: `foo`
173173 --> $DIR/invalid-attribute.rs:81:1
174174 |
You can’t perform that action at this time.
0 commit comments