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:
Jonathan Brouwer
2025-06-24 23:05:45 +02:00
parent 287d9afce7
commit 3d1cee5324
12 changed files with 133 additions and 81 deletions

View File

@@ -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