From 3000c24afc37fe09c65772a71331002a7505dc11 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 21 Jul 2023 09:41:07 -0400 Subject: [PATCH 1/5] special-case proc-macro crates in rustc_codegen_ssa::back::linker::exported_symbols to only export the two symbols that proc-macros need. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 4c04fc60b9836..74b81733356a4 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -13,6 +13,7 @@ use std::{env, mem, str}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; use rustc_middle::middle::dependency_format::Linkage; +use rustc_middle::middle::exported_symbols; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; @@ -659,8 +660,6 @@ impl<'a> Linker for GccLinker<'a> { return; } - // FIXME(#99978) hide #[no_mangle] symbols for proc-macros - let is_windows = self.sess.target.is_like_windows; let path = tmpdir.join(if is_windows { "list.def" } else { "list" }); @@ -1679,8 +1678,15 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec, crate_type: CrateType) -> Vec { + let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { if info.level.is_below_threshold(export_threshold) { @@ -1691,6 +1697,26 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec) -> Vec { + let mut symbols = Vec::new(); + + let stable_crate_id = tcx.sess.local_stable_crate_id(); + let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); + let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); + + // You would think that both the two names would always be there, but in + // pnkfelix's local experiments that was not case. So instead we walk the + // list and only add them if they *are* there. + for_each_exported_symbols_include_dep(tcx, CrateType::ProcMacro, |symbol, _info, cnum| { + let name = symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum); + if name == proc_macro_decls_name || name == metadata_symbol_name { + symbols.push(name); + } + }); + + return symbols; +} + pub(crate) fn linked_symbols( tcx: TyCtxt<'_>, crate_type: CrateType, From 7a0e2ee133dacf4e2dbda64a316a95746a469c58 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 4 Aug 2023 11:29:41 -0400 Subject: [PATCH 2/5] regression test for issue 111888. --- .../proc-macro/auxiliary/exports_no_mangle.rs | 9 +++++++++ .../no-mangle-in-proc-macro-issue-111888.rs | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/proc-macro/auxiliary/exports_no_mangle.rs create mode 100644 tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs diff --git a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs new file mode 100644 index 0000000000000..ef5bf94b0358c --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs @@ -0,0 +1,9 @@ +#![crate_type="lib"] + +// Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.) +// exports a no_mangle function; that combination of acts was broken for some +// period of time. See further discussion in the test file that imports this +// crate. + +#[no_mangle] +pub fn some_no_mangle_function() { } diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs new file mode 100644 index 0000000000000..087c9a2f0652a --- /dev/null +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:exports_no_mangle.rs +#![crate_type = "proc-macro"] + +// Issue #111888: this proc-macro crate imports another crate that itself +// exports a no_mangle function. +// +// That combination was broken for a period of time, because: +// +// In PR #99944 we *stopped* exporting no_mangle symbols from +// proc-macro crates. The constructed linker version script still referred +// to them, but resolving that discrepancy was left as a FIXME in the code. +// +// In PR #108017 we started telling the linker to check (via the +// `--no-undefined-version` linker invocation flag) that every symbol referenced +// in the "linker version script" is actually present in the linker input. So +// the unresolved discrepancy from #99944 started surfacing as a compile-time +// error. + +extern crate exports_no_mangle; From 5881e5f88d9245ef9259ca600b32af80d5972a7f Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Fri, 4 Aug 2023 12:11:34 -0400 Subject: [PATCH 3/5] Update tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs fix to test as proposed by wesleywiser Co-authored-by: Wesley Wiser --- tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs index 087c9a2f0652a..de2ca496cafba 100644 --- a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -1,4 +1,4 @@ -// run-pass +// build-pass // aux-build:exports_no_mangle.rs #![crate_type = "proc-macro"] From a2058ddbed82adda55ce39f0e0915996706cb2b9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 7 Aug 2023 13:31:14 -0400 Subject: [PATCH 4/5] Review feedback: return empty iff !should_codegen, and use simpler unconditional logic otherwise. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 74b81733356a4..a1e322f4b3130 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1698,23 +1698,16 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) - } fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec { - let mut symbols = Vec::new(); + // `exported_symbols` will be empty when !should_codegen. + if !tcx.sess.opts.output_types.should_codegen() { + return Vec::new(); + } let stable_crate_id = tcx.sess.local_stable_crate_id(); let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); - // You would think that both the two names would always be there, but in - // pnkfelix's local experiments that was not case. So instead we walk the - // list and only add them if they *are* there. - for_each_exported_symbols_include_dep(tcx, CrateType::ProcMacro, |symbol, _info, cnum| { - let name = symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum); - if name == proc_macro_decls_name || name == metadata_symbol_name { - symbols.push(name); - } - }); - - return symbols; + vec![proc_macro_decls_name, metadata_symbol_name] } pub(crate) fn linked_symbols( From a2a7f27fd2548874b203f1f577f64cf61627e0a5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 8 Aug 2023 11:40:35 -0400 Subject: [PATCH 5/5] fix proc-macro test added here to solely be exercised as a build product for the host. thus we should no longer see test failures for e.g. wasm32 target. --- tests/ui/proc-macro/auxiliary/exports_no_mangle.rs | 2 ++ tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs index ef5bf94b0358c..a8a478ffc74c4 100644 --- a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs +++ b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs @@ -1,3 +1,5 @@ +// force-host +// no-prefer-dynamic #![crate_type="lib"] // Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.) diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs index de2ca496cafba..4e5208e50580b 100644 --- a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -1,4 +1,6 @@ // build-pass +// force-host +// no-prefer-dynamic // aux-build:exports_no_mangle.rs #![crate_type = "proc-macro"]