Rollup merge of #138842 - Noratrieb:inline-exported, r=me,saethlin
Emit `unused_attributes` for `#[inline]` on exported functions I saw someone post a code sample that contained these two attributes, which immediately made me suspicious. My suspicions were confirmed when I did a small test and checked the compiler source code to confirm that in these cases, `#[inline]` is indeed ignored (because you can't exactly `LocalCopy`an unmangled symbol since that would lead to duplicate symbols, and doing a mix of an unmangled `GloballyShared` and mangled `LocalCopy` instantiation is too complicated for our current instatiation mode logic, which I don't want to change right now). So instead, emit the usual unused attribute lint with a message saying that the attribute is ignored in this position. I think this is not 100% true, since I expect LLVM `inlinehint` to still be applied to such a function, but that's not why people use this attribute, they use it for the `LocalCopy` instantiation mode, where it doesn't work. r? saethlin as the instantiation guy Procedurally, I think this should be fine to merge without any lang involvement, as this only does a very minor extension to an existing lint.
This commit is contained in:
commit
ac05597cd7
8 changed files with 96 additions and 6 deletions
|
@ -383,6 +383,10 @@ passes_inline_ignored_constants =
|
|||
.warn = {-passes_previously_accepted}
|
||||
.note = {-passes_see_issue(issue: "65833")}
|
||||
|
||||
passes_inline_ignored_for_exported =
|
||||
`#[inline]` is ignored on externally exported functions
|
||||
.help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
|
||||
|
||||
passes_inline_ignored_function_prototype =
|
||||
`#[inline]` is ignored on function prototypes
|
||||
|
||||
|
|
|
@ -451,6 +451,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
|
||||
if let Some(did) = hir_id.as_owner()
|
||||
&& self.tcx.def_kind(did).has_codegen_attrs()
|
||||
&& !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never))
|
||||
{
|
||||
let attrs = self.tcx.codegen_fn_attrs(did);
|
||||
// Not checking naked as `#[inline]` is forbidden for naked functions anyways.
|
||||
if attrs.contains_extern_indicator() {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
errors::InlineIgnoredForExported {},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that `#[coverage(..)]` is applied to a function/closure/method,
|
||||
|
|
|
@ -1441,6 +1441,11 @@ pub(crate) struct OnlyHasEffectOn {
|
|||
pub target_name: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_inline_ignored_for_exported)]
|
||||
#[help]
|
||||
pub(crate) struct InlineIgnoredForExported {}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_object_lifetime_err)]
|
||||
pub(crate) struct ObjectLifetimeErr {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue