Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2233d39
Mangle personality symbol
Noratrieb Nov 2, 2025
2e2cd54
Improve diagnostics for non-well-formed associated items
ozankenangungor Sep 6, 2026
29d1ae1
Handle explicit associated item own bounds generally
ozankenangungor Oct 10, 2026
24171c0
`incomplete` -> `unstable` for delegation feature
aerooneqq Oct 12, 2026
35b8ebc
Point at assoc item for trait that needs to be implemented
estebank Oct 12, 2026
bee7ba8
Simplify associated type bound checks
ozankenangungor Oct 12, 2026
192d095
Document associated type guard
ozankenangungor Oct 12, 2026
f8d4856
Output remapped paths in rustdoc JSON with the `DOCUMENTATION` scope
Urgau Oct 13, 2026
0d0f404
Add README.md and descriptions for the remap-path-prefix JSON tests
Urgau Oct 13, 2026
60ec7da
Move `thin_lto_buffer` to a OnceLock in ModuleLlvm
Zalathar Oct 14, 2026
d3f7014
Use a callback to enforce scoped lifetimes in ModuleLlvm
Zalathar Oct 9, 2026
d005c65
Avoid `&'static mut` references to an owned `llvm::Context`
Zalathar Oct 9, 2026
86d1817
add tests for local binding resolution in move expressions
TaKO8Ki Oct 10, 2026
1346617
reject out-of-scope local bindings in move expressions
TaKO8Ki Oct 10, 2026
2e4bf49
[coff] Symbol renaming stored the original name, not the undecorated …
dpaoliello Oct 14, 2026
dd49010
Test panics and wasm32-wasip3 in CI, not wasip1
alexcrichton Sep 17, 2026
533c8d7
Add aarch64-unknown-qtee as a tier 3 target
atmartorana Oct 3, 2026
7fec32e
Ignore the remap rustdoc-json tests on windows
Urgau Oct 14, 2026
e60c62f
disallow invalid const parameter types in function signatures
bit-aloo Oct 15, 2026
a85352d
add test with invalid param argument
bit-aloo Oct 15, 2026
3f1d1cb
format abby dsl errors better
khyperia Oct 15, 2026
8c2fbbc
expand and document tool attribute shadowing test
mejrs Oct 15, 2026
8c2dd05
no weird Option<AbbyConstraint>
BoxyUwU Oct 13, 2026
6640de2
Rollup merge of #163132 - alexcrichton:wasm-unwind-tests, r=saethlin
JonathanBrouwer Oct 15, 2026
c6f3c9d
Rollup merge of #164314 - BoxyUwU:abby_allocless_true, r=khyperia
JonathanBrouwer Oct 15, 2026
af0594f
Rollup merge of #148413 - Noratrieb:mangle-rust-eh-personality, r=pet…
JonathanBrouwer Oct 15, 2026
5d37291
Rollup merge of #163688 - atmartorana:aarch64-unknown-qtee, r=petroch…
JonathanBrouwer Oct 15, 2026
7cdf723
Rollup merge of #164076 - TaKO8Ki:fix-move-expr-local-bindings-ice, r…
JonathanBrouwer Oct 15, 2026
48bd735
Rollup merge of #164327 - dpaoliello:ecinternalname, r=bjorn3
JonathanBrouwer Oct 15, 2026
d6d1347
Rollup merge of #162432 - ozankenangungor:issue-162368, r=maxdexh,Sho…
JonathanBrouwer Oct 15, 2026
ecf470f
Rollup merge of #164138 - Zalathar:llmod-refs, r=hanna-kruppe
JonathanBrouwer Oct 15, 2026
46ad60a
Rollup merge of #164210 - aerooneqq:make-delegation-complete, r=petro…
JonathanBrouwer Oct 15, 2026
3252cea
Rollup merge of #164225 - estebank:found-assoc, r=ShoyuVanilla
JonathanBrouwer Oct 15, 2026
68f7a0a
Rollup merge of #164278 - Urgau:rustdoc-json-remap-path, r=GuillaumeG…
JonathanBrouwer Oct 15, 2026
e0b2caa
Rollup merge of #164308 - khyperia:abby-dsl-format, r=BoxyUwU
JonathanBrouwer Oct 15, 2026
8efe2f8
Rollup merge of #164335 - mejrs:shadowing, r=petrochenkov
JonathanBrouwer Oct 15, 2026
494c961
Rollup merge of #164342 - bit-aloo:2026-10-15-fix-arg-pos-const-type-…
JonathanBrouwer Oct 15, 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
6 changes: 6 additions & 0 deletions bootstrap.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,12 @@
# want to enable this right now.
#rust.wasm-proc-macros = false

# Enables wasm targets to be built with `-Cpanic=unwind` by default instead of
# the current `-Cpanic=abort`. This is currently used in testing the Rust
# compiler itself and is only intended for local development/testing at this
# time.
#rust.wasm-panic-unwind-default = false

# =============================================================================
# Distribution options
#
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub(crate) struct UnwindContext {
}

impl UnwindContext {
pub(crate) fn new(module: &mut dyn Module, pic_eh_frame: bool) -> Self {
pub(crate) fn new(module: &mut dyn Module, eh_personality: &str, pic_eh_frame: bool) -> Self {
let endian = match module.isa().endianness() {
Endianness::Little => RunTimeEndian::Little,
Endianness::Big => RunTimeEndian::Big,
Expand Down Expand Up @@ -70,7 +70,7 @@ impl UnwindContext {
// FIXME use eh_personality lang item instead
let personality = module
.declare_function(
"rust_eh_personality",
eh_personality,
Linkage::Import,
&Signature {
params: vec![
Expand All @@ -89,7 +89,7 @@ impl UnwindContext {
// Use indirection here to support PIC the case where rust_eh_personality is defined in
// another DSO.
let personality_ref = module
.declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
.declare_data(&format!("DW.ref.{eh_personality}"), Linkage::Local, false, false)
.unwrap();

let mut personality_ref_data = DataDescription::new();
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ fn make_module(tcx: TyCtxt<'_>, cgu_name: &str) -> AotModule {
tcx.sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections),
);

let module = UnwindModule::new(ObjectModule::new(builder), true);
let module = UnwindModule::new(
ObjectModule::new(builder),
&rustc_symbol_mangling::eh_personality_symbol(tcx),
true,
);

let producer = crate::debuginfo::producer(tcx.sess);
let global_asm_config = GlobalAsmConfig::new(tcx.sess);
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_cranelift/src/driver/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ fn create_jit_module(
let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
crate::compiler_builtins::register_functions_for_jit(&mut jit_builder);
jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info.clone()));
let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
let mut jit_module = UnwindModule::new(
JITModule::new(jit_builder),
&rustc_symbol_mangling::eh_personality_symbol(tcx),
false,
);

let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name");

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/unwind_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub(crate) struct UnwindModule<T> {
}

impl<T: Module> UnwindModule<T> {
pub(crate) fn new(mut module: T, pic_eh_frame: bool) -> Self {
let unwind_context = UnwindContext::new(&mut module, pic_eh_frame);
pub(crate) fn new(mut module: T, eh_personality: &str, pic_eh_frame: bool) -> Self {
let unwind_context = UnwindContext::new(&mut module, eh_personality, pic_eh_frame);
UnwindModule { module, unwind_context }
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,10 +517,12 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.declare_fn(symbol_name, fn_abi)
}
_ => {
let rust_name;
let name = if wants_msvc_seh(&self.sess().target) {
"__CxxFrameHandler3"
} else {
"rust_eh_personality"
rust_name = rustc_symbol_mangling::eh_personality_symbol(tcx);
&rust_name
};
self.declare_func(name, self.type_i32(), &[], true)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ fn declare_raw_fn<'gcc>(
cx.functions.borrow_mut().insert(name.to_string(), func);

#[cfg(feature = "master")]
if name == "rust_eh_personality" {
if name.ends_with("rust_eh_personality") {
// NOTE: GCC will sometimes change the personality function set on a function from
// rust_eh_personality to __gcc_personality_v0 as an optimization.
// As such, we need to create a weak alias from __gcc_personality_v0 to
Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ impl GccCodegenBackend {
fn config(&self) -> &BackendConfig {
self.config.as_ref().expect("target info not initialized")
}

#[cfg(feature = "master")]
fn set_personality_function(&self, tcx: TyCtxt<'_>) {
let personality_symbol = rustc_symbol_mangling::eh_personality_symbol(tcx);
gccjit::set_global_personality_function_name(
&CString::new(personality_symbol).expect("symbol name shouldn't contain NUL"),
);
}
}

fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {
Expand Down Expand Up @@ -235,8 +243,6 @@ impl CodegenBackend for GccCodegenBackend {
target_info: Arc::new(IntoDynSyncSend(context.get_target_info())),
lto_supported: gccjit::is_lto_supported(),
});

gccjit::set_global_personality_function_name(c"rust_eh_personality");
}

#[cfg(not(feature = "master"))]
Expand Down Expand Up @@ -272,6 +278,8 @@ impl CodegenBackend for GccCodegenBackend {
}

fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
#[cfg(feature = "master")]
self.set_personality_function(tcx);
Box::new(codegen_crate(self.clone(), tcx))
}

Expand Down
98 changes: 74 additions & 24 deletions compiler/rustc_codegen_llvm/src/back/llvm_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

use std::any::Any;
use std::ffi::CStr;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::path::PathBuf;
use std::ptr;
use std::sync::OnceLock;

use rustc_ast::expand::allocator::AllocatorMethod;
use rustc_codegen_ssa::back::lto::ThinModule;
Expand Down Expand Up @@ -59,11 +62,10 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
methods: &[AllocatorMethod],
) -> ModuleLlvm {
let module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
let cx =
SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size());
unsafe {
allocator::codegen(tcx, cx, module_name, methods);
}
module_llvm.with_module_refs(|ModuleRefs { llcx, llmod, .. }| {
let cx = SimpleCx::new(llmod, llcx, tcx.data_layout.pointer_size());
unsafe { allocator::codegen(tcx, cx, module_name, methods) };
});
module_llvm
}
fn compile_codegen_unit(
Expand Down Expand Up @@ -141,7 +143,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
module: &mut ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) {
back::write::optimize(cgcx, prof, shared_emitter, module, config)
back::write::optimize(cgcx, prof, shared_emitter, module, config);
}
fn optimize_and_codegen_thin(
cgcx: &CodegenContext,
Expand All @@ -162,7 +164,9 @@ impl WriteBackendMethods for LlvmCodegenBackend {
back::write::codegen(cgcx, prof, shared_emitter, module, config)
}
fn serialize_module(module: Self::Module, is_thin: bool) -> Self::ModuleBuffer {
back::lto::ModuleBuffer::new(module.llmod(), is_thin)
module.with_module_refs(|ModuleRefs { llmod, .. }| {
back::lto::ModuleBuffer::new(llmod, is_thin)
})
}
}

Expand Down Expand Up @@ -421,40 +425,56 @@ impl CodegenBackend for LlvmCodegenBackend {
}

pub struct ModuleLlvm {
pub(crate) llcx: &'static mut llvm::Context,
llcx_raw: ptr::NonNull<llvm::Context>,
llmod_raw: *const llvm::Module,

// This field is `ManuallyDrop` because it is important that the `TargetMachine`
// is disposed prior to the `Context` being disposed otherwise UAFs can occur.
pub(crate) tm: ManuallyDrop<OwnedTargetMachine>,
tm: ManuallyDrop<OwnedTargetMachine>,

/// Saved ThinLTO buffer for embedding in the object file.
///
/// This is currently a `OnceLock` to avoid aliasing problems when writing to it
/// from code that also wants to pass around a shared ref to `ModuleCodegen`.
pub(crate) thin_lto_buffer: OnceLock<Vec<u8>>,
}

unsafe impl Send for ModuleLlvm {}
unsafe impl Sync for ModuleLlvm {}

/// Shared helper to call [`llvm::LLVMContextCreate`] and then configure
/// [`llvm::LLVMContextSetDiscardValueNames`].
fn create_context_and_set_fewer_names(fewer_names: bool) -> ptr::NonNull<llvm::Context> {
unsafe {
let llcx_raw = llvm::LLVMContextCreate();
llvm::LLVMContextSetDiscardValueNames(llcx_raw.as_ref(), fewer_names.to_llvm_bool());
llcx_raw
}
}

impl ModuleLlvm {
pub(crate) fn new(tcx: TyCtxt<'_>, mod_name: &str) -> Self {
unsafe {
let llcx = llvm::LLVMContextCreate();
llvm::LLVMContextSetDiscardValueNames(llcx, tcx.sess.fewer_names().to_llvm_bool());
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
let llcx_raw = create_context_and_set_fewer_names(tcx.sess.fewer_names());
let llmod_raw = context::create_module(tcx, llcx_raw.as_ref(), mod_name);
ModuleLlvm {
llmod_raw,
llcx,
llcx_raw,
tm: ManuallyDrop::new(create_target_machine(tcx, mod_name)),
thin_lto_buffer: OnceLock::new(),
}
}
}

pub(crate) fn new_metadata(tcx: TyCtxt<'_>, mod_name: &str) -> Self {
unsafe {
let llcx = llvm::LLVMContextCreate();
llvm::LLVMContextSetDiscardValueNames(llcx, tcx.sess.fewer_names().to_llvm_bool());
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
let llcx_raw = create_context_and_set_fewer_names(tcx.sess.fewer_names());
let llmod_raw = context::create_module(tcx, llcx_raw.as_ref(), mod_name);
ModuleLlvm {
llmod_raw,
llcx,
llcx_raw,
tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess)),
thin_lto_buffer: OnceLock::new(),
}
}
}
Expand All @@ -467,25 +487,55 @@ impl ModuleLlvm {
dcx: DiagCtxtHandle<'_>,
) -> Self {
unsafe {
let llcx = llvm::LLVMContextCreate();
llvm::LLVMContextSetDiscardValueNames(llcx, cgcx.fewer_names.to_llvm_bool());
let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx);
let llcx_raw = create_context_and_set_fewer_names(cgcx.fewer_names);
let llmod_raw = back::lto::parse_module(llcx_raw.as_ref(), name, buffer, dcx);
let tm = tm_factory(dcx, TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap()));

ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }
ModuleLlvm {
llmod_raw,
llcx_raw,
tm: ManuallyDrop::new(tm),
thin_lto_buffer: OnceLock::new(),
}
}
}

pub(crate) fn llmod(&self) -> &llvm::Module {
unsafe { &*self.llmod_raw }
/// Passes a [`ModuleRefs`] struct to a callback function, giving it scoped
/// access to the resources owned by this module.
///
/// Passing the references to a callback ensures that they have coherent
/// `'ll` lifetimes, and that they can't escape the callback.
pub(crate) fn with_module_refs<R>(
&self,
inner_fn: impl for<'ll> FnOnce(ModuleRefs<'ll>) -> R,
) -> R {
inner_fn(ModuleRefs {
llcx: unsafe { self.llcx_raw.as_ref() },
llmod: unsafe { &*self.llmod_raw },
tm: self.tm.raw(),
_ph: PhantomData,
})
}
}

impl Drop for ModuleLlvm {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.tm);
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
llvm::LLVMContextDispose(self.llcx_raw);
}
}
}

/// Bundle of references provided by [`ModuleLlvm::with_module_refs`].
#[derive(Clone, Copy)]
pub(crate) struct ModuleRefs<'ll> {
pub(crate) llcx: &'ll llvm::Context,
pub(crate) llmod: &'ll llvm::Module,
pub(crate) tm: &'ll llvm::TargetMachine,
/// Make sure `'ll` is invariant, even if no fields happen to require that.
///
/// FIXME(Zalathar): Consider using `PhantomInvariantLifetime` when the API
/// for that is settled.
_ph: PhantomData<fn(&'ll ()) -> &'ll ()>,
}
Loading
Loading