mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 18:27:37 +00:00
Move mixed export_name/no_mangle check to check_attr.rs and improve the error
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
This commit is contained in:
parent
287d9afce7
commit
3d1cee5324
@ -205,11 +205,6 @@ codegen_ssa_missing_features = add the missing features in a `target_feature` at
|
||||
codegen_ssa_missing_query_depgraph =
|
||||
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
|
||||
|
||||
codegen_ssa_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `#[export_name]`
|
||||
.label = `{$no_mangle_attr}` is ignored
|
||||
.note = `#[export_name]` takes precedence
|
||||
.suggestion = remove the `{$no_mangle_attr}` attribute
|
||||
|
||||
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
|
||||
|
||||
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
|
||||
|
@ -9,7 +9,7 @@ use rustc_attr_data_structures::{
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
|
||||
use rustc_hir::{self as hir, HirId, LangItem, lang_items};
|
||||
use rustc_hir::{self as hir, LangItem, lang_items};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
};
|
||||
@ -87,7 +87,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
|
||||
let mut link_ordinal_span = None;
|
||||
let mut no_sanitize_span = None;
|
||||
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
|
||||
|
||||
for attr in attrs.iter() {
|
||||
// In some cases, attribute are only valid on functions, but it's the `check_attr`
|
||||
@ -119,20 +118,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
.max();
|
||||
}
|
||||
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
|
||||
AttributeKind::ExportName { name, span: attr_span } => {
|
||||
AttributeKind::ExportName { name, .. } => {
|
||||
codegen_fn_attrs.export_name = Some(*name);
|
||||
mixed_export_name_no_mangle_lint_state.track_export_name(*attr_span);
|
||||
}
|
||||
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
|
||||
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
|
||||
AttributeKind::NoMangle(attr_span) => {
|
||||
if tcx.opt_item_name(did.to_def_id()).is_some() {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||
mixed_export_name_no_mangle_lint_state.track_no_mangle(
|
||||
*attr_span,
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
attr,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().emit_err(NoMangleNameless {
|
||||
span: *attr_span,
|
||||
@ -437,8 +430,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
}
|
||||
}
|
||||
|
||||
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
|
||||
|
||||
// Apply the minimum function alignment here, so that individual backends don't have to.
|
||||
codegen_fn_attrs.alignment =
|
||||
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
|
||||
@ -665,49 +656,6 @@ fn check_link_name_xor_ordinal(
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MixedExportNameAndNoMangleState<'a> {
|
||||
export_name: Option<Span>,
|
||||
hir_id: Option<HirId>,
|
||||
no_mangle: Option<Span>,
|
||||
no_mangle_attr: Option<&'a hir::Attribute>,
|
||||
}
|
||||
|
||||
impl<'a> MixedExportNameAndNoMangleState<'a> {
|
||||
fn track_export_name(&mut self, span: Span) {
|
||||
self.export_name = Some(span);
|
||||
}
|
||||
|
||||
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) {
|
||||
self.no_mangle = Some(span);
|
||||
self.hir_id = Some(hir_id);
|
||||
self.no_mangle_attr = Some(attr_name);
|
||||
}
|
||||
|
||||
/// Emit diagnostics if the lint condition is met.
|
||||
fn lint_if_mixed(self, tcx: TyCtxt<'_>) {
|
||||
if let Self {
|
||||
export_name: Some(export_name),
|
||||
no_mangle: Some(no_mangle),
|
||||
hir_id: Some(hir_id),
|
||||
no_mangle_attr: Some(_),
|
||||
} = self
|
||||
{
|
||||
tcx.emit_node_span_lint(
|
||||
lint::builtin::UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
no_mangle,
|
||||
errors::MixedExportNameAndNoMangle {
|
||||
no_mangle,
|
||||
no_mangle_attr: "#[unsafe(no_mangle)]".to_string(),
|
||||
export_name,
|
||||
removal_span: no_mangle,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
|
||||
/// macros. There are two forms. The pure one without args to mark primal functions (the functions
|
||||
/// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the
|
||||
|
@ -1200,18 +1200,6 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> {
|
||||
#[diag(codegen_ssa_aix_strip_not_used)]
|
||||
pub(crate) struct AixStripNotUsed;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(codegen_ssa_mixed_export_name_and_no_mangle)]
|
||||
pub(crate) struct MixedExportNameAndNoMangle {
|
||||
#[label]
|
||||
pub no_mangle: Span,
|
||||
pub no_mangle_attr: String,
|
||||
#[note]
|
||||
pub export_name: Span,
|
||||
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
|
||||
pub removal_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic, Debug)]
|
||||
pub(crate) enum XcrunError {
|
||||
#[diag(codegen_ssa_xcrun_failed_invoking)]
|
||||
|
@ -486,6 +486,11 @@ passes_missing_panic_handler =
|
||||
passes_missing_stability_attr =
|
||||
{$descr} has missing stability attribute
|
||||
|
||||
passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`
|
||||
.label = `{$no_mangle_attr}` is ignored
|
||||
.note = `{$export_name_attr}` takes precedence
|
||||
.suggestion = remove the `{$no_mangle_attr}` attribute
|
||||
|
||||
passes_multiple_rustc_main =
|
||||
multiple functions with a `#[rustc_main]` attribute
|
||||
.first = first `#[rustc_main]` function
|
||||
|
@ -30,11 +30,13 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypingMode};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::lint;
|
||||
use rustc_session::lint::builtin::{
|
||||
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
|
||||
};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, sym};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
|
||||
@ -403,6 +405,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
self.check_repr(attrs, span, target, item, hir_id);
|
||||
self.check_used(attrs, target, span);
|
||||
self.check_rustc_force_inline(hir_id, attrs, span, target);
|
||||
self.check_mix_no_mangle_export(hir_id, attrs);
|
||||
}
|
||||
|
||||
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
|
||||
@ -2628,6 +2631,36 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_mix_no_mangle_export(&self, hir_id: HirId, attrs: &[Attribute]) {
|
||||
if let Some(export_name_span) = find_attr!(attrs, AttributeKind::ExportName { span: export_name_span, .. } => *export_name_span)
|
||||
&& let Some(no_mangle_span) =
|
||||
find_attr!(attrs, AttributeKind::NoMangle(no_mangle_span) => *no_mangle_span)
|
||||
{
|
||||
let no_mangle_attr = if no_mangle_span.edition() >= Edition::Edition2024 {
|
||||
"#[unsafe(no_mangle)]"
|
||||
} else {
|
||||
"#[no_mangle]"
|
||||
};
|
||||
let export_name_attr = if export_name_span.edition() >= Edition::Edition2024 {
|
||||
"#[unsafe(export_name)]"
|
||||
} else {
|
||||
"#[export_name]"
|
||||
};
|
||||
|
||||
self.tcx.emit_node_span_lint(
|
||||
lint::builtin::UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
no_mangle_span,
|
||||
errors::MixedExportNameAndNoMangle {
|
||||
no_mangle_span,
|
||||
export_name_span,
|
||||
no_mangle_attr,
|
||||
export_name_attr,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `#[autodiff]` is applied to an item other than a function item.
|
||||
fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) {
|
||||
debug!("check_autodiff");
|
||||
|
@ -49,6 +49,18 @@ pub(crate) struct ConstContinueAttr {
|
||||
pub node_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_mixed_export_name_and_no_mangle)]
|
||||
pub(crate) struct MixedExportNameAndNoMangle {
|
||||
#[label]
|
||||
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
|
||||
pub no_mangle_span: Span,
|
||||
#[note]
|
||||
pub export_name_span: Span,
|
||||
pub no_mangle_attr: &'static str,
|
||||
pub export_name_attr: &'static str,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_outer_crate_level_attr)]
|
||||
pub(crate) struct OuterCrateLevelAttr;
|
||||
|
@ -3,11 +3,11 @@
|
||||
//@ check-pass
|
||||
|
||||
#![warn(unused_attributes)]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
#[export_name = "foo"]
|
||||
pub fn bar() {}
|
||||
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
#[export_name = "baz"]
|
||||
pub fn bak() {}
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
#![warn(unused_attributes)]
|
||||
#[no_mangle]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
#[export_name = "foo"]
|
||||
pub fn bar() {}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||
#[export_name = "baz"]
|
||||
pub fn bak() {}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
|
||||
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
|
||||
--> $DIR/mixed_export_name_and_no_mangle.rs:6:1
|
||||
|
|
||||
LL | #[no_mangle]
|
||||
| ^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
|
||||
| ^^^^^^^^^^^^ `#[no_mangle]` is ignored
|
||||
|
|
||||
note: `#[export_name]` takes precedence
|
||||
--> $DIR/mixed_export_name_and_no_mangle.rs:8:1
|
||||
@ -14,23 +14,23 @@ note: the lint level is defined here
|
||||
|
|
||||
LL | #![warn(unused_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
help: remove the `#[unsafe(no_mangle)]` attribute
|
||||
help: remove the `#[no_mangle]` attribute
|
||||
|
|
||||
LL - #[no_mangle]
|
||||
|
|
||||
|
||||
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
|
||||
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
|
||||
--> $DIR/mixed_export_name_and_no_mangle.rs:11:1
|
||||
|
|
||||
LL | #[unsafe(no_mangle)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `#[no_mangle]` is ignored
|
||||
|
|
||||
note: `#[export_name]` takes precedence
|
||||
--> $DIR/mixed_export_name_and_no_mangle.rs:13:1
|
||||
|
|
||||
LL | #[export_name = "baz"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: remove the `#[unsafe(no_mangle)]` attribute
|
||||
help: remove the `#[no_mangle]` attribute
|
||||
|
|
||||
LL - #[unsafe(no_mangle)]
|
||||
|
|
||||
|
@ -0,0 +1,15 @@
|
||||
// issue: rust-lang/rust#47446
|
||||
//@ run-rustfix
|
||||
//@ check-pass
|
||||
//@ edition:2024
|
||||
|
||||
#![warn(unused_attributes)]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
|
||||
#[unsafe(export_name = "foo")]
|
||||
pub fn bar() {}
|
||||
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
|
||||
#[unsafe(export_name = "baz")]
|
||||
pub fn bak() {}
|
||||
|
||||
fn main() {}
|
17
tests/ui/attributes/mixed_export_name_and_no_mangle_2024.rs
Normal file
17
tests/ui/attributes/mixed_export_name_and_no_mangle_2024.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// issue: rust-lang/rust#47446
|
||||
//@ run-rustfix
|
||||
//@ check-pass
|
||||
//@ edition:2024
|
||||
|
||||
#![warn(unused_attributes)]
|
||||
#[unsafe(no_mangle)]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
|
||||
#[unsafe(export_name = "foo")]
|
||||
pub fn bar() {}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
|
||||
#[unsafe(export_name = "baz")]
|
||||
pub fn bak() {}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,39 @@
|
||||
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]`
|
||||
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:7:1
|
||||
|
|
||||
LL | #[unsafe(no_mangle)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
|
||||
|
|
||||
note: `#[unsafe(export_name)]` takes precedence
|
||||
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:9:1
|
||||
|
|
||||
LL | #[unsafe(export_name = "foo")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: the lint level is defined here
|
||||
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:6:9
|
||||
|
|
||||
LL | #![warn(unused_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
help: remove the `#[unsafe(no_mangle)]` attribute
|
||||
|
|
||||
LL - #[unsafe(no_mangle)]
|
||||
|
|
||||
|
||||
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]`
|
||||
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:12:1
|
||||
|
|
||||
LL | #[unsafe(no_mangle)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
|
||||
|
|
||||
note: `#[unsafe(export_name)]` takes precedence
|
||||
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:14:1
|
||||
|
|
||||
LL | #[unsafe(export_name = "baz")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: remove the `#[unsafe(no_mangle)]` attribute
|
||||
|
|
||||
LL - #[unsafe(no_mangle)]
|
||||
|
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
Loading…
x
Reference in New Issue
Block a user