Auto merge of #114470 - pnkfelix:dont-export-no-mangle-from-proc-macros-issue-99978, r=bjorn3
Restrict linker version script of proc-macro crates to just its two symbols Restrict linker version script of proc-macro crates to just the two symbols of each proc-macro crate. The main known effect of doing this is to stop including `#[no_mangle]` symbols in the linker version script. Background: The combination of a proc-macro crate with an import of another crate that itself exports a no_mangle function was broken for a period of time, because: * In PR #99944 we stopped exporting no_mangle symbols from proc-macro crates; proc-macro crates have a very limited interface and are meant to be treated as a blackbox to everything except rustc itself. However: he constructed linker version script still referred to them, but resolving that discrepancy was left as a FIXME in the code, tagged with issue #99978. * 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 provided as linker input. So the unresolved discrepancy from #99978 started surfacing as a compile-time error (e.g. #111888). Fix #111888 Fix #99978.
This commit is contained in:
commit
a946c1e017
3 changed files with 55 additions and 3 deletions
|
@ -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<St
|
|||
return exports.iter().map(ToString::to_string).collect();
|
||||
}
|
||||
|
||||
let mut symbols = Vec::new();
|
||||
if let CrateType::ProcMacro = crate_type {
|
||||
exported_symbols_for_proc_macro_crate(tcx)
|
||||
} else {
|
||||
exported_symbols_for_non_proc_macro(tcx, crate_type)
|
||||
}
|
||||
}
|
||||
|
||||
fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
|
||||
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,19 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
|
|||
symbols
|
||||
}
|
||||
|
||||
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
|
||||
// `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);
|
||||
|
||||
vec![proc_macro_decls_name, metadata_symbol_name]
|
||||
}
|
||||
|
||||
pub(crate) fn linked_symbols(
|
||||
tcx: TyCtxt<'_>,
|
||||
crate_type: CrateType,
|
||||
|
|
11
tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
Normal file
11
tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![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() { }
|
22
tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
Normal file
22
tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// build-pass
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
// 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;
|
Loading…
Add table
Reference in a new issue