Skip to content

Commit 4f90cc2

Browse files
committed
Auto merge of #157981 - JonathanBrouwer:rollup-NojNbtG, r=<try>
Rollup of 12 pull requests try-job: dist-various-1 try-job: test-various try-job: x86_64-gnu-aux try-job: x86_64-gnu-llvm-21-3 try-job: x86_64-msvc-1 try-job: aarch64-apple try-job: x86_64-mingw-1 try-job: i686-msvc-2
2 parents 89a9993 + 0feb5df commit 4f90cc2

122 files changed

Lines changed: 7621 additions & 6177 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ pub(crate) fn expand_deriving_partial_eq(
2222
path: path_std!(marker::StructuralPartialEq),
2323
skip_path_as_bound: true, // crucial!
2424
needs_copy_as_bound_if_packed: false,
25-
additional_bounds: Vec::new(),
25+
// The `StructuralPartialEq` impl must have the *same* bounds as the `PartialEq` impl,
26+
// or it will apply in situations where it should not, such as in the bug
27+
// <https://github.com/rust-lang/rust/issues/147714>.
28+
additional_bounds: vec![ty::Ty::Path(path_std!(cmp::PartialEq))],
2629
// We really don't support unions, but that's already checked by the impl generated below;
2730
// a second check here would lead to redundant error messages.
2831
supports_unions: true,

compiler/rustc_codegen_ssa/src/back/archive.rs

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Cow;
12
use std::env;
23
use std::error::Error;
34
use std::ffi::OsString;
@@ -22,7 +23,7 @@ use tracing::trace;
2223

2324
use super::metadata::{create_compressed_metadata_file, search_for_section};
2425
use super::rmeta_link;
25-
use super::symbol_edit::apply_hide;
26+
use super::symbol_edit::{apply_edits, collect_internal_names};
2627
use crate::common;
2728
// Public for ArchiveBuilderBuilder::extract_bundled_libs
2829
pub use crate::errors::ExtractBundledLibsError;
@@ -314,12 +315,18 @@ pub enum AddArchiveKind<'a> {
314315
Other,
315316
}
316317

318+
pub struct ArchiveSymbols {
319+
pub exported: FxHashSet<String>,
320+
pub rename_suffix: Option<String>,
321+
pub hide: bool,
322+
}
323+
317324
pub trait ArchiveBuilder {
318325
fn add_file(&mut self, path: &Path, kind: ArchiveEntryKind);
319326

320327
fn add_archive(&mut self, archive: &Path, kind: AddArchiveKind<'_>) -> io::Result<()>;
321328

322-
fn build(self: Box<Self>, output: &Path, exported_symbols: Option<FxHashSet<String>>) -> bool;
329+
fn build(self: Box<Self>, output: &Path, symbols: Option<ArchiveSymbols>) -> bool;
323330
}
324331

325332
fn target_archive_format_to_object_kind(format: &str) -> Option<ObjectArchiveKind> {
@@ -534,9 +541,9 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
534541

535542
/// Combine the provided files, rlibs, and native libraries into a single
536543
/// `Archive`.
537-
fn build(self: Box<Self>, output: &Path, exported_symbols: Option<FxHashSet<String>>) -> bool {
544+
fn build(self: Box<Self>, output: &Path, symbols: Option<ArchiveSymbols>) -> bool {
538545
let sess = self.sess;
539-
match self.build_inner(output, exported_symbols) {
546+
match self.build_inner(output, symbols) {
540547
Ok(any_members) => any_members,
541548
Err(error) => {
542549
sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error })
@@ -546,11 +553,7 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
546553
}
547554

548555
impl<'a> ArArchiveBuilder<'a> {
549-
fn build_inner(
550-
self,
551-
output: &Path,
552-
exported_symbols: Option<FxHashSet<String>>,
553-
) -> io::Result<bool> {
556+
fn build_inner(self, output: &Path, symbols: Option<ArchiveSymbols>) -> io::Result<bool> {
554557
let archive_kind = match &*self.sess.target.archive_format {
555558
"gnu" => ArchiveKind::Gnu,
556559
"bsd" => ArchiveKind::Bsd,
@@ -562,6 +565,39 @@ impl<'a> ArArchiveBuilder<'a> {
562565
}
563566
};
564567

568+
// Collect all internally-defined symbol names across every Rust object file.
569+
// This set is needed because rename must also apply to *undefined* references
570+
// (cross-object calls within the staticlib), but we cannot use `!exported.contains(name)`
571+
// alone — that would also match external C symbols like `malloc` which must not be renamed.
572+
let rename = if let Some(sym) = &symbols
573+
&& let Some(rename_suffix) = sym.rename_suffix.as_deref()
574+
{
575+
let mut names = FxHashSet::default();
576+
for (_, entry) in &self.entries {
577+
if entry.kind != ArchiveEntryKind::RustObj {
578+
continue;
579+
}
580+
match &entry.source {
581+
ArchiveEntrySource::Archive { archive_index, file_range } => {
582+
let src_archive = &self.src_archives[*archive_index];
583+
let start = file_range.0 as usize;
584+
let end = start + file_range.1 as usize;
585+
if let Some(data) = src_archive.1.get(start..end) {
586+
collect_internal_names(data, &sym.exported, &mut names);
587+
}
588+
}
589+
ArchiveEntrySource::File(file) => {
590+
if let Ok(data) = fs::read(file) {
591+
collect_internal_names(&data, &sym.exported, &mut names);
592+
}
593+
}
594+
}
595+
}
596+
Some((names, rename_suffix))
597+
} else {
598+
None
599+
};
600+
565601
let mut entries = Vec::new();
566602

567603
for (entry_name, entry) in self.entries {
@@ -588,9 +624,9 @@ impl<'a> ArArchiveBuilder<'a> {
588624
};
589625

590626
if entry.kind == ArchiveEntryKind::RustObj
591-
&& let Some(exported) = &exported_symbols
627+
&& let Some(sym) = &symbols
592628
{
593-
Box::new(apply_hide(data, exported))
629+
Box::new(apply_edits(data, &sym.exported, sym.hide, rename.as_ref()))
594630
} else {
595631
Box::new(data)
596632
}
@@ -602,9 +638,13 @@ impl<'a> ArArchiveBuilder<'a> {
602638
)
603639
.map_err(|err| io_error_context("failed to map object file", err))?;
604640
if entry.kind == ArchiveEntryKind::RustObj
605-
&& let Some(exported) = &exported_symbols
641+
&& let Some(sym) = &symbols
606642
{
607-
Box::new(apply_hide(&mmap, exported))
643+
let edited = apply_edits(&mmap, &sym.exported, sym.hide, rename.as_ref());
644+
match edited {
645+
Cow::Borrowed(_) => Box::new(mmap) as Box<dyn AsRef<[u8]>>,
646+
Cow::Owned(v) => Box::new(v),
647+
}
608648
} else {
609649
Box::new(mmap) as Box<dyn AsRef<[u8]>>
610650
}

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ use rustc_session::{Session, filesearch};
4747
use rustc_span::Symbol;
4848
use rustc_target::spec::crt_objects::CrtObjects;
4949
use rustc_target::spec::{
50-
BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
50+
Arch, BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
5151
LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, Os, RelocModel,
5252
RelroLevel, SanitizerSet, SplitDebuginfo,
5353
};
5454
use tracing::{debug, info, warn};
5555

56-
use super::archive::{AddArchiveKind, ArchiveBuilder, ArchiveBuilderBuilder, ArchiveEntryKind};
56+
use super::archive::{
57+
AddArchiveKind, ArchiveBuilder, ArchiveBuilderBuilder, ArchiveEntryKind, ArchiveSymbols,
58+
};
5759
use super::command::Command;
5860
use super::linker::{self, Linker};
5961
use super::metadata::{MetadataPosition, create_wrapper_file};
@@ -566,11 +568,21 @@ fn link_staticlib(
566568
sess.dcx().emit_fatal(e);
567569
}
568570

569-
let exported_symbols = if sess.opts.unstable_opts.staticlib_hide_internal_symbols {
571+
let hide = sess.opts.unstable_opts.staticlib_hide_internal_symbols;
572+
let rename = sess.opts.unstable_opts.staticlib_rename_internal_symbols;
573+
574+
let exported_symbols = if hide || rename {
570575
if !matches!(sess.target.binary_format, BinaryFormat::Elf | BinaryFormat::MachO) {
571-
sess.dcx().emit_warn(errors::StaticlibHideInternalSymbolsUnsupported {
572-
binary_format: sess.target.archive_format.to_string(),
573-
});
576+
if hide {
577+
sess.dcx().emit_warn(errors::StaticlibHideInternalSymbolsUnsupported {
578+
binary_format: sess.target.archive_format.to_string(),
579+
});
580+
}
581+
if rename {
582+
sess.dcx().emit_warn(errors::StaticlibRenameInternalSymbolsUnsupported {
583+
binary_format: sess.target.archive_format.to_string(),
584+
});
585+
}
574586
None
575587
} else {
576588
crate_info
@@ -581,7 +593,14 @@ fn link_staticlib(
581593
} else {
582594
None
583595
};
584-
ab.build(out_filename, exported_symbols);
596+
597+
let symbols = exported_symbols.map(|exported| ArchiveSymbols {
598+
exported,
599+
rename_suffix: rename.then(|| crate_info.symbol_rename_suffix.clone()),
600+
hide,
601+
});
602+
603+
ab.build(out_filename, symbols);
585604

586605
let crates = crate_info.used_crates.iter();
587606

@@ -2394,6 +2413,69 @@ fn add_rpath_args(
23942413
}
23952414
}
23962415

2416+
fn strip_numeric_suffix<'a>(base: &'a str, suffix: impl AsRef<str>, fallback: &'a str) -> &'a str {
2417+
if suffix.as_ref().parse::<u32>().is_ok() { base } else { fallback }
2418+
}
2419+
2420+
fn undecorate_c_symbol<'a>(
2421+
name: &'a str,
2422+
sess: &Session,
2423+
kind: SymbolExportKind,
2424+
) -> Option<&'a str> {
2425+
match sess.target.binary_format {
2426+
BinaryFormat::MachO => {
2427+
// Mach-O: strip the leading underscore that all external symbols have.
2428+
// The Darwin linker's export_symbols will add it back.
2429+
name.strip_prefix('_')
2430+
}
2431+
BinaryFormat::Coff => {
2432+
// MSVC C++ mangled names start with '?' and use a completely different
2433+
// decorating scheme that includes '@@' as structural delimiters.
2434+
// They must not be subjected to C calling-convention undecoration.
2435+
if name.starts_with('?') {
2436+
return Some(name);
2437+
}
2438+
Some(match sess.target.arch {
2439+
Arch::X86 => {
2440+
// COFF 32-bit: strip calling-convention decorations.
2441+
if let Some(rest) = name.strip_prefix('@') {
2442+
// fastcall: @foo@N -> foo
2443+
rest.rsplit_once('@')
2444+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2445+
.unwrap_or(name)
2446+
} else if let Some(stripped) = name.strip_prefix('_') {
2447+
if let Some((base, suffix)) = stripped.rsplit_once('@') {
2448+
// stdcall: _foo@N -> foo
2449+
strip_numeric_suffix(base, suffix, stripped)
2450+
} else {
2451+
// cdecl: _foo -> foo
2452+
stripped
2453+
}
2454+
} else {
2455+
// vectorcall: foo@@N -> foo
2456+
name.rsplit_once("@@")
2457+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2458+
.unwrap_or(name)
2459+
}
2460+
}
2461+
Arch::X86_64 => {
2462+
// COFF 64-bit: vectorcall mangling (foo@@N -> foo) also applies on x86_64.
2463+
name.rsplit_once("@@")
2464+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2465+
.unwrap_or(name)
2466+
}
2467+
Arch::Arm64EC if kind == SymbolExportKind::Text => {
2468+
// Arm64EC: `#` prefix distinguishes ARM64EC text symbols from x64 thunks.
2469+
name.strip_prefix('#').unwrap_or(name)
2470+
}
2471+
_ => name,
2472+
})
2473+
}
2474+
// ELF: no decoration
2475+
_ => Some(name),
2476+
}
2477+
}
2478+
23972479
fn add_c_staticlib_symbols(
23982480
sess: &Session,
23992481
lib: &NativeLib,
@@ -2435,7 +2517,14 @@ fn add_c_staticlib_symbols(
24352517
}
24362518

24372519
for symbol in object.symbols() {
2438-
if symbol.scope() != object::SymbolScope::Dynamic {
2520+
// The `object` crate returns `Dynamic` for ELF/Mach-O global symbols,
2521+
// but always returns `Linkage` for COFF external symbols.
2522+
// Accept both for COFF (Windows and UEFI).
2523+
let scope = symbol.scope();
2524+
if scope != object::SymbolScope::Dynamic
2525+
&& !(sess.target.binary_format == BinaryFormat::Coff
2526+
&& scope == object::SymbolScope::Linkage)
2527+
{
24392528
continue;
24402529
}
24412530

@@ -2450,9 +2539,10 @@ fn add_c_staticlib_symbols(
24502539
_ => continue,
24512540
};
24522541

2453-
// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple.
2454-
// Need to be resolved.
2455-
out.push((name.to_string(), export_kind));
2542+
let Some(undecorated) = undecorate_c_symbol(name, sess, export_kind) else {
2543+
continue;
2544+
};
2545+
out.push((undecorated.to_string(), export_kind));
24562546
}
24572547
}
24582548

0 commit comments

Comments
 (0)