From 3af067dc0ee961e945cfd02e2f80f4af9f7876c3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 17 Mar 2026 21:41:44 +1100 Subject: [PATCH 01/13] Use closures more consistently in `dep_graph.rs`. This file has several methods that take a `FnOnce() -> R` closure: - `DepGraph::with_ignore` - `DepGraph::with_query_deserialization` - `DepGraph::with_anon_task` - `DepGraphData::with_anon_task_inner` It also has two methods that take a faux closure via an `A` argument and a `fn(TyCtxt<'tcx>, A) -> R` argument: - DepGraph::with_task - DepGraphData::with_task The rationale is that the faux closure exercises tight control over what state they have access to. This seems silly when (a) they are passed a `TyCtxt`, and (b) when similar nearby functions take real closures. And they are more awkward to use, e.g. requiring multiple arguments to be gathered into a tuple. This commit changes the faux closures to real closures. --- src/base.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index d1637dd663b..8c29cfe4a0a 100644 --- a/src/base.rs +++ b/src/base.rs @@ -83,8 +83,7 @@ pub fn compile_codegen_unit( let (module, _) = tcx.dep_graph.with_task( dep_node, tcx, - (cgu_name, target_info, lto_supported), - module_codegen, + || module_codegen(tcx, cgu_name, target_info, lto_supported), Some(dep_graph::hash_result), ); let time_to_codegen = start_time.elapsed(); @@ -96,7 +95,9 @@ pub fn compile_codegen_unit( fn module_codegen( tcx: TyCtxt<'_>, - (cgu_name, target_info, lto_supported): (Symbol, LockedTargetInfo, bool), + cgu_name: Symbol, + target_info: LockedTargetInfo, + lto_supported: bool, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... From 42050041ebbfc29b1df9aedb1bddf9cbc1c9202a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:37:35 +0000 Subject: [PATCH 02/13] Move some thin local LTO handling to start_executing_work By not pushing any crates to each_linked_rlib_for_lto when no cross-crate LTO is used, we can avoid special cases elsewhere. --- src/back/lto.rs | 59 ++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index aee164cf322..401d4c244d5 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -31,7 +31,6 @@ use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_log::tracing::info; -use rustc_session::config::Lto; use tempfile::{TempDir, tempdir}; use crate::back::write::{codegen, save_temp_bitcode}; @@ -45,11 +44,7 @@ struct LtoData { tmp_path: TempDir, } -fn prepare_lto( - cgcx: &CodegenContext, - each_linked_rlib_for_lto: &[PathBuf], - dcx: DiagCtxtHandle<'_>, -) -> LtoData { +fn prepare_lto(each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>) -> LtoData { let tmp_path = match tempdir() { Ok(tmp_path) => tmp_path, Err(error) => { @@ -64,32 +59,30 @@ fn prepare_lto( // We save off all the bytecode and GCC module file path for later processing // with either fat or thin LTO let mut upstream_modules = Vec::new(); - if cgcx.lto != Lto::ThinLocal { - for path in each_linked_rlib_for_lto { - let archive_data = unsafe { - Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib") - }; - let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib"); - let obj_files = archive - .members() - .filter_map(|child| { - child.ok().and_then(|c| { - std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)) - }) - }) - .filter(|&(name, _)| looks_like_rust_object_file(name)); - for (name, child) in obj_files { - info!("adding bitcode from {}", name); - let path = tmp_path.path().join(name); - match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) { - Ok(()) => { - let buffer = ModuleBuffer::new(path); - let module = SerializedModule::Local(buffer); - upstream_modules.push((module, CString::new(name).unwrap())); - } - Err(e) => { - dcx.emit_fatal(e); - } + for path in each_linked_rlib_for_lto { + let archive_data = unsafe { + Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib") + }; + let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib"); + let obj_files = archive + .members() + .filter_map(|child| { + child + .ok() + .and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))) + }) + .filter(|&(name, _)| looks_like_rust_object_file(name)); + for (name, child) in obj_files { + info!("adding bitcode from {}", name); + let path = tmp_path.path().join(name); + match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) { + Ok(()) => { + let buffer = ModuleBuffer::new(path); + let module = SerializedModule::Local(buffer); + upstream_modules.push((module, CString::new(name).unwrap())); + } + Err(e) => { + dcx.emit_fatal(e); } } } @@ -115,7 +108,7 @@ pub(crate) fn run_fat( ) -> CompiledModule { let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); + let lto_data = prepare_lto(each_linked_rlib_for_lto, dcx); /*let symbols_below_threshold = lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ fat_lto( From 2bf125f2c316ba59003fb1fd487a55a628e6aa80 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:08:37 +0000 Subject: [PATCH 03/13] Introduce ThinLtoInput --- src/lib.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bf13f0b2127..d50968bad25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,9 +81,9 @@ use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; use rustc_ast::expand::allocator::AllocatorMethod; -use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; +use rustc_codegen_ssa::back::lto::ThinModule; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, ThinLtoInput, }; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; @@ -449,8 +449,7 @@ impl WriteBackendMethods for GccCodegenBackend { // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], _each_linked_rlib_for_lto: &[PathBuf], - _modules: Vec<(String, Self::ModuleBuffer)>, - _cached_modules: Vec<(SerializedModule, WorkProduct)>, + _modules: Vec>, ) -> (Vec>, Vec) { unreachable!() } From 40746da78bae8f0851c72b52014838c781f18882 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 25 Mar 2026 08:54:32 +1100 Subject: [PATCH 04/13] Move `rustc_middle::mir::mono` to `rustc_middle::mono` Because the things in this module aren't MIR and don't use anything from `rustc_middle::mir`. Also, modules that use `mono` often don't use anything else from `rustc_middle::mir`. --- src/base.rs | 2 +- src/context.rs | 2 +- src/mono_item.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index d1637dd663b..73b0723895b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::traits::DebugInfoCodegenMethods; use rustc_hir::attrs::Linkage; use rustc_middle::dep_graph; #[cfg(feature = "master")] -use rustc_middle::mir::mono::Visibility; +use rustc_middle::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; use rustc_span::Symbol; diff --git a/src/context.rs b/src/context.rs index c34c615306a..c7a2b92ac13 100644 --- a/src/context.rs +++ b/src/context.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodege use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::interpret::Allocation; -use rustc_middle::mir::mono::CodegenUnit; +use rustc_middle::mono::CodegenUnit; use rustc_middle::span_bug; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, diff --git a/src/mono_item.rs b/src/mono_item.rs index 1429738a7e7..d5874779021 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -6,7 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::mono::Visibility; +use rustc_middle::mono::Visibility; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; From 17d844f76309b9076c0c53153b4526f8650d0270 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 2 Apr 2026 09:36:14 -0700 Subject: [PATCH 05/13] Hexagon inline asm: add reg_pair, vreg, vreg_pair, and qreg register classes Add new Hexagon inline asm register classes: - reg_pair: GPR double registers (r1:0 through r27:26) for i64/f64 types - vreg: HVX vector registers (v0-v31) for mode-dependent vector types - vreg_pair: HVX vector pair registers (v1:0 through v31:30) for vector pairs - qreg: HVX predicate registers (q0-q3), clobber-only Key implementation details: - GPR pairs use LLVM's 'd' register naming (d0-d13) for constraints - HVX vector pairs use LLVM's 'w' register naming (w0-w15) for constraints - Register overlap tracking for GPR pair<->single and HVX pair<->single conflicts - HVX vector types are mode-dependent (64B vs 128B HVX length) Note: vreg_quad (HVX vector quads) is not supported as LLVM's Hexagon backend does not support vector quad types in inline asm constraints. --- src/asm.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/asm.rs b/src/asm.rs index c5fb257107f..1443aa925f7 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -687,9 +687,15 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg_pair) => "r", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { unreachable!("clobber-only") } + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::vreg_pair) => "v", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::qreg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", @@ -779,9 +785,19 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl cx.type_vector(cx.type_i64(), 2) } InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg_pair) => cx.type_i64(), InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { unreachable!("clobber-only") } + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::vreg) => { + cx.type_vector(cx.type_i32(), 16) + } + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::vreg_pair) => { + cx.type_vector(cx.type_i32(), 32) + } + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::qreg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), From da0c8715437a255a0f9b32cd9ad58d00eb02e8cf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 8 Apr 2026 11:50:38 +0000 Subject: [PATCH 06/13] Store a PathBuf rather than SerializedModule for cached modules In cg_gcc ModuleBuffer already only contains a path anyway. And for moving LTO into -Zlink-only we will need to serialize MaybeLtoModules. By storing a path cached modules we avoid writing them to the disk a second time during serialization of MaybeLtoModules. --- src/back/lto.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index 401d4c244d5..6fd9cc96328 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -144,9 +144,12 @@ fn fat_lto( for module in modules { match module { FatLtoInput::InMemory(m) => in_memory.push(m), - FatLtoInput::Serialized { name, buffer } => { + FatLtoInput::Serialized { name, bitcode_path } => { info!("pushing serialized module {:?}", name); - serialized_modules.push((buffer, CString::new(name).unwrap())); + serialized_modules.push(( + SerializedModule::from_file(&bitcode_path), + CString::new(name).unwrap(), + )); } } } From 1bf42b40fa69099620324c099a2b849014917f9a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 8 Apr 2026 21:03:50 +0200 Subject: [PATCH 07/13] preseve SIMD element type information and provide it to LLVM for better optimization --- src/abi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/abi.rs b/src/abi.rs index 4d1274a63d1..8277231f16a 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -90,7 +90,9 @@ impl GccType for Reg { 64 => cx.type_f64(), _ => bug!("unsupported float: {:?}", self), }, - RegKind::Vector => cx.type_vector(cx.type_i8(), self.size.bytes()), + RegKind::Vector { hint_vector_elem: _ } => { + cx.type_vector(cx.type_i8(), self.size.bytes()) + } } } } From 92c02eca2eb289d1ff3b772107cdd095addb165b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 17 May 2025 14:35:25 +0000 Subject: [PATCH 08/13] Use `!null` pattern type in libcore --- example/mini_core.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 2e165cc3c12..87b059526ea 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -9,6 +9,7 @@ transparent_unions, auto_traits, freeze_impls, + pattern_types, thread_local )] #![no_core] @@ -580,9 +581,16 @@ pub struct Global; impl Allocator for Global {} #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull(pub *const T); +pub struct NonNull(pub pattern_type!(*const T is !null)); + +#[rustc_builtin_macro(pattern_type)] +#[macro_export] +macro_rules! pattern_type { + ($($arg:tt)*) => { + /* compiler built-in */ + }; +} impl CoerceUnsized> for NonNull where T: Unsize {} impl DispatchFromDyn> for NonNull where T: Unsize {} From 60ef0f0b80b3912f6b312c3e7ed1c53ecc18a8ac Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 8 Apr 2026 15:01:26 +1000 Subject: [PATCH 09/13] Refactor FnDecl and FnSig flags into packed structs --- src/intrinsic/mod.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 83ac627d27c..2a7c88afe17 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -7,8 +7,6 @@ use std::iter; #[cfg(feature = "master")] use gccjit::Type; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; -#[cfg(feature = "master")] -use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; @@ -1483,32 +1481,26 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( // `unsafe fn(*mut i8) -> ()` let try_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( iter::once(i8p), tcx.types.unit, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )), ); // `unsafe fn(*mut i8, *mut i8) -> ()` let catch_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( [i8p, i8p].iter().cloned(), tcx.types.unit, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )), ); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` - let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( + let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi( [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )); let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen); cx.rust_try_fn.set(Some(rust_try)); From d10ab82d5623bae4eef102fd0d4054089c8c2736 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Wed, 15 Apr 2026 12:17:20 +0800 Subject: [PATCH 10/13] fix all errors --- src/intrinsic/simd.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 4ca890fee19..6fd19c4f82c 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -16,7 +16,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; use rustc_hir as hir; use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::HasTyCtxt; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, Unnormalized}; use rustc_span::{Span, Symbol, sym}; use crate::builder::Builder; @@ -539,7 +539,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *in_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(ty), + ) }); require!( metadata.is_unit(), @@ -553,7 +556,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *out_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(ty), + ) }); require!( metadata.is_unit(), From 228e2549c942f3813f26a71e13569cf68766d398 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 29 Apr 2026 14:01:21 -0400 Subject: [PATCH 11/13] Update to nightly-2026-04-29 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 796a468daab..56fcfdff1c7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2026-04-05" +channel = "nightly-2026-04-29" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From d2b7a2e43a896df30c3c5ebb2725eaf60e159065 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 29 Apr 2026 14:14:55 -0400 Subject: [PATCH 12/13] Fix minicore --- example/mini_core.rs | 56 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 87b059526ea..481fe5387e1 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -15,6 +15,30 @@ #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] +#[lang = "pointee_trait"] +pub trait Pointee: PointeeSized { + #[lang = "metadata_type"] + // needed so that layout_of will return `TooGeneric` instead of `Unknown` + // when asked for the layout of `*const T`. Which is important for making + // transmutes between raw pointers (and especially pattern types of raw pointers) + // work. + type Metadata: Copy + Sync + Unpin + Freeze; +} + +#[lang = "dyn_metadata"] +pub struct DynMetadata { + _vtable_ptr: NonNull, + _phantom: PhantomData, +} + +unsafe extern "C" { + /// Opaque type for accessing vtables. + /// + /// Private implementation detail of `DynMetadata::size_of` etc. + /// There is conceptually not actually any Abstract Machine memory behind this pointer. + type VTable; +} + #[no_mangle] unsafe extern "C" fn _Unwind_Resume() { intrinsics::unreachable(); @@ -113,7 +137,7 @@ unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl Sync for [u8; 16] {} #[lang = "freeze"] -unsafe auto trait Freeze {} +pub unsafe auto trait Freeze {} unsafe impl Freeze for PhantomData {} unsafe impl Freeze for *const T {} @@ -592,6 +616,13 @@ macro_rules! pattern_type { }; } +impl CoerceUnsized for pattern_type!(*const T is !null) where + T: Unsize +{ +} + +impl, U> DispatchFromDyn for pattern_type!(T is !null) {} + impl CoerceUnsized> for NonNull where T: Unsize {} impl DispatchFromDyn> for NonNull where T: Unsize {} @@ -604,9 +635,9 @@ impl CoerceUnsized> for Unique wh impl DispatchFromDyn> for Unique where T: Unsize {} #[lang = "owned_box"] -pub struct Box(Unique, A); +pub struct Box(Unique, A); -impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} +impl, U: ?Sized> CoerceUnsized> for Box {} impl Box { pub fn new(val: T) -> Box { @@ -614,16 +645,27 @@ impl Box { let size = size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); - Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) + Box( + Unique { + pointer: NonNull(intrinsics::transmute::< + *mut u8, + pattern_type!(*const T is !null), + >(ptr)), + _marker: PhantomData, + }, + Global, + ) } } } -impl Drop for Box { +impl Drop for Box { fn drop(&mut self) { - // inner value is dropped by compiler. + // inner value is dropped by compiler unsafe { - libc::free(self.0.pointer.0 as *mut u8); + libc::free(intrinsics::transmute::( + self.0.pointer.0, + ) as *mut u8); } } } From d46f3aa39f97f8259fc533843c75505c957d3ea2 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 29 Apr 2026 14:36:41 -0400 Subject: [PATCH 13/13] Add failing UI tests --- tests/failing-ui-tests.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 1257193bf96..d81d54e311f 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -105,3 +105,10 @@ tests/ui/eii/default/call_default_panics.rs tests/ui/explicit-tail-calls/indirect.rs tests/ui/traits/inheritance/self-in-supertype.rs tests/ui/fmt/fmt_debug/shallow.rs +tests/ui/c-variadic/roundtrip.rs +tests/ui/eii/eii_impl_with_contract.rs +tests/ui/eii/static/cross_crate_decl.rs +tests/ui/eii/static/cross_crate_def.rs +tests/ui/eii/static/same_address.rs +tests/ui/eii/static/simple.rs +tests/ui/explicit-tail-calls/default-trait-method.rs