Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
314a75b
`TrivialTypeTraversalImpls!`: also impl `GenericTypeVisitable`
ada4a Sep 16, 2026
e394051
dogfood: add missing `GenericTypeVisitable` impls
ada4a Sep 30, 2026
df42c7b
elide potentially-problematic projection clauses
dianne Oct 6, 2026
3e2bec1
Fix COFF renaming of decorated (stdcall/fastcall/vectorcall) exports
cezarbbb Sep 29, 2026
a9388e6
run `tests/debuginfo` on `x86_64-mingw`
Walnut356 Oct 6, 2026
19735e0
add MISSING_GENERIC_TYPE_VISITABLE lint
ada4a Aug 1, 2026
7cbe17e
Condense AdtDef lang item checks into one match
oli-obk Oct 8, 2026
02f6b38
_Complex for mips
folkertdev Jul 26, 2026
e5ddf33
Add `bf16` to arm features
Jamesbarford Oct 8, 2026
8186e2c
Include enclosing item's context on const errors
estebank Oct 8, 2026
824c4c0
reject non-async coroutine closures as async callables
amirHdev Oct 5, 2026
13703b5
comptime fn error: suggest wrapping in const block
mejrs Oct 8, 2026
a61d626
run completions-check and tidy in parallel
the8472 Aug 16, 2026
7f191f9
reduce str.contains(&str) calls in tidy
the8472 Aug 16, 2026
1eed105
run tidy::deps in multiple threads
the8472 Aug 16, 2026
2c43f7a
Revert "compiletest: stream output of executor process when --no-capt…
jieyouxu Oct 8, 2026
9a9f204
Rollup merge of #163462 - cezarbbb:symbol-edit-undecorate-coff, r=bjorn3
JonathanBrouwer Oct 8, 2026
f0a1b1a
Rollup merge of #163855 - estebank:const-context-spans, r=oli-obk
JonathanBrouwer Oct 8, 2026
96302d1
Rollup merge of #163861 - Walnut356:windows_gnu_di_test, r=Kobzol
JonathanBrouwer Oct 8, 2026
79d2894
Rollup merge of #161201 - the8472:tidy-opts, r=Kobzol
JonathanBrouwer Oct 8, 2026
4e53737
Rollup merge of #163538 - ada4a:missing-generic-type-visitable, r=Jon…
JonathanBrouwer Oct 8, 2026
c963d95
Rollup merge of #163617 - folkertdev:complex-mips, r=beetrees
JonathanBrouwer Oct 8, 2026
5950437
Rollup merge of #163772 - mejrs:comptime_error, r=nnethercote
JonathanBrouwer Oct 8, 2026
17cd5a0
Rollup merge of #163832 - amirHdev:reject-non-async-coroutine-closure…
JonathanBrouwer Oct 8, 2026
48fd345
Rollup merge of #163958 - dianne:fix-rustaceansareawesome-take-2-part…
JonathanBrouwer Oct 8, 2026
1e86388
Rollup merge of #163974 - oli-obk:push-psmmpmqzwvmo, r=lqd
JonathanBrouwer Oct 8, 2026
5471393
Rollup merge of #163979 - Jamesbarford:feat/add-bf16-to-arm-features,…
JonathanBrouwer Oct 8, 2026
3a5e142
Rollup merge of #163989 - jieyouxu:revert-stream-output, r=lqd
JonathanBrouwer Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 6 additions & 46 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use rustc_span::{Symbol, bug};
use rustc_structures::{CrateType, NativeLibKind};
use rustc_target::spec::crt_objects::CrtObjects;
use rustc_target::spec::{
Arch, BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, Os, RelocModel,
RelroLevel, SanitizerSet, SplitDebuginfo,
};
Expand All @@ -58,7 +58,7 @@ use super::linker::{self, Linker};
use super::metadata::{MetadataPosition, create_wrapper_file};
use super::rmeta_link::RmetaLinkCache;
use super::rpath::{self, RPathConfig};
use super::{apple, rmeta_link, versioned_llvm_target};
use super::{apple, rmeta_link, symbol_export, versioned_llvm_target};
use crate::base::needs_allocator_shim_for_linking;
use crate::{
CodegenLintLevelSpecs, CompiledModule, CompiledModules, CrateInfo, NativeLib, SymbolExport,
Expand Down Expand Up @@ -2759,10 +2759,6 @@ fn add_rpath_args(
}
}

fn strip_numeric_suffix<'a>(base: &'a str, suffix: impl AsRef<str>, fallback: &'a str) -> &'a str {
if suffix.as_ref().parse::<u32>().is_ok() { base } else { fallback }
}

fn undecorate_c_symbol<'a>(
name: &'a str,
sess: &Session,
Expand All @@ -2775,47 +2771,11 @@ fn undecorate_c_symbol<'a>(
name.strip_prefix('_')
}
BinaryFormat::Coff => {
// MSVC C++ mangled names start with '?' and use a completely different
// decorating scheme that includes '@@' as structural delimiters.
// They must not be subjected to C calling-convention undecoration.
if name.starts_with('?') {
return Some(name);
// COFF undecoration is shared with `symbol_edit`'s binary-level matching.
match symbol_export::coff_machine_for_arch(&sess.target.arch) {
Some(machine) => Some(symbol_export::undecorate_coff_symbol(name, machine, kind)),
None => Some(name),
}
Some(match sess.target.arch {
Arch::X86 => {
// COFF 32-bit: strip calling-convention decorations.
if let Some(rest) = name.strip_prefix('@') {
// fastcall: @foo@N -> foo
rest.rsplit_once('@')
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
} else if let Some(stripped) = name.strip_prefix('_') {
if let Some((base, suffix)) = stripped.rsplit_once('@') {
// stdcall: _foo@N -> foo
strip_numeric_suffix(base, suffix, stripped)
} else {
// cdecl: _foo -> foo
stripped
}
} else {
// vectorcall: foo@@N -> foo
name.rsplit_once("@@")
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
}
}
Arch::X86_64 => {
// COFF 64-bit: vectorcall mangling (foo@@N -> foo) also applies on x86_64.
name.rsplit_once("@@")
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
}
Arch::Arm64EC if kind == SymbolExportKind::Text => {
// Arm64EC: `#` prefix distinguishes ARM64EC text symbols from x64 thunks.
name.strip_prefix('#').unwrap_or(name)
}
_ => name,
})
}
// ELF: no decoration
_ => Some(name),
Expand Down
67 changes: 22 additions & 45 deletions compiler/rustc_codegen_ssa/src/back/symbol_edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ use object::read::elf::{SectionHeader as _, Sym as _};
use object::read::macho::Nlist;
use object::{Endianness, elf, macho, pe};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::middle::exported_symbols::SymbolExportKind;

use super::symbol_export::undecorate_coff_symbol;

struct Patch {
offset: usize,
Expand Down Expand Up @@ -58,20 +61,8 @@ pub(super) fn apply_edits<'a>(
rename,
mem::offset_of!(macho::Nlist32<Endianness>, n_type),
),
Some(object::File::Coff(f)) => coff_edit_impl(
data,
f.coff_header(),
hide,
rename,
coff_strip_underscore(f.coff_header()),
),
Some(object::File::CoffBig(f)) => coff_edit_impl(
data,
f.coff_header(),
hide,
rename,
coff_strip_underscore(f.coff_header()),
),
Some(object::File::Coff(f)) => coff_edit_impl(data, f.coff_header(), hide, rename),
Some(object::File::CoffBig(f)) => coff_edit_impl(data, f.coff_header(), hide, rename),
_ => None,
};
match result {
Expand Down Expand Up @@ -99,28 +90,20 @@ pub(super) fn collect_internal_names(
object::File::MachO32(_) => {
macho_collect_impl::<macho::MachHeader32<Endianness>>(data, exported, out)
}
object::File::Coff(f) => coff_collect_impl(
data,
f.coff_header(),
exported,
out,
coff_strip_underscore(f.coff_header()),
),
object::File::CoffBig(f) => coff_collect_impl(
data,
f.coff_header(),
exported,
out,
coff_strip_underscore(f.coff_header()),
),
object::File::Coff(f) => coff_collect_impl(data, f.coff_header(), exported, out),
object::File::CoffBig(f) => coff_collect_impl(data, f.coff_header(), exported, out),
_ => {}
}
}

/// Whether this machine's COFF ABI decorates external symbols with a leading `_`
/// (i686 only).
fn coff_strip_underscore(header: &impl CoffHeader) -> bool {
header.machine() == pe::IMAGE_FILE_MACHINE_I386
/// The `SymbolExportKind` of a COFF symbol, so `#`-prefixed `Arm64EC` text symbols are told
/// apart from data symbols during undecoration.
fn coff_symbol_kind(sym: &impl object::read::coff::ImageSymbol) -> SymbolExportKind {
if sym.derived_type() == pe::IMAGE_SYM_DTYPE_FUNCTION {
SymbolExportKind::Text
} else {
SymbolExportKind::Data
}
}

fn elf_collect_impl<Elf: object::read::elf::FileHeader<Endian = Endianness>>(
Expand Down Expand Up @@ -485,10 +468,10 @@ fn coff_collect_impl<'data, Coff: CoffHeader>(
header: &'data Coff,
exported: &FxHashSet<String>,
out: &mut FxHashSet<String>,
strip_underscore: bool,
) {
let Ok(symbols) = header.symbols(data) else { return };
let strings = symbols.strings();
let machine = header.machine();

for (_index, sym) in symbols.iter() {
let sclass = sym.storage_class();
Expand All @@ -499,15 +482,10 @@ fn coff_collect_impl<'data, Coff: CoffHeader>(
continue;
}
let Ok(name_bytes) = sym.name(strings) else { continue };
let Ok(mut name) = str::from_utf8(name_bytes).map(String::from) else { continue };
if strip_underscore {
name = name.strip_prefix('_').unwrap_or(&name).to_string();
}
let is_exported = exported.contains(&name)
|| (header.machine() == pe::IMAGE_FILE_MACHINE_ARM64EC
&& name.strip_prefix('#').is_some_and(|name| exported.contains(name)));
if !is_exported {
out.insert(name);
let Ok(name) = str::from_utf8(name_bytes) else { continue };
let name = undecorate_coff_symbol(name, machine, coff_symbol_kind(sym));
if !exported.contains(name) {
out.insert(name.to_string());
}
}
}
Expand All @@ -517,7 +495,6 @@ fn coff_edit_impl<'data, Coff: CoffHeader>(
header: &'data Coff,
hide: bool,
rename: Option<&(FxHashSet<String>, &str)>,
strip_underscore: bool,
) -> Option<Vec<u8>> {
// COFF has no visibility concept, so hiding is unsupported; the caller
// has already warned and does not request it.
Expand Down Expand Up @@ -545,6 +522,7 @@ fn coff_edit_impl<'data, Coff: CoffHeader>(

let Ok(symbols) = header.symbols(data) else { return None };
let strings = symbols.strings();
let machine = header.machine();

let mut renames = Vec::new();
for (index, sym) in symbols.iter() {
Expand All @@ -554,8 +532,7 @@ fn coff_edit_impl<'data, Coff: CoffHeader>(
}
let Ok(name_bytes) = sym.name(strings) else { continue };
let Ok(name) = str::from_utf8(name_bytes) else { continue };
let check_name =
if strip_underscore { name.strip_prefix('_').unwrap_or(name) } else { name };
let check_name = undecorate_coff_symbol(name, machine, coff_symbol_kind(sym));
if rename.is_some_and(|(rename_set, _)| rename_set.contains(check_name)) {
renames.push(RenameEntry {
name_field_offset: symbol_bytes_offset + index.0 * sym_size,
Expand Down
63 changes: 63 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::hash_map::Entry::*;

use object::pe;
use rustc_abi::{CanonAbi, X86Call};
use rustc_ast::expand::allocator::{AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name};
use rustc_crate_store::CrateDepKind;
Expand Down Expand Up @@ -813,6 +814,68 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
maybe_emutls_symbol_name(tcx, symbol, &undecorated).unwrap_or(undecorated)
}

fn strip_numeric_suffix<'a>(base: &'a str, suffix: impl AsRef<str>, fallback: &'a str) -> &'a str {
if suffix.as_ref().parse::<u32>().is_ok() { base } else { fallback }
}

/// COFF `IMAGE_FILE_MACHINE_*` for an arch with decorated symbols, or `None`.
pub(super) fn coff_machine_for_arch(arch: &Arch) -> Option<u16> {
match *arch {
Arch::X86 => Some(pe::IMAGE_FILE_MACHINE_I386),
Arch::X86_64 => Some(pe::IMAGE_FILE_MACHINE_AMD64),
Arch::Arm64EC => Some(pe::IMAGE_FILE_MACHINE_ARM64EC),
_ => None,
}
}

/// Undecorated counterpart of [`linking_symbol_name_for_instance_in_crate`].
pub(super) fn undecorate_coff_symbol<'a>(
name: &'a str,
machine: u16,
kind: SymbolExportKind,
) -> &'a str {
// MSVC C++ mangled names start with '?' and use a completely different
// decorating scheme that includes '@@' as structural delimiters.
// They must not be subjected to C calling-convention undecoration.
if name.starts_with('?') {
return name;
}
match machine {
pe::IMAGE_FILE_MACHINE_I386 => {
if let Some(rest) = name.strip_prefix('@') {
// fastcall: @foo@N -> foo
rest.rsplit_once('@')
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
} else if let Some(stripped) = name.strip_prefix('_') {
if let Some((base, suffix)) = stripped.rsplit_once('@') {
// stdcall: _foo@N -> foo
strip_numeric_suffix(base, suffix, stripped)
} else {
// cdecl: _foo -> foo
stripped
}
} else {
// vectorcall: foo@@N -> foo
name.rsplit_once("@@")
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
}
}
pe::IMAGE_FILE_MACHINE_AMD64 => {
// vectorcall: foo@@N -> foo
name.rsplit_once("@@")
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
.unwrap_or(name)
}
pe::IMAGE_FILE_MACHINE_ARM64EC if kind == SymbolExportKind::Text => {
// `#` prefix distinguishes ARM64EC text symbols from x64 thunks.
name.strip_prefix('#').unwrap_or(name)
}
_ => name,
}
}

/// On amdhsa, `gpu-kernel` functions have an associated metadata object with a `.kd` suffix.
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
/// object.
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ fn report_eval_error<'tcx>(
where_ = if num_frames == 0 { "here" } else { "inside this call" },
),
);
for span in crate::util::context_spans(*ecx.tcx, span, cid.instance.def_id()) {
diag.span_context(span);
}
for frame in frames {
diag.subdiagnostic(frame);
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_const_eval/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ pub(crate) struct NonConstImplNote {
#[derive(Clone)]
pub(crate) struct FrameNote {
pub span: Span,
pub span_context: Vec<Span>,
pub times: i32,
pub where_: &'static str,
pub instance: String,
Expand All @@ -322,6 +323,9 @@ impl Subdiagnostic for FrameNote {
if self.has_label && !self.span.is_dummy() {
span.push_span_label(self.span, msg!("the failure occurred here"));
}
for sp in &self.span_context {
span.push_span_context(*sp);
}
let msg = msg!(
r#"{$times ->
[0] inside {$where_ ->
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,18 +230,21 @@ impl<'tcx> FrameInfo<'tcx> {
diagnostics::FrameNote {
where_: "closure",
span,
span_context: vec![],
instance: String::new(),
times: 0,
has_label: false,
}
} else {
let instance = format!("{}", self.instance);
let span_context = crate::util::context_spans(tcx, span, self.instance.def_id());
// Note: this triggers a `must_produce_diag` state, which means that if we ever get
// here we must emit a diagnostic. We should never display a `FrameInfo` unless we
// actually want to emit a warning or error to the user.
diagnostics::FrameNote {
where_: "instance",
span,
span_context,
instance,
times: 0,
has_label: false,
Expand Down
Loading
Loading