From 60ee6fbaa464d4d65313a7919c07113ef6068140 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 31 Oct 2024 11:39:45 +0100 Subject: [PATCH 001/106] Update tests. --- example/mini_core.rs | 2 +- example/mini_core_hello_world.rs | 4 ++-- example/mod_bench.rs | 2 +- example/std_example.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index cdd151613df8..685e03c07c18 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -681,7 +681,7 @@ impl Index for [T] { } } -extern { +extern "C" { type VaListImpl; } diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index dcfa34cb729d..1d51e0a1856b 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -258,13 +258,13 @@ fn main() { assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); - extern { + extern "C" { #[linkage = "weak"] static ABC: *const u8; } { - extern { + extern "C" { #[linkage = "weak"] static ABC: *const u8; } diff --git a/example/mod_bench.rs b/example/mod_bench.rs index cae911c1073d..e8a9cade7474 100644 --- a/example/mod_bench.rs +++ b/example/mod_bench.rs @@ -3,7 +3,7 @@ #![allow(internal_features)] #[link(name = "c")] -extern {} +extern "C" {} #[panic_handler] fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! { diff --git a/example/std_example.rs b/example/std_example.rs index 9e43b4635f0d..5fa1e0afb060 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -7,7 +7,7 @@ use std::arch::x86_64::*; use std::io::Write; use std::ops::Coroutine; -extern { +extern "C" { pub fn printf(format: *const i8, ...) -> i32; } From 0f89f3ffd438d145a0896c6c86de3bf46d7e14df Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 15 Dec 2024 11:03:37 +0000 Subject: [PATCH 002/106] Use a C-safe return type for `__rust_[ui]128_*` overflowing intrinsics Combined with [1], this will change the overflowing multiplication operations to return an `extern "C"`-safe type. Link: https://github.com/rust-lang/compiler-builtins/pull/735 [1] --- src/int.rs | 119 +++++++++++++++++++++---------------------- src/intrinsic/mod.rs | 6 ++- 2 files changed, 62 insertions(+), 63 deletions(-) diff --git a/src/int.rs b/src/int.rs index 7b9d1feb8d71..fe6a65bed03b 100644 --- a/src/int.rs +++ b/src/int.rs @@ -322,36 +322,26 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { }, } } else { - match new_kind { - Int(I128) | Uint(U128) => { - let func_name = match oop { - OverflowOp::Add => match new_kind { - Int(I128) => "__rust_i128_addo", - Uint(U128) => "__rust_u128_addo", - _ => unreachable!(), - }, - OverflowOp::Sub => match new_kind { - Int(I128) => "__rust_i128_subo", - Uint(U128) => "__rust_u128_subo", - _ => unreachable!(), - }, - OverflowOp::Mul => match new_kind { - Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead? - Uint(U128) => "__rust_u128_mulo", - _ => unreachable!(), - }, - }; - return self.operation_with_overflow(func_name, lhs, rhs); - } - _ => match oop { - OverflowOp::Mul => match new_kind { - Int(I32) => "__mulosi4", - Int(I64) => "__mulodi4", - _ => unreachable!(), - }, - _ => unimplemented!("overflow operation for {:?}", new_kind), + let (func_name, width) = match oop { + OverflowOp::Add => match new_kind { + Int(I128) => ("__rust_i128_addo", 128), + Uint(U128) => ("__rust_u128_addo", 128), + _ => unreachable!(), }, - } + OverflowOp::Sub => match new_kind { + Int(I128) => ("__rust_i128_subo", 128), + Uint(U128) => ("__rust_u128_subo", 128), + _ => unreachable!(), + }, + OverflowOp::Mul => match new_kind { + Int(I32) => ("__mulosi4", 32), + Int(I64) => ("__mulodi4", 64), + Int(I128) => ("__rust_i128_mulo", 128), // TODO(antoyo): use __muloti4d instead? + Uint(U128) => ("__rust_u128_mulo", 128), + _ => unreachable!(), + }, + }; + return self.operation_with_overflow(func_name, lhs, rhs, width); }; let intrinsic = self.context.get_builtin_function(name); @@ -364,80 +354,87 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { (res.dereference(self.location).to_rvalue(), overflow) } + /// Non-`__builtin_*` overflow operations with a `fn(T, T, &mut i32) -> T` signature. pub fn operation_with_overflow( &self, func_name: &str, lhs: RValue<'gcc>, rhs: RValue<'gcc>, + width: u64, ) -> (RValue<'gcc>, RValue<'gcc>) { let a_type = lhs.get_type(); let b_type = rhs.get_type(); debug_assert!(a_type.dyncast_array().is_some()); debug_assert!(b_type.dyncast_array().is_some()); + let overflow_type = self.i32_type; + let overflow_param_type = overflow_type.make_pointer(); + let res_type = a_type; + + let overflow_value = + self.current_func().new_local(self.location, overflow_type, "overflow"); + let overflow_addr = overflow_value.get_address(self.location); + let param_a = self.context.new_parameter(self.location, a_type, "a"); let param_b = self.context.new_parameter(self.location, b_type, "b"); - let result_field = self.context.new_field(self.location, a_type, "result"); - let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow"); + let param_overflow = + self.context.new_parameter(self.location, overflow_param_type, "overflow"); - let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]); + let a_elem_type = a_type.dyncast_array().expect("non-array a value"); + debug_assert!(a_elem_type.is_integral()); + let res_ty = match width { + 32 => self.tcx.types.i32, + 64 => self.tcx.types.i64, + 128 => self.tcx.types.i128, + _ => unreachable!("unexpected integer size"), + }; let layout = self .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ret_ty)) + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(res_ty)) .unwrap(); let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) }; let mut fn_abi = FnAbi { - args: vec![arg_abi.clone(), arg_abi.clone()].into_boxed_slice(), + args: vec![arg_abi.clone(), arg_abi.clone(), arg_abi.clone()].into_boxed_slice(), ret: arg_abi, c_variadic: false, - fixed_count: 2, + fixed_count: 3, conv: Conv::C, can_unwind: false, }; fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { unwind: false }).unwrap(); - let indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); + let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); + + let result = if ret_indirect { + let res_value = self.current_func().new_local(self.location, res_type, "result_value"); + let res_addr = res_value.get_address(self.location); + let res_param_type = res_type.make_pointer(); + let param_res = self.context.new_parameter(self.location, res_param_type, "result"); - let return_type = self - .context - .new_struct_type(self.location, "result_overflow", &[result_field, overflow_field]); - let result = if indirect { - let return_value = - self.current_func().new_local(self.location, return_type.as_type(), "return_value"); - let return_param_type = return_type.as_type().make_pointer(); - let return_param = - self.context.new_parameter(self.location, return_param_type, "return_value"); let func = self.context.new_function( self.location, FunctionType::Extern, self.type_void(), - &[return_param, param_a, param_b], + &[param_res, param_a, param_b, param_overflow], func_name, false, ); - self.llbb().add_eval( - self.location, - self.context.new_call(self.location, func, &[ - return_value.get_address(self.location), - lhs, - rhs, - ]), - ); - return_value.to_rvalue() + let _void = + self.context.new_call(self.location, func, &[res_addr, lhs, rhs, overflow_addr]); + res_value.to_rvalue() } else { let func = self.context.new_function( self.location, FunctionType::Extern, - return_type.as_type(), - &[param_a, param_b], + res_type, + &[param_a, param_b, param_overflow], func_name, false, ); - self.context.new_call(self.location, func, &[lhs, rhs]) + self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr]) }; - let overflow = result.access_field(self.location, overflow_field); - let int_result = result.access_field(self.location, result_field); - (int_result, overflow) + + (result, self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue()) } pub fn gcc_icmp( diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 42d189d1b7d3..48606f5f91c0 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -1001,7 +1001,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { 128 => "__rust_i128_addo", _ => unreachable!(), }; - let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); + let (int_result, overflow) = + self.operation_with_overflow(func_name, lhs, rhs, width); self.llbb().add_assignment(self.location, res, int_result); overflow }; @@ -1071,7 +1072,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { 128 => "__rust_i128_subo", _ => unreachable!(), }; - let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); + let (int_result, overflow) = + self.operation_with_overflow(func_name, lhs, rhs, width); self.llbb().add_assignment(self.location, res, int_result); overflow }; From 4600047767f36d12dff51e2b844ed67f81d7adda Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 17 Jan 2025 09:44:09 -0800 Subject: [PATCH 003/106] When LLVM's location discriminator value limit is exceeded, emit locations with dummy spans instead of dropping them entirely Revert most of #133194 (except the test and the comment fixes). Then refix not emitting locations at all when the correct location discriminator value exceeds LLVM's capacity. --- src/debuginfo.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index d3aeb7f3bdeb..4b84b1dbfd39 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>( let scope_data = &mir.source_scopes[scope]; let parent_scope = if let Some(parent) = scope_data.parent_scope { make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent); - debug_context.scopes[parent].unwrap() + debug_context.scopes[parent] } else { // The root is the function itself. let file = cx.sess().source_map().lookup_source_file(mir.span.lo()); - debug_context.scopes[scope] = Some(DebugScope { + debug_context.scopes[scope] = DebugScope { file_start_pos: file.start_pos, file_end_pos: file.end_position(), - ..debug_context.scopes[scope].unwrap() - }); + ..debug_context.scopes[scope] + }; instantiated.insert(scope); return; }; @@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>( if !vars.contains(scope) && scope_data.inlined.is_none() { // Do not create a DIScope if there are no variables defined in this // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. - debug_context.scopes[scope] = Some(parent_scope); + debug_context.scopes[scope] = parent_scope; instantiated.insert(scope); return; } @@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>( // TODO(tempdragon): dbg_scope: Add support for scope extension here. inlined_at.or(p_inlined_at); - debug_context.scopes[scope] = Some(DebugScope { + debug_context.scopes[scope] = DebugScope { dbg_scope, inlined_at, file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_position(), - }); + }; instantiated.insert(scope); } @@ -232,12 +232,12 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } // Initialize fn debug context (including scopes). - let empty_scope = Some(DebugScope { + let empty_scope = DebugScope { dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)), inlined_at: None, file_start_pos: BytePos(0), file_end_pos: BytePos(0), - }); + }; let mut fn_debug_context = FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()), inlined_function_scopes: Default::default(), From 49e047f5aa09d8179dce0d36df8a8263b144de81 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 8 Jan 2025 15:00:25 +0000 Subject: [PATCH 004/106] Treat undef bytes as equal to any other byte --- src/common.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common.rs b/src/common.rs index f43743fc2a41..bd5d6ba387cf 100644 --- a/src/common.rs +++ b/src/common.rs @@ -64,6 +64,11 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } + fn is_undef(&self, _val: RValue<'gcc>) -> bool { + // FIXME: actually check for undef + false + } + fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> { let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined"); if typ.is_struct().is_some() { From 301d2478e04264d1336572a810c33108ec0a278f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 14 Dec 2024 09:13:12 +0100 Subject: [PATCH 005/106] remove support for the #[start] attribute --- build_system/src/test.rs | 26 ----------------------- example/alloc_example.rs | 7 ++++--- example/mini_core_hello_world.rs | 2 +- example/mod_bench.rs | 36 -------------------------------- src/context.rs | 1 - tests/run/abort1.rs | 7 ++++--- tests/run/abort2.rs | 7 ++++--- tests/run/array.rs | 7 ++++--- tests/run/assign.rs | 7 ++++--- tests/run/closure.rs | 7 ++++--- tests/run/condition.rs | 7 ++++--- tests/run/empty_main.rs | 7 ++++--- tests/run/exit.rs | 7 ++++--- tests/run/exit_code.rs | 7 ++++--- tests/run/fun_ptr.rs | 7 ++++--- tests/run/mut_ref.rs | 7 ++++--- tests/run/operations.rs | 7 ++++--- tests/run/ptr_cast.rs | 7 ++++--- tests/run/return-tuple.rs | 7 ++++--- tests/run/slice.rs | 7 ++++--- tests/run/static.rs | 7 ++++--- tests/run/structs.rs | 7 ++++--- tests/run/tuple.rs | 7 ++++--- 23 files changed, 77 insertions(+), 121 deletions(-) delete mode 100644 example/mod_bench.rs diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 7cc7336612c7..0e790a4befc9 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> { run_command_with_env(&command, None, Some(env))?; maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?; - // FIXME: create a function "display_if_not_quiet" or something along the line. - println!("[AOT] mod_bench"); - let mut command = args.config_info.rustc_command_vec(); - command.extend_from_slice(&[ - &"example/mod_bench.rs", - &"--crate-type", - &"bin", - &"--target", - &args.config_info.target_triple, - ]); - run_command_with_env(&command, None, Some(env))?; - // FIXME: the compiled binary is not run. - Ok(()) } @@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { Ok(()) } -// echo "[BENCH COMPILE] mod_bench" -// -// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline" -// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort" -// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort" -// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort" -// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort" -// -// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow -// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3" -// echo "[BENCH RUN] mod_bench" -// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_* - fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> { if !args.is_using_gcc_master_branch() { println!("Not using GCC master branch. Skipping `extended_rand_tests`."); diff --git a/example/alloc_example.rs b/example/alloc_example.rs index 6ed8b9157f21..9a0b46d5b221 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,5 +1,6 @@ -#![feature(start, core_intrinsics, alloc_error_handler, lang_items)] +#![feature(core_intrinsics, alloc_error_handler, lang_items)] #![no_std] +#![no_main] #![allow(internal_features)] extern crate alloc; @@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() { core::intrinsics::unreachable(); } -#[start] -fn main(_argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int { let world: Box<&str> = Box::new("Hello World!\0"); unsafe { puts(*world as *const str as *const u8); diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 1d51e0a1856b..4cbe66c5e4c6 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,7 +1,7 @@ // Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs #![feature( - no_core, unboxed_closures, start, lang_items, never_type, linkage, + no_core, unboxed_closures, lang_items, never_type, linkage, extern_types, thread_local )] #![no_core] diff --git a/example/mod_bench.rs b/example/mod_bench.rs deleted file mode 100644 index e8a9cade7474..000000000000 --- a/example/mod_bench.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![feature(start, core_intrinsics, lang_items)] -#![no_std] -#![allow(internal_features)] - -#[link(name = "c")] -extern "C" {} - -#[panic_handler] -fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! { - core::intrinsics::abort(); -} - -#[lang="eh_personality"] -fn eh_personality(){} - -// Required for rustc_codegen_llvm -#[no_mangle] -unsafe extern "C" fn _Unwind_Resume() { - core::intrinsics::unreachable(); -} - -#[start] -fn main(_argc: isize, _argv: *const *const u8) -> isize { - for i in 2..100_000_000 { - black_box((i + 1) % i); - } - - 0 -} - -#[inline(never)] -fn black_box(i: u32) { - if i != 1 { - core::intrinsics::abort(); - } -} diff --git a/src/context.rs b/src/context.rs index c81c53359fd1..30732c74eb3e 100644 --- a/src/context.rs +++ b/src/context.rs @@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} - // instead of #[start] None } } diff --git a/tests/run/abort1.rs b/tests/run/abort1.rs index 696197d73772..385e41a68817 100644 --- a/tests/run/abort1.rs +++ b/tests/run/abort1.rs @@ -3,11 +3,12 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -49,7 +50,7 @@ fn test_fail() -> ! { unsafe { intrinsics::abort() }; } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { test_fail(); } diff --git a/tests/run/abort2.rs b/tests/run/abort2.rs index 714cd6c0f381..6c66a930e074 100644 --- a/tests/run/abort2.rs +++ b/tests/run/abort2.rs @@ -3,11 +3,12 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -50,8 +51,8 @@ fn fail() -> i32 { 0 } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { fail(); 0 } diff --git a/tests/run/array.rs b/tests/run/array.rs index c3c08c29c6db..e18a4ced6bc4 100644 --- a/tests/run/array.rs +++ b/tests/run/array.rs @@ -7,10 +7,11 @@ // 5 // 10 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] { [42, 10, 5] } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let array = [42, 7, 5]; let array2 = make_array(); unsafe { diff --git a/tests/run/assign.rs b/tests/run/assign.rs index 2a47f0c2966e..4d414c577a65 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -6,10 +6,11 @@ // 10 #![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] +#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -142,8 +143,8 @@ fn inc(num: isize) -> isize { } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { argc = inc(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); diff --git a/tests/run/closure.rs b/tests/run/closure.rs index 46c47bc54ed0..c7a236f74f9e 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -8,10 +8,11 @@ // Int argument: 2 // Both args: 11 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -22,8 +23,8 @@ mod libc { } } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let string = "Arg: %d\n\0"; let mut closure = || { unsafe { diff --git a/tests/run/condition.rs b/tests/run/condition.rs index 039ef94eaa71..b02359702ed2 100644 --- a/tests/run/condition.rs +++ b/tests/run/condition.rs @@ -5,10 +5,11 @@ // stdout: true // 1 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -19,8 +20,8 @@ mod libc { } } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { if argc == 1 { libc::printf(b"true\n\0" as *const u8 as *const i8); diff --git a/tests/run/empty_main.rs b/tests/run/empty_main.rs index e66a859ad698..042e44080c53 100644 --- a/tests/run/empty_main.rs +++ b/tests/run/empty_main.rs @@ -3,11 +3,12 @@ // Run-time: // status: 0 -#![feature(auto_traits, lang_items, no_core, start)] +#![feature(auto_traits, lang_items, no_core)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {} * Code */ -#[start] -fn main(_argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { 0 } diff --git a/tests/run/exit.rs b/tests/run/exit.rs index bf1cbeef3020..9a7c91c0adb2 100644 --- a/tests/run/exit.rs +++ b/tests/run/exit.rs @@ -3,11 +3,12 @@ // Run-time: // status: 2 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![feature(auto_traits, lang_items, no_core, intrinsics)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] mod libc { #[link(name = "c")] @@ -41,8 +42,8 @@ pub(crate) unsafe auto trait Freeze {} * Code */ -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { libc::exit(2); } diff --git a/tests/run/exit_code.rs b/tests/run/exit_code.rs index be7a233efdaa..c50d2b0d7107 100644 --- a/tests/run/exit_code.rs +++ b/tests/run/exit_code.rs @@ -3,11 +3,12 @@ // Run-time: // status: 1 -#![feature(auto_traits, lang_items, no_core, start)] +#![feature(auto_traits, lang_items, no_core)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {} * Code */ -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { 1 } diff --git a/tests/run/fun_ptr.rs b/tests/run/fun_ptr.rs index ed1bf72bb275..98b351e50449 100644 --- a/tests/run/fun_ptr.rs +++ b/tests/run/fun_ptr.rs @@ -4,10 +4,11 @@ // status: 0 // stdout: 1 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -26,8 +27,8 @@ fn call_func(func: fn(i16) -> i8, param: i16) -> i8 { func(param) } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { let result = call_func(i16_as_i8, argc as i16) as isize; libc::printf(b"%ld\n\0" as *const u8 as *const i8, result); diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index 3ae793382164..9be64f991ee0 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -8,10 +8,11 @@ // 11 #![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] +#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -148,8 +149,8 @@ fn update_num(num: &mut isize) { *num = *num + 5; } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let mut test = test(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); diff --git a/tests/run/operations.rs b/tests/run/operations.rs index 0e44fc580b8c..c92d3cc0b8fb 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -6,10 +6,11 @@ // 10 #![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)] +#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -231,8 +232,8 @@ pub fn panic_const_mul_overflow() -> ! { * Code */ -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc); libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc); diff --git a/tests/run/ptr_cast.rs b/tests/run/ptr_cast.rs index 2b8812ad51c5..0ba49e7187fc 100644 --- a/tests/run/ptr_cast.rs +++ b/tests/run/ptr_cast.rs @@ -4,10 +4,11 @@ // status: 0 // stdout: 1 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -24,8 +25,8 @@ fn make_array() -> [u8; 3] { [42, 10, 5] } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { let ptr = ONE as *mut usize; let value = ptr as usize; diff --git a/tests/run/return-tuple.rs b/tests/run/return-tuple.rs index f2a5a2e4384d..3cc1e274001e 100644 --- a/tests/run/return-tuple.rs +++ b/tests/run/return-tuple.rs @@ -6,11 +6,12 @@ // 10 // 42 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![feature(auto_traits, lang_items, no_core, intrinsics)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] #[lang = "copy"] pub unsafe trait Copy {} @@ -61,8 +62,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3 ) } -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42); unsafe { libc::printf(b"%d\n\0" as *const u8 as *const i8, c); diff --git a/tests/run/slice.rs b/tests/run/slice.rs index fba93fc15549..825fcb8a081e 100644 --- a/tests/run/slice.rs +++ b/tests/run/slice.rs @@ -4,10 +4,11 @@ // status: 0 // stdout: 5 -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] +#![no_main] extern crate mini_core; @@ -26,8 +27,8 @@ fn index_slice(s: &[u32]) -> u32 { } } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let array = [42, 7, 5]; unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array)); diff --git a/tests/run/static.rs b/tests/run/static.rs index a17ea2a48936..80c8782c4b1a 100644 --- a/tests/run/static.rs +++ b/tests/run/static.rs @@ -9,11 +9,12 @@ // 12 // 1 -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -98,8 +99,8 @@ static mut WITH_REF: WithRef = WithRef { refe: unsafe { &TEST }, }; -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT); libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field); diff --git a/tests/run/structs.rs b/tests/run/structs.rs index d6455667400c..59b8f358863f 100644 --- a/tests/run/structs.rs +++ b/tests/run/structs.rs @@ -5,11 +5,12 @@ // stdout: 1 // 2 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![feature(auto_traits, lang_items, no_core, intrinsics)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -55,8 +56,8 @@ fn one() -> isize { 1 } -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let test = Test { field: one(), }; diff --git a/tests/run/tuple.rs b/tests/run/tuple.rs index 8a7d85ae867e..ed60a56a68c4 100644 --- a/tests/run/tuple.rs +++ b/tests/run/tuple.rs @@ -4,11 +4,12 @@ // status: 0 // stdout: 3 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![feature(auto_traits, lang_items, no_core, intrinsics)] #![allow(internal_features)] #![no_std] #![no_core] +#![no_main] /* * Core @@ -42,8 +43,8 @@ mod libc { * Code */ -#[start] -fn main(mut argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { let test: (isize, isize, isize) = (3, 1, 4); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0); From 0692ca3d20787e43a3ff3674c0cc7e7487de6508 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 24 Jan 2025 16:05:26 -0500 Subject: [PATCH 006/106] Make CodegenCx and Builder generic Co-authored-by: Oli Scherer --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 7329080ce1f7..34aead1a6300 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -442,7 +442,6 @@ impl WriteBackendMethods for GccCodegenBackend { } fn autodiff( _cgcx: &CodegenContext, - _tcx: TyCtxt<'_>, _module: &ModuleCodegen, _diff_fncs: Vec, _config: &ModuleConfig, From d6d7c1581e211b9847ffc488645ec7bc342990f7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2025 23:12:17 +0100 Subject: [PATCH 007/106] Merge commit '9f33f846ddc06afd7ffd839ee4f18babac3f3204' --- .github/workflows/ci.yml | 10 +++--- .github/workflows/failures.yml | 6 ++-- .github/workflows/gcc12.yml | 2 +- .github/workflows/m68k.yml | 8 ++--- .github/workflows/release.yml | 13 +++++--- build_system/src/build.rs | 10 ++++-- build_system/src/config.rs | 57 ++++++++++++++++++++++++++-------- build_system/src/info.rs | 4 ++- build_system/src/main.rs | 4 +-- build_system/src/test.rs | 7 +++-- libgccjit.version | 2 +- messages.ftl | 3 -- 12 files changed, 85 insertions(+), 41 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73ec6b84a155..f96912e6b7a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,14 +13,14 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: libgccjit_version: - - { gcc: "gcc-13.deb" } - - { gcc: "gcc-13-without-int128.deb" } + - { gcc: "gcc-15.deb" } + - { gcc: "gcc-15-without-int128.deb" } commands: [ "--std-tests", # FIXME: re-enable asm tests when GCC can emit in the right syntax. @@ -108,13 +108,13 @@ jobs: cargo clippy --all-targets --features master -- -D warnings duplicates: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - run: python tools/check_intrinsics_duplicates.py build_system: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Test build system diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index f33d9fcc5825..d080bbfe91fe 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -56,12 +56,12 @@ jobs: - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb - name: Setup path to libgccjit if: matrix.libgccjit_version.gcc != 'libgccjit12.so' run: | - sudo dpkg --force-overwrite -i gcc-13.deb + sudo dpkg --force-overwrite -i gcc-15.deb echo 'gcc-path = "/usr/lib"' > config.toml echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 4c2ce91e86ee..bb9e020dc6a4 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -17,7 +17,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 07bb372b3606..ed1fc02bd913 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -17,7 +17,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -47,17 +47,17 @@ jobs: - name: Install packages run: | sudo apt-get update - sudo apt-get install qemu qemu-user-static + sudo apt-get install qemu-system qemu-user-static - name: Download artifact - run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb + run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-15.deb - name: Download VM artifact run: curl -LO https://github.com/cross-cg-gcc-tools/vms/releases/latest/download/debian-m68k.img - name: Setup path to libgccjit run: | - sudo dpkg -i gcc-m68k-13.deb + sudo dpkg -i gcc-m68k-15.deb echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60e0943c87da..886ce90b4713 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -37,11 +37,11 @@ jobs: run: sudo apt-get install ninja-build ripgrep - name: Download artifact - run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb - name: Setup path to libgccjit run: | - sudo dpkg --force-overwrite -i gcc-13.deb + sudo dpkg --force-overwrite -i gcc-15.deb echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env @@ -76,4 +76,9 @@ jobs: - name: Run y.sh cargo build run: | EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml - # TODO: grep the asm output for "call my_func" and fail if it is found. + call_found=$(objdump -dj .text tests/hello-world/target/release/hello_world | grep -c "call .*mylib.*my_func" ) ||: + if [ $call_found -gt 0 ]; then + echo "ERROR: call my_func found in asm" + echo "Test is done with LTO enabled, hence inlining should occur across crates" + exit 1 + fi diff --git a/build_system/src/build.rs b/build_system/src/build.rs index d0ced211a616..e98377f15a94 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -150,6 +150,8 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu "debug" }; + // We have a different environment variable than RUSTFLAGS to make sure those flags are only + // sent to rustc_codegen_gcc and not the LLVM backend. if let Ok(cg_rustflags) = std::env::var("CG_RUSTFLAGS") { rustflags.push(' '); rustflags.push_str(&cg_rustflags); @@ -184,8 +186,12 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let mut env = HashMap::new(); - env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); - env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); + let gcc_path = + args.config_info.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ); + env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone()); + env.insert("LIBRARY_PATH".to_string(), gcc_path); if args.config_info.no_default_features { env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 37b4b68950e4..4f9fcc971514 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -112,7 +112,7 @@ pub struct ConfigInfo { pub sysroot_panic_abort: bool, pub cg_backend_path: String, pub sysroot_path: String, - pub gcc_path: String, + pub gcc_path: Option, config_file: Option, // This is used in particular in rust compiler bootstrap because it doesn't run at the root // of the `cg_gcc` folder, making it complicated for us to get access to local files we need @@ -173,6 +173,14 @@ impl ConfigInfo { "--release-sysroot" => self.sysroot_release_channel = true, "--release" => self.channel = Channel::Release, "--sysroot-panic-abort" => self.sysroot_panic_abort = true, + "--gcc-path" => match args.next() { + Some(arg) if !arg.is_empty() => { + self.gcc_path = Some(arg.into()); + } + _ => { + return Err("Expected a value after `--gcc-path`, found nothing".to_string()); + } + }, "--cg_gcc-path" => match args.next() { Some(arg) if !arg.is_empty() => { self.cg_gcc_path = Some(arg.into()); @@ -260,8 +268,9 @@ impl ConfigInfo { create_symlink(&libgccjit_so, output_dir.join(&format!("{}.0", libgccjit_so_name)))?; } - self.gcc_path = output_dir.display().to_string(); - println!("Using `{}` as path for libgccjit", self.gcc_path); + let gcc_path = output_dir.display().to_string(); + println!("Using `{}` as path for libgccjit", gcc_path); + self.gcc_path = Some(gcc_path); Ok(()) } @@ -273,6 +282,15 @@ impl ConfigInfo { } pub fn setup_gcc_path(&mut self) -> Result<(), String> { + // If the user used the `--gcc-path` option, no need to look at `config.toml` content + // since we already have everything we need. + if let Some(gcc_path) = &self.gcc_path { + println!( + "`--gcc-path` was provided, ignoring config file. Using `{}` as path for libgccjit", + gcc_path + ); + return Ok(()); + } let config_file = match self.config_file.as_deref() { Some(config_file) => config_file.into(), None => self.compute_path("config.toml"), @@ -283,12 +301,15 @@ impl ConfigInfo { self.download_gccjit_if_needed()?; return Ok(()); } - self.gcc_path = match gcc_path { - Some(path) => path, - None => { - return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),)); - } + let Some(gcc_path) = gcc_path else { + return Err(format!("missing `gcc-path` value from `{}`", config_file.display())); }; + println!( + "GCC path retrieved from `{}`. Using `{}` as path for libgccjit", + config_file.display(), + gcc_path + ); + self.gcc_path = Some(gcc_path); Ok(()) } @@ -299,10 +320,17 @@ impl ConfigInfo { ) -> Result<(), String> { env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string()); - if self.gcc_path.is_empty() && !use_system_gcc { - self.setup_gcc_path()?; - } - env.insert("GCC_PATH".to_string(), self.gcc_path.clone()); + let gcc_path = if !use_system_gcc { + if self.gcc_path.is_none() { + self.setup_gcc_path()?; + } + self.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ) + } else { + String::new() + }; + env.insert("GCC_PATH".to_string(), gcc_path.clone()); if self.cargo_target_dir.is_empty() { match env.get("CARGO_TARGET_DIR").filter(|dir| !dir.is_empty()) { @@ -381,6 +409,8 @@ impl ConfigInfo { } // This environment variable is useful in case we want to change options of rustc commands. + // We have a different environment variable than RUSTFLAGS to make sure those flags are + // only sent to rustc_codegen_gcc and not the LLVM backend. if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") { rustflags.extend_from_slice(&split_args(&cg_rustflags)?); } @@ -414,7 +444,7 @@ impl ConfigInfo { "{target}:{sysroot}:{gcc_path}", target = self.cargo_target_dir, sysroot = sysroot.display(), - gcc_path = self.gcc_path, + gcc_path = gcc_path, ); env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone()); env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); @@ -459,6 +489,7 @@ impl ConfigInfo { --release-sysroot : Build sysroot in release mode --sysroot-panic-abort : Build the sysroot without unwinding support --config-file : Location of the config file to be used + --gcc-path : Location of the GCC root folder --cg_gcc-path : Location of the rustc_codegen_gcc root folder (used when ran from another directory) --no-default-features : Add `--no-default-features` flag to cargo commands diff --git a/build_system/src/info.rs b/build_system/src/info.rs index ea38791d38c9..bd891de2eb4c 100644 --- a/build_system/src/info.rs +++ b/build_system/src/info.rs @@ -14,6 +14,8 @@ pub fn run() -> Result<(), String> { } config.no_download = true; config.setup_gcc_path()?; - println!("{}", config.gcc_path); + if let Some(gcc_path) = config.gcc_path { + println!("{}", gcc_path); + } Ok(()) } diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 3a860e2b1360..393617183061 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -34,11 +34,11 @@ Options: --help : Displays this help message. Commands: - cargo : Executes a cargo command. + cargo : Executes a cargo command. rustc : Compiles the program using the GCC compiler. clean : Cleans the build directory, removing all compiled files and artifacts. prepare : Prepares the environment for building, including fetching dependencies and setting up configurations. - build : Compiles the project. + build : Compiles the project. test : Runs tests for the project. info : Displays information about the build environment and project configuration. clone-gcc : Clones the GCC compiler from a specified source. diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 0e790a4befc9..6c29c7d1825b 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1229,8 +1229,11 @@ pub fn run() -> Result<(), String> { if !args.use_system_gcc { args.config_info.setup_gcc_path()?; - env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); + let gcc_path = args.config_info.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ); + env.insert("LIBRARY_PATH".to_string(), gcc_path.clone()); + env.insert("LD_LIBRARY_PATH".to_string(), gcc_path); } build_if_no_backend(&env, &args)?; diff --git a/libgccjit.version b/libgccjit.version index ff58accec1d4..417fd5b03935 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -45648c2edd4ecd862d9f08196d3d6c6ccba79f07 +e607be166673a8de9fc07f6f02c60426e556c5f2 diff --git a/messages.ftl b/messages.ftl index 85fa17a6ba50..882fff8673a1 100644 --- a/messages.ftl +++ b/messages.ftl @@ -5,9 +5,6 @@ codegen_gcc_unknown_ctarget_feature_prefix = codegen_gcc_invalid_minimum_alignment = invalid minimum global alignment: {$err} -codegen_gcc_lto_not_supported = - LTO is not supported. You may get a linker error. - codegen_gcc_forbidden_ctarget_feature = target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason} From 24ce0a2efa314eff96af73f5b6c5d0e3392abf38 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 12 Jan 2025 20:18:45 +0000 Subject: [PATCH 008/106] Stabilize `const_black_box` This has been unstably const since [1], but a tracking issue was never created. Per discussion on Zulip [2], there should not be any blockers to making this const-stable. The function does not provide any functionality at compile time but does allow code reuse between const- and non-const functions, so stabilize it here. [1]: https://github.com/rust-lang/rust/pull/92226 [2]: https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/const_black_box --- tests/run/int.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/run/int.rs b/tests/run/int.rs index bfe73c38435a..58a26801b678 100644 --- a/tests/run/int.rs +++ b/tests/run/int.rs @@ -3,8 +3,6 @@ // Run-time: // status: 0 -#![feature(const_black_box)] - /* * Code */ From bc6b9bf526b2aafefe5d212cdde85e01b16351ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 27 Jan 2025 23:27:43 +0100 Subject: [PATCH 009/106] Add CI success job --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f96912e6b7a8..689a7dee435f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,3 +121,23 @@ jobs: run: | cd build_system cargo test + + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success: + needs: [build, duplicates, build_system] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' From 600999a4fe7af3c7eae9349f6530c5c7b12ce1cd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Jan 2025 18:30:17 +0100 Subject: [PATCH 010/106] ABI-required target features: warn when they are missing in base CPU (rather than silently enabling them) --- src/gcc_util.rs | 50 +------------------------------------------------ src/lib.rs | 5 +++-- 2 files changed, 4 insertions(+), 51 deletions(-) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 560aff43d653..4e8c8aaaf5c8 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -1,10 +1,8 @@ -use std::iter::FromIterator; - #[cfg(feature = "master")] use gccjit::Context; use rustc_codegen_ssa::codegen_attrs::check_tied_features; use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unord::UnordSet; use rustc_session::Session; use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; @@ -45,12 +43,6 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec Vec Date: Fri, 10 Jan 2025 04:36:11 +0000 Subject: [PATCH 011/106] Do not treat vtable supertraits as distinct when bound with different bound vars --- src/common.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common.rs b/src/common.rs index bd5d6ba387cf..20a3482aaa27 100644 --- a/src/common.rs +++ b/src/common.rs @@ -234,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { GlobalAlloc::VTable(ty, dyn_ty) => { let alloc = self .tcx - .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal()))) + .global_alloc(self.tcx.vtable_allocation(( + ty, + dyn_ty.principal().map(|principal| { + self.tcx.instantiate_bound_regions_with_erased(principal) + }), + ))) .unwrap_memory(); let init = const_alloc_to_gcc(self, alloc); self.static_addr_of(init, alloc.inner().align, None) From 12feb0e21fe1cc79ee31951322b3bc587e07befe Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 Jan 2025 20:26:10 +0000 Subject: [PATCH 012/106] Use ExistentialTraitRef throughout codegen --- src/context.rs | 6 +++--- src/debuginfo.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/context.rs b/src/context.rs index 30732c74eb3e..570ef938dc44 100644 --- a/src/context.rs +++ b/src/context.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{ FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::source_map::respan; use rustc_span::{DUMMY_SP, Span}; @@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> { pub function_instances: RefCell, Function<'gcc>>>, /// Cache generated vtables pub vtables: - RefCell, Option>), RValue<'gcc>>>, + RefCell, Option>), RValue<'gcc>>>, // TODO(antoyo): improve the SSA API to not require those. /// Mapping from function pointer type to indexes of on stack parameters. @@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn vtables( &self, - ) -> &RefCell, Option>), RValue<'gcc>>> { + ) -> &RefCell, Option>), RValue<'gcc>>> { &self.vtables } diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 4b84b1dbfd39..86d3de225f71 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::DenseBitSet; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, Body, SourceScope}; -use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; +use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty}; use rustc_session::config::DebugInfo; use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol}; use rustc_target::abi::Size; @@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn create_vtable_debuginfo( &self, _ty: Ty<'tcx>, - _trait_ref: Option>, + _trait_ref: Option>, _vtable: Self::Value, ) { // TODO(antoyo) From adee0849a2971663984f6d7c1612097d4cbbcbd3 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 1 Feb 2025 10:31:25 -0500 Subject: [PATCH 013/106] Add success job for all CI workflows --- .github/workflows/ci.yml | 1 - .github/workflows/failures.yml | 2 +- .github/workflows/gcc12.yml | 2 +- .github/workflows/m68k.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/stdarch.yml | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 689a7dee435f..688a9f7d7bf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,6 @@ jobs: cd build_system cargo test - # Summary job for the merge queue. # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! success: diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index d080bbfe91fe..b9f6f9d84f46 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - build: + success: runs-on: ubuntu-24.04 strategy: diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index bb9e020dc6a4..0308eec51cdf 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -16,7 +16,7 @@ env: GCC_EXEC_PREFIX: /usr/lib/gcc/ jobs: - build: + success: runs-on: ubuntu-24.04 strategy: diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index ed1fc02bd913..e031ad59f4b5 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -16,7 +16,7 @@ env: OVERWRITE_TARGET_TRIPLE: m68k-unknown-linux-gnu jobs: - build: + success: runs-on: ubuntu-24.04 strategy: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 886ce90b4713..4367cbccab11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - build: + success: runs-on: ubuntu-24.04 strategy: diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index d5ae6144496f..ea8bec02eef1 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - build: + success: runs-on: ubuntu-24.04 strategy: From ff2cd0fb6390d775c753733abefab6b81d45eb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 1 Feb 2025 19:13:41 +0100 Subject: [PATCH 014/106] Remove duplicated CI triggers There shouldn't be a need to run all CI jobs on all pushes. --- .github/workflows/ci.yml | 1 - .github/workflows/gcc12.yml | 1 - .github/workflows/m68k.yml | 1 - .github/workflows/release.yml | 1 - .github/workflows/stdarch.yml | 1 - 5 files changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 688a9f7d7bf7..bf974f65c1e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,6 @@ name: CI on: - - push - pull_request permissions: diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 0308eec51cdf..0d49336ea208 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -1,7 +1,6 @@ name: CI libgccjit 12 on: - - push - pull_request permissions: diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index e031ad59f4b5..af5f084205e5 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -3,7 +3,6 @@ name: m68k CI on: - - push - pull_request permissions: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4367cbccab11..4582cf577fe6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,6 @@ name: CI with sysroot compiled in release mode on: - - push - pull_request permissions: diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index ea8bec02eef1..a1df0207d54f 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -1,7 +1,6 @@ name: stdarch tests with sysroot compiled in release mode on: - - push - pull_request permissions: From befc31c588585db6650d228f50727070e2ccd96b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 1 Feb 2025 12:19:35 -0500 Subject: [PATCH 015/106] Move back to a success job so because the required checks only work without a matrix --- .github/workflows/failures.yml | 21 ++++++++++++++++++++- .github/workflows/gcc12.yml | 21 ++++++++++++++++++++- .github/workflows/m68k.yml | 21 ++++++++++++++++++++- .github/workflows/release.yml | 21 ++++++++++++++++++++- .github/workflows/stdarch.yml | 21 ++++++++++++++++++++- 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index b9f6f9d84f46..ab3e4002e87f 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - success: + build: runs-on: ubuntu-24.04 strategy: @@ -108,3 +108,22 @@ jobs: echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!" exit 1 fi + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_failures: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 0308eec51cdf..33d5d1a52df8 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -16,7 +16,7 @@ env: GCC_EXEC_PREFIX: /usr/lib/gcc/ jobs: - success: + build: runs-on: ubuntu-24.04 strategy: @@ -85,3 +85,22 @@ jobs: #- name: Run tests #run: | #./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_gcc12: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index e031ad59f4b5..a7090338a7f1 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -16,7 +16,7 @@ env: OVERWRITE_TARGET_TRIPLE: m68k-unknown-linux-gnu jobs: - success: + build: runs-on: ubuntu-24.04 strategy: @@ -105,3 +105,22 @@ jobs: - name: Run tests run: | ./y.sh test --release --clean --build-sysroot --sysroot-features compiler_builtins/no-f16-f128 ${{ matrix.commands }} + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_m68k: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4367cbccab11..7284b7f7398a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - success: + build: runs-on: ubuntu-24.04 strategy: @@ -82,3 +82,22 @@ jobs: echo "Test is done with LTO enabled, hence inlining should occur across crates" exit 1 fi + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_release: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index ea8bec02eef1..9438e557ecd9 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -12,7 +12,7 @@ env: RUST_BACKTRACE: 1 jobs: - success: + build: runs-on: ubuntu-24.04 strategy: @@ -102,3 +102,22 @@ jobs: # TODO: remove --skip test_mm512_stream_ps when stdarch is updated in rustc. # TODO: remove --skip test_tile_ when it's implemented. STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features --cfg stdarch_intel_sde" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_mm512_stream_ps --skip test_tile_ + + # Summary job for the merge queue. + # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB! + success_stdarch: + needs: [build] + # We need to ensure this job does *not* get skipped if its dependencies fail, + # because a skipped job is considered a success by GitHub. So we have to + # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run + # when the workflow is canceled manually. + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + # Manually check the status of all dependencies. `if: failure()` does not work. + - name: Conclusion + run: | + # Print the dependent jobs to see them in the CI log + jq -C <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful. + jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' From ad2be68b490180012d7775a2ae3e0fd8e9cabda4 Mon Sep 17 00:00:00 2001 From: Kevin Hamacher Date: Mon, 27 Jan 2025 19:05:14 +0100 Subject: [PATCH 016/106] Make globals always have 2+ chars as suffix As discussed on chat, there currently is the bug where certain suffixes are interpreted by the (m68k) assembler. Example: `move.l #global.w,-44(%fp)` `.w` is interpreted by the assembler as a size hint for `#global`. --- src/context.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/context.rs b/src/context.rs index c81c53359fd1..2a33beef63b9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -606,7 +606,10 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { let mut name = String::with_capacity(prefix.len() + 6); name.push_str(prefix); name.push('.'); - name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY)); + // Offset the index by the base so that always at least two characters + // are generated. This avoids cases where the suffix is interpreted as + // size by the assembler (for m68k: .b, .w, .l). + name.push_str(&(idx as u64 + ALPHANUMERIC_ONLY as u64).to_base(ALPHANUMERIC_ONLY)); name } } From 5d12c54b345d6bf6e7d25b904c1b7fbb0287429e Mon Sep 17 00:00:00 2001 From: Kevin Hamacher Date: Mon, 27 Jan 2025 18:49:49 +0100 Subject: [PATCH 017/106] Add M68000 entry to arch_to_gcc --- src/gcc_util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 560aff43d653..f463ee406174 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -242,6 +242,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> fn arch_to_gcc(name: &str) -> &str { match name { + "M68000" => "68000", "M68020" => "68020", _ => name, } From e0d8fb949cafac87d072e7bb873eeb115fe22706 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Mon, 3 Feb 2025 06:44:41 +0300 Subject: [PATCH 018/106] tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc` --- src/debuginfo.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 86d3de225f71..12cbde0ad0d3 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -1,9 +1,9 @@ use std::ops::Range; +use std::sync::Arc; use gccjit::{Location, RValue}; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods}; -use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::DenseBitSet; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, Body, SourceScope}; @@ -172,7 +172,7 @@ fn make_mir_scope<'gcc, 'tcx>( // `lookup_char_pos` return the right information instead. pub struct DebugLoc { /// Information about the original source file. - pub file: Lrc, + pub file: Arc, /// The (1-based) line number. pub line: u32, /// The (1-based) column number. From 4c932ff8379e70893d3cdc835c289547ba3bee26 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 25 Jan 2025 23:32:44 +0100 Subject: [PATCH 019/106] Update repositories URL for repositories moved to `rust-lang` organization --- Readme.md | 4 ++-- build_system/src/clone_gcc.rs | 2 +- doc/add-attribute.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index e92c16ece2f1..d0e4dbba6d35 100644 --- a/Readme.md +++ b/Readme.md @@ -23,7 +23,7 @@ A secondary goal is to check if using the gcc backend will provide any run-time ## Building **This requires a patched libgccjit in order to work. -You need to use my [fork of gcc](https://github.com/antoyo/gcc) which already includes these patches.** +You need to use my [fork of gcc](https://github.com/rust-lang/gcc) which already includes these patches.** ```bash $ cp config.example.toml config.toml @@ -40,7 +40,7 @@ to do a few more things. To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue): ```bash -$ git clone https://github.com/antoyo/gcc +$ git clone https://github.com/rust-lang/gcc $ sudo apt install flex libmpfr-dev libgmp-dev libmpc3 libmpc-dev $ mkdir gcc-build gcc-install $ cd gcc-build diff --git a/build_system/src/clone_gcc.rs b/build_system/src/clone_gcc.rs index e28ee873eb6b..b49dd47f3521 100644 --- a/build_system/src/clone_gcc.rs +++ b/build_system/src/clone_gcc.rs @@ -61,7 +61,7 @@ pub fn run() -> Result<(), String> { return Ok(()); }; - let result = git_clone("https://github.com/antoyo/gcc", Some(&args.out_path), false)?; + let result = git_clone("https://github.com/rust-lang/gcc", Some(&args.out_path), false)?; if result.ran_clone { let gcc_commit = args.config_info.get_gcc_commit()?; println!("Checking out GCC commit `{}`...", gcc_commit); diff --git a/doc/add-attribute.md b/doc/add-attribute.md index ae3bcc5e2ebe..267c18195255 100644 --- a/doc/add-attribute.md +++ b/doc/add-attribute.md @@ -14,4 +14,4 @@ Finally, you need to update this repository by calling the relevant API you adde To test it, build `gcc`, run `cargo update -p gccjit` and then you can test the generated output for a given Rust crate. -[gccjit.rs]: https://github.com/antoyo/gccjit.rs +[gccjit.rs]: https://github.com/rust-lang/gccjit.rs From beb24b3301e6f9b831f16ddd542930024ffe8239 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Feb 2025 15:15:28 +0100 Subject: [PATCH 020/106] intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic --- src/intrinsic/mod.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 48606f5f91c0..83d0db0fb54a 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::ceilf64 => "ceil", sym::truncf32 => "truncf", sym::truncf64 => "trunc", - sym::rintf32 => "rintf", - sym::rintf64 => "rint", - sym::nearbyintf32 => "nearbyintf", - sym::nearbyintf64 => "nearbyint", + // We match the LLVM backend and lower this to `rint`. + sym::round_ties_even_f32 => "rintf", + sym::round_ties_even_f64 => "rint", sym::roundf32 => "roundf", sym::roundf64 => "round", - sym::roundevenf32 => "roundevenf", - sym::roundevenf64 => "roundeven", sym::abort => "abort", _ => return None, }; From 819ab9b0656e3efbabdf680856d957ec746bc58a Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 2 Nov 2024 17:49:42 -0700 Subject: [PATCH 021/106] cg_gcc: Directly use rustc_abi instead of reexports --- src/abi.rs | 6 +++--- src/builder.rs | 2 +- src/consts.rs | 2 +- src/context.rs | 2 +- src/debuginfo.rs | 4 ++-- src/declare.rs | 2 +- src/int.rs | 7 +++---- src/intrinsic/mod.rs | 14 +++++++------- src/intrinsic/simd.rs | 2 +- src/type_.rs | 2 +- src/type_of.rs | 7 ++++--- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index 14fc23593f0e..d94fc5525288 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; -use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -132,10 +132,10 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if cx.sess().opts.optimize == config::OptLevel::No { return ty; } - if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NoAlias) { + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) { ty = ty.make_restrict() } - if attrs.regular.contains(rustc_target::abi::call::ArgAttribute::NonNull) { + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) { non_null_args.push(arg_index as i32 + 1); } ty diff --git a/src/builder.rs b/src/builder.rs index 89e5cf1b8c6b..bba19d062583 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -29,7 +29,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::def_id::DefId; -use rustc_target::abi::call::FnAbi; +use rustc_target::callconv::FnAbi; use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, WasmCAbi, X86Abi}; use crate::common::{SignType, TypeReflection, type_is_pointer}; diff --git a/src/consts.rs b/src/consts.rs index 1631ecfeecf3..fb0ca31c5433 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,6 +1,7 @@ #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute, Visibility}; use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type}; +use rustc_abi::{self as abi, Align, HasDataLayout, Primitive, Size, WrappingRange}; use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods, }; @@ -14,7 +15,6 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; -use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange}; use crate::base; use crate::context::CodegenCx; diff --git a/src/context.rs b/src/context.rs index 570ef938dc44..1e1f577bb3a1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell}; use gccjit::{ Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type, }; +use rustc_abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods}; @@ -18,7 +19,6 @@ use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::source_map::respan; use rustc_span::{DUMMY_SP, Span}; -use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; use rustc_target::spec::{ HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi, }; diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 86d3de225f71..3f6fdea9fb8c 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -1,6 +1,7 @@ use std::ops::Range; use gccjit::{Location, RValue}; +use rustc_abi::Size; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods}; use rustc_data_structures::sync::Lrc; @@ -10,8 +11,7 @@ use rustc_middle::mir::{self, Body, SourceScope}; use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty}; use rustc_session::config::DebugInfo; use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol}; -use rustc_target::abi::Size; -use rustc_target::abi::call::FnAbi; +use rustc_target::callconv::FnAbi; use crate::builder::Builder; use crate::context::CodegenCx; diff --git a/src/declare.rs b/src/declare.rs index 442488b7fd65..7cdbe3c0c629 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -4,7 +4,7 @@ use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type}; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods; use rustc_middle::ty::Ty; use rustc_span::Symbol; -use rustc_target::abi::call::FnAbi; +use rustc_target::callconv::FnAbi; use crate::abi::{FnAbiGcc, FnAbiGccExt}; use crate::context::CodegenCx; diff --git a/src/int.rs b/src/int.rs index fe6a65bed03b..4a1db8d662a9 100644 --- a/src/int.rs +++ b/src/int.rs @@ -3,12 +3,11 @@ //! 128-bit integers on 32-bit platforms and thus require to be handled manually. use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp}; +use rustc_abi::{Endian, ExternAbi}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::Endian; -use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}; -use rustc_target::spec; +use rustc_target::callconv::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}; use crate::builder::{Builder, ToGccComp}; use crate::common::{SignType, TypeReflection}; @@ -401,7 +400,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { conv: Conv::C, can_unwind: false, }; - fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { unwind: false }).unwrap(); + fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }).unwrap(); let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 48606f5f91c0..a1123fafe2f3 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -7,6 +7,9 @@ use std::iter; #[cfg(feature = "master")] use gccjit::FunctionType; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp}; +#[cfg(feature = "master")] +use rustc_abi::ExternAbi; +use rustc_abi::HasDataLayout; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; @@ -25,11 +28,8 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::abi::HasDataLayout; -use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use rustc_target::spec::PanicStrategy; -#[cfg(feature = "master")] -use rustc_target::spec::abi::Abi; #[cfg(feature = "master")] use crate::abi::FnAbiGccExt; @@ -1238,7 +1238,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx.types.unit, false, rustc_hir::Safety::Unsafe, - Abi::Rust, + ExternAbi::Rust, )), ); // `unsafe fn(*mut i8, *mut i8) -> ()` @@ -1249,7 +1249,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx.types.unit, false, rustc_hir::Safety::Unsafe, - Abi::Rust, + ExternAbi::Rust, )), ); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` @@ -1258,7 +1258,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx.types.i32, false, rustc_hir::Safety::Unsafe, - Abi::Rust, + ExternAbi::Rust, )); let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen); cx.rust_try_fn.set(Some(rust_try)); diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 1be452e5d05d..12a7dab155b4 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -3,6 +3,7 @@ use std::iter::FromIterator; use gccjit::{BinaryOp, RValue, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{ComparisonOp, UnaryOp}; +use rustc_abi::{Align, Size}; use rustc_codegen_ssa::base::compare_simd_types; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; #[cfg(feature = "master")] @@ -17,7 +18,6 @@ use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::abi::{Align, Size}; use crate::builder::Builder; #[cfg(not(feature = "master"))] diff --git a/src/type_.rs b/src/type_.rs index 4ea5544721de..cb08723431a9 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -4,13 +4,13 @@ use std::convert::TryInto; #[cfg(feature = "master")] use gccjit::CType; use gccjit::{RValue, Struct, Type}; +use rustc_abi::{AddressSpace, Align, Integer, Size}; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, DerivedTypeCodegenMethods, TypeMembershipCodegenMethods, }; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, ty}; -use rustc_target::abi::{AddressSpace, Align, Integer, Size}; use crate::common::TypeReflection; use crate::context::CodegenCx; diff --git a/src/type_of.rs b/src/type_of.rs index 0efdf36da485..8b8b54753e7f 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -3,7 +3,9 @@ use std::fmt::Write; use gccjit::{Struct, Type}; use rustc_abi as abi; use rustc_abi::Primitive::*; -use rustc_abi::{BackendRepr, FieldsShape, Integer, PointeeInfo, Size, Variants}; +use rustc_abi::{ + BackendRepr, FieldsShape, Integer, PointeeInfo, Reg, Size, TyAbiInterface, Variants, +}; use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, DerivedTypeCodegenMethods, LayoutTypeCodegenMethods, }; @@ -11,8 +13,7 @@ use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; -use rustc_target::abi::TyAbiInterface; -use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; +use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; use crate::context::CodegenCx; From 2214ba9f1a9a3d88098ae34912d5c646b57f59a6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 5 Feb 2025 12:16:57 -0500 Subject: [PATCH 022/106] Run the CI on push on the master branch --- .github/workflows/ci.yml | 5 ++++- .github/workflows/failures.yml | 5 ++++- .github/workflows/gcc12.yml | 5 ++++- .github/workflows/m68k.yml | 5 ++++- .github/workflows/release.yml | 5 ++++- .github/workflows/stdarch.yml | 5 ++++- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf974f65c1e1..ef024258ffc8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,10 @@ name: CI on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index ab3e4002e87f..bc42eb1468ea 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -2,7 +2,10 @@ name: Failures on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index d6b7e5a2a13a..da9a1506855c 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -1,7 +1,10 @@ name: CI libgccjit 12 on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 90fa5acc3fb0..21731f7087e2 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -3,7 +3,10 @@ name: m68k CI on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f6e3b475319..47a40286554e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,10 @@ name: CI with sysroot compiled in release mode on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 350e099d8870..4b9f48e7b183 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -1,7 +1,10 @@ name: stdarch tests with sysroot compiled in release mode on: - - pull_request + push: + branches: + - master + pull_request: permissions: contents: read From 09d907627b6f86fae8cc926a353a44bd723ccf59 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 7 Feb 2025 16:48:39 +0100 Subject: [PATCH 023/106] fix backslashes in path used for `asm_tests` --- build_system/src/test.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index efd7b2b8df3a..096b4c4a7154 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -542,20 +542,21 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); - let extra = - if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; - - let rustc_args = &format!( - r#"-Zpanic-abort-tests \ - -Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \ - --sysroot "{sysroot_dir}" -Cpanic=abort{extra}"#, + let codegen_backend_path = format!( + "{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}", pwd = std::env::current_dir() .map_err(|error| format!("`current_dir` failed: {:?}", error))? .display(), channel = args.config_info.channel.as_str(), dylib_ext = args.config_info.dylib_ext, - sysroot_dir = args.config_info.sysroot_path, - extra = extra, + ); + + let extra = + if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; + + let rustc_args = format!( + "-Zpanic-abort-tests -Zcodegen-backend={codegen_backend_path} --sysroot {} -Cpanic=abort{extra}", + args.config_info.sysroot_path ); run_command_with_env( From 21b60aad987f5e61658901675cd64a5736ee5eef Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:47:21 +0000 Subject: [PATCH 024/106] Remove Linkage::Private This is the same as Linkage::Internal except that it doesn't emit any symbol. Some backends may not support it and it isn't all that useful anyway. --- src/base.rs | 2 -- src/mono_item.rs | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/base.rs b/src/base.rs index c9701fb9885c..f2fc09800447 100644 --- a/src/base.rs +++ b/src/base.rs @@ -51,7 +51,6 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind { Linkage::WeakODR => unimplemented!(), Linkage::Appending => unimplemented!(), Linkage::Internal => GlobalKind::Internal, - Linkage::Private => GlobalKind::Internal, Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage. Linkage::Common => unimplemented!(), } @@ -68,7 +67,6 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType { Linkage::WeakODR => unimplemented!(), Linkage::Appending => unimplemented!(), Linkage::Internal => FunctionType::Internal, - Linkage::Private => FunctionType::Internal, Linkage::ExternalWeak => unimplemented!(), Linkage::Common => unimplemented!(), } diff --git a/src/mono_item.rs b/src/mono_item.rs index 239902df7f04..a2df7b2596fc 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -61,10 +61,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // compiler-rt, then we want to implicitly compile everything with hidden // visibility as we're going to link this object all over the place but // don't want the symbols to get exported. - if linkage != Linkage::Internal - && linkage != Linkage::Private - && self.tcx.is_compiler_builtins(LOCAL_CRATE) - { + if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) { #[cfg(feature = "master")] decl.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); } else { From a90648d25533cd67d978d611dcddeb6f4b6caa39 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:52:07 +0000 Subject: [PATCH 025/106] Remove Linkage::Appending It can only be used for certain LLVM internal variables like llvm.global_ctors which users are not allowed to define. --- src/base.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index f2fc09800447..962f4b161d78 100644 --- a/src/base.rs +++ b/src/base.rs @@ -49,7 +49,6 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind { Linkage::LinkOnceODR => unimplemented!(), Linkage::WeakAny => unimplemented!(), Linkage::WeakODR => unimplemented!(), - Linkage::Appending => unimplemented!(), Linkage::Internal => GlobalKind::Internal, Linkage::ExternalWeak => GlobalKind::Imported, // TODO(antoyo): should be weak linkage. Linkage::Common => unimplemented!(), @@ -65,7 +64,6 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType { Linkage::LinkOnceODR => unimplemented!(), Linkage::WeakAny => FunctionType::Exported, // FIXME(antoyo): should be similar to linkonce. Linkage::WeakODR => unimplemented!(), - Linkage::Appending => unimplemented!(), Linkage::Internal => FunctionType::Internal, Linkage::ExternalWeak => unimplemented!(), Linkage::Common => unimplemented!(), From 83f7576a770d394c79c8ef28e1687e3ad0f747d9 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Feb 2025 22:56:30 -0800 Subject: [PATCH 026/106] compiler: remove reexports from rustc_target::callconv --- src/abi.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/abi.rs b/src/abi.rs index d94fc5525288..717baebcd8cd 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -1,6 +1,7 @@ #[cfg(feature = "master")] use gccjit::FnAttribute; use gccjit::{ToLValue, ToRValue, Type}; +use rustc_abi::{Reg, RegKind}; use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; @@ -8,7 +9,7 @@ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; -use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; From 180f350fc67eed3142fdc7b2e7e6955e4922642e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Feb 2025 22:12:13 +0000 Subject: [PATCH 027/106] Rustfmt --- src/builder.rs | 21 +- src/intrinsic/llvm.rs | 22 +- src/intrinsic/simd.rs | 464 +++++++++++++++++++++--------------------- 3 files changed, 258 insertions(+), 249 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index bba19d062583..1c3d6cc899a6 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -155,14 +155,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // NOTE: not sure why, but we have the wrong type here. let int_type = compare_exchange.get_param(2).to_rvalue().get_type(); let src = self.context.new_bitcast(self.location, src, int_type); - self.context.new_call(self.location, compare_exchange, &[ - dst, - expected, - src, - weak, - order, - failure_order, - ]) + self.context.new_call( + self.location, + compare_exchange, + &[dst, expected, src, weak, order, failure_order], + ) } pub fn assign(&self, lvalue: LValue<'gcc>, value: RValue<'gcc>) { @@ -1076,9 +1073,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let align = dest.val.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); - let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[ - self.const_usize(1), - ]); + let next = self.inbounds_gep( + self.backend_type(cg_elem.layout), + current.to_rvalue(), + &[self.const_usize(1)], + ); self.llbb().add_assignment(self.location, current, next); self.br(header_bb); diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 231307def291..2d731f88d7d3 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -687,11 +687,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( let field2 = builder.context.new_field(None, args[1].get_type(), "carryResult"); let struct_type = builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]); - return_value = - builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[ - return_value, - last_arg.dereference(None).to_rvalue(), - ]); + return_value = builder.context.new_struct_constructor( + None, + struct_type.as_type(), + None, + &[return_value, last_arg.dereference(None).to_rvalue()], + ); } } "__builtin_ia32_stmxcsr" => { @@ -716,11 +717,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( let field2 = builder.context.new_field(None, return_value.get_type(), "success"); let struct_type = builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]); - return_value = - builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[ - random_number, - success_variable.to_rvalue(), - ]); + return_value = builder.context.new_struct_constructor( + None, + struct_type.as_type(), + None, + &[random_number, success_variable.to_rvalue()], + ); } "fma" => { let f16_type = builder.context.new_c_type(CType::Float16); diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 12a7dab155b4..84cd5b002fbb 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -62,11 +62,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let arg_tys = sig.inputs(); if name == sym::simd_select_bitmask { - require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument { - span, - name, - ty: arg_tys[1] - }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + ); let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let expected_int_bits = (len.max(8) - 1).next_power_of_two(); @@ -140,14 +139,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { - span, - name, - in_len, - in_ty, - ret_ty, - out_len - }); + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); require!( bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty } @@ -269,23 +271,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let lo_nibble = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &lo_nibble_elements); - let mask = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![ - bx.context - .new_rvalue_from_int( - bx.u8_type, 0x0f - ); - byte_vector_type_size - as _ - ]); + let mask = bx.context.new_rvalue_from_vector( + None, + long_byte_vector_type, + &vec![bx.context.new_rvalue_from_int(bx.u8_type, 0x0f); byte_vector_type_size as _], + ); - let four_vec = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![ - bx.context - .new_rvalue_from_int( - bx.u8_type, 4 - ); - byte_vector_type_size - as _ - ]); + let four_vec = bx.context.new_rvalue_from_vector( + None, + long_byte_vector_type, + &vec![bx.context.new_rvalue_from_int(bx.u8_type, 4); byte_vector_type_size as _], + ); // Step 2: Byte-swap the input. let swapped = simd_bswap(bx, args[0].immediate()); @@ -388,21 +384,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); - require!(out_len == n, InvalidMonomorphization::ReturnLength { - span, - name, - in_len: n, - ret_ty, - out_len - }); - require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement { - span, - name, - in_elem, - in_ty, - ret_ty, - out_ty - }); + require!( + out_len == n, + InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len } + ); + require!( + in_elem == out_ty, + InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } + ); let vector = args[2].immediate(); @@ -411,13 +400,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( #[cfg(feature = "master")] if name == sym::simd_insert { - require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType { - span, - name, - in_elem, - in_ty, - out_ty: arg_tys[2] - }); + require!( + in_elem == arg_tys[2], + InvalidMonomorphization::InsertedType { + span, + name, + in_elem, + in_ty, + out_ty: arg_tys[2] + } + ); let vector = args[0].immediate(); let index = args[1].immediate(); let value = args[2].immediate(); @@ -431,13 +423,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( #[cfg(feature = "master")] if name == sym::simd_extract { - require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType { - span, - name, - in_elem, - in_ty, - ret_ty - }); + require!( + ret_ty == in_elem, + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } + ); let vector = args[0].immediate(); return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); } @@ -445,18 +434,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( if name == sym::simd_select { let m_elem_ty = in_elem; let m_len = in_len; - require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument { - span, - name, - ty: arg_tys[1] - }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + ); let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); - require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths { - span, - name, - m_len, - v_len - }); + require!( + m_len == v_len, + InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } + ); match *m_elem_ty.kind() { ty::Int(_) => {} _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }), @@ -468,25 +454,27 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { - span, - name, - in_len, - in_ty, - ret_ty, - out_len - }); + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); 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) }); - require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { - span, - name, - ty: in_elem - }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem } + ); } _ => { return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) @@ -497,11 +485,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) }); - require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { - span, - name, - ty: out_elem - }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem } + ); } _ => { return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) @@ -524,14 +511,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { - span, - name, - in_len, - in_ty, - ret_ty, - out_len - }); + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); match *in_elem.kind() { ty::RawPtr(_, _) => {} @@ -560,14 +550,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { - span, - name, - in_len, - in_ty, - ret_ty, - out_len - }); + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); match *in_elem.kind() { ty::Uint(ty::UintTy::Usize) => {} @@ -596,14 +589,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( if name == sym::simd_cast || name == sym::simd_as { require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { - span, - name, - in_len, - in_ty, - ret_ty, - out_len - }); + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); // casting cares about nominal type, not just structural type if in_elem == out_elem { return Ok(args[0].immediate()); @@ -629,14 +625,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match (in_style, out_style) { (Style::Unsupported, Style::Unsupported) => { - require!(false, InvalidMonomorphization::UnsupportedCast { - span, - name, - in_ty, - in_elem, - ret_ty, - out_elem - }); + require!( + false, + InvalidMonomorphization::UnsupportedCast { + span, + name, + in_ty, + in_elem, + ret_ty, + out_elem + } + ); } _ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)), } @@ -914,45 +913,47 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // All types must be simd vector types require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); - require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond { - span, - name, - ty: arg_tys[1] - }); - require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird { - span, - name, - ty: arg_tys[2] - }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + ); + require_simd!( + arg_tys[2], + InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + ); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); // Of the same length: let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); - require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength { - span, - name, - in_len, - in_ty, - arg_ty: arg_tys[1], - out_len - }); - require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength { - span, - name, - in_len, - in_ty, - arg_ty: arg_tys[2], - out_len: out_len2 - }); + require!( + in_len == out_len, + InvalidMonomorphization::SecondArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[1], + out_len + } + ); + require!( + in_len == out_len2, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[2], + out_len: out_len2 + } + ); // The return type must match the first argument type - require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType { - span, - name, - in_ty, - ret_ty - }); + require!( + ret_ty == in_ty, + InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty } + ); // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { @@ -979,15 +980,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( (ptr_count(element_ty1), non_ptr(element_ty1)) } _ => { - require!(false, InvalidMonomorphization::ExpectedElementType { - span, - name, - expected_element: element_ty1, - second_arg: arg_tys[1], - in_elem, - in_ty, - mutability: ExpectedPointerMutability::Not, - }); + require!( + false, + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: element_ty1, + second_arg: arg_tys[1], + in_elem, + in_ty, + mutability: ExpectedPointerMutability::Not, + } + ); unreachable!(); } }; @@ -1000,12 +1004,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *element_ty2.kind() { ty::Int(_) => (), _ => { - require!(false, InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - }); + require!( + false, + InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + } + ); } } @@ -1029,36 +1036,40 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // All types must be simd vector types require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); - require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond { - span, - name, - ty: arg_tys[1] - }); - require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird { - span, - name, - ty: arg_tys[2] - }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + ); + require_simd!( + arg_tys[2], + InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + ); // Of the same length: let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); - require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength { - span, - name, - in_len, - in_ty, - arg_ty: arg_tys[1], - out_len: element_len1 - }); - require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength { - span, - name, - in_len, - in_ty, - arg_ty: arg_tys[2], - out_len: element_len2 - }); + require!( + in_len == element_len1, + InvalidMonomorphization::SecondArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[1], + out_len: element_len1 + } + ); + require!( + in_len == element_len2, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[2], + out_len: element_len2 + } + ); // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { @@ -1086,15 +1097,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( (ptr_count(element_ty1), non_ptr(element_ty1)) } _ => { - require!(false, InvalidMonomorphization::ExpectedElementType { - span, - name, - expected_element: element_ty1, - second_arg: arg_tys[1], - in_elem, - in_ty, - mutability: ExpectedPointerMutability::Mut, - }); + require!( + false, + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: element_ty1, + second_arg: arg_tys[1], + in_elem, + in_ty, + mutability: ExpectedPointerMutability::Mut, + } + ); unreachable!(); } }; @@ -1106,12 +1120,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *element_ty2.kind() { ty::Int(_) => (), _ => { - require!(false, InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - }); + require!( + false, + InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + } + ); } } @@ -1278,13 +1295,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( ($name:ident : $vec_op:expr, $float_reduce:ident, $ordered:expr, $op:ident, $identity:expr) => { if name == sym::$name { - require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType { - span, - name, - in_elem, - in_ty, - ret_ty - }); + require!( + ret_ty == in_elem, + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } + ); return match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => { let r = bx.vector_reduce_op(args[0].immediate(), $vec_op); @@ -1350,13 +1364,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( macro_rules! minmax_red { ($name:ident: $int_red:ident, $float_red:ident) => { if name == sym::$name { - require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType { - span, - name, - in_elem, - in_ty, - ret_ty - }); + require!( + ret_ty == in_elem, + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } + ); return match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())), ty::Float(_) => Ok(bx.$float_red(args[0].immediate())), @@ -1380,13 +1391,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( ($name:ident : $op:expr, $boolean:expr) => { if name == sym::$name { let input = if !$boolean { - require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType { - span, - name, - in_elem, - in_ty, - ret_ty - }); + require!( + ret_ty == in_elem, + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } + ); args[0].immediate() } else { match *in_elem.kind() { From cb499a29a8d26cf58e4b26ea70fd49c9486e7528 Mon Sep 17 00:00:00 2001 From: c8ef Date: Tue, 11 Feb 2025 03:17:38 +0800 Subject: [PATCH 028/106] remove some intrinsics (#625) --- src/builder.rs | 10 +--------- src/intrinsic/llvm.rs | 42 +----------------------------------------- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 89e5cf1b8c6b..8268819c5fae 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -371,16 +371,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let previous_arg_count = args.len(); let orig_args = args; let args = { - let function_address_names = self.function_address_names.borrow(); - let original_function_name = function_address_names.get(&func_ptr); func_ptr = llvm::adjust_function(self.context, &func_name, func_ptr, args); - llvm::adjust_intrinsic_arguments( - self, - gcc_func, - args.into(), - &func_name, - original_function_name, - ) + llvm::adjust_intrinsic_arguments(self, gcc_func, args.into(), &func_name) }; let args_adjusted = args.len() != previous_arg_count; let args = self.check_ptr_call("call", func_ptr, &args); diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 231307def291..afa434ce74e3 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use gccjit::{CType, Context, Function, FunctionPtrType, RValue, ToRValue, UnaryOp}; +use gccjit::{CType, Context, Function, FunctionPtrType, RValue, ToRValue}; use rustc_codegen_ssa::traits::BuilderMethods; use crate::builder::Builder; @@ -43,7 +43,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, - original_function_name: Option<&String>, ) -> Cow<'b, [RValue<'gcc>]> { // TODO: this might not be a good way to workaround the missing tile builtins. if func_name == "__builtin_trap" { @@ -541,33 +540,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 2]); args = vec![a, b, c, new_args[3]].into(); } - "__builtin_ia32_vfmaddsubpd256" - | "__builtin_ia32_vfmaddsubps" - | "__builtin_ia32_vfmaddsubps256" - | "__builtin_ia32_vfmaddsubpd" => { - if let Some(original_function_name) = original_function_name { - match &**original_function_name { - "llvm.x86.fma.vfmsubadd.pd.256" - | "llvm.x86.fma.vfmsubadd.ps" - | "llvm.x86.fma.vfmsubadd.ps.256" - | "llvm.x86.fma.vfmsubadd.pd" => { - // NOTE: since both llvm.x86.fma.vfmsubadd.ps and llvm.x86.fma.vfmaddsub.ps maps to - // __builtin_ia32_vfmaddsubps, only add minus if this comes from a - // subadd LLVM intrinsic, e.g. _mm256_fmsubadd_pd. - let mut new_args = args.to_vec(); - let arg3 = &mut new_args[2]; - *arg3 = builder.context.new_unary_op( - None, - UnaryOp::Minus, - arg3.get_type(), - *arg3, - ); - args = new_args.into(); - } - _ => (), - } - } - } "__builtin_ia32_ldmxcsr" => { // The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer, // so dereference the pointer. @@ -913,16 +885,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.ctlz.v4i64" => "__builtin_ia32_vplzcntq_256_mask", "llvm.ctlz.v2i64" => "__builtin_ia32_vplzcntq_128_mask", "llvm.ctpop.v32i16" => "__builtin_ia32_vpopcountw_v32hi", - "llvm.x86.fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd3", - "llvm.x86.fma.vfmsub.ss" => "__builtin_ia32_vfmsubss3", - "llvm.x86.fma.vfmsubadd.pd" => "__builtin_ia32_vfmaddsubpd", - "llvm.x86.fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmaddsubpd256", - "llvm.x86.fma.vfmsubadd.ps" => "__builtin_ia32_vfmaddsubps", - "llvm.x86.fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmaddsubps256", - "llvm.x86.fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd3", - "llvm.x86.fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss3", - "llvm.x86.fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd3", - "llvm.x86.fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss3", "llvm.x86.avx512.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", "llvm.x86.avx512.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", "llvm.x86.avx512.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", @@ -1000,8 +962,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.fshr.v32i16" => "__builtin_ia32_vpshrdv_v32hi", "llvm.fshr.v16i16" => "__builtin_ia32_vpshrdv_v16hi", "llvm.fshr.v8i16" => "__builtin_ia32_vpshrdv_v8hi", - "llvm.x86.fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd3", - "llvm.x86.fma.vfmadd.ss" => "__builtin_ia32_vfmaddss3", "llvm.x86.rdrand.64" => "__builtin_ia32_rdrand64_step", // The above doc points to unknown builtins for the following, so override them: From 65da92e77c60a7144145b02719272b2c99419705 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 10 Feb 2025 11:19:02 -0800 Subject: [PATCH 029/106] cg_gcc: stop caring about compiling for unknown targets --- src/int.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/int.rs b/src/int.rs index 4a1db8d662a9..f3552d9b12fc 100644 --- a/src/int.rs +++ b/src/int.rs @@ -400,7 +400,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { conv: Conv::C, can_unwind: false, }; - fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }).unwrap(); + fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }); let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); From d7f2227e63c9f496837530f338fc864532907704 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 11 Feb 2025 09:47:13 +0300 Subject: [PATCH 030/106] compiler/rustc_codegen_gcc/src/back/lto.rs: delete "unsafe impl Sync/Send" --- src/back/lto.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index e419bd180990..cb4caec8c326 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -710,10 +710,6 @@ pub struct ThinBuffer { context: Arc, } -// TODO: check if this makes sense to make ThinBuffer Send and Sync. -unsafe impl Send for ThinBuffer {} -unsafe impl Sync for ThinBuffer {} - impl ThinBuffer { pub(crate) fn new(context: &Arc) -> Self { Self { context: Arc::clone(context) } From c817210c70bed03133395890a09908ae06e44c94 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Feb 2025 15:22:13 +0100 Subject: [PATCH 031/106] handle NaN in unordered comparisons --- src/builder.rs | 45 +++++++++++++++++++++++++++++++++++++- tests/failing-ui-tests.txt | 1 - tests/run/float.rs | 32 +++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 tests/run/float.rs diff --git a/src/builder.rs b/src/builder.rs index 8268819c5fae..fc2f6862c161 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1284,7 +1284,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { - self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) + // LLVM has a concept of "unordered compares", where eg ULT returns true if either the two + // arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does + // not natively have this concept, so in some cases we must manually handle NaNs + let must_handle_nan = match op { + RealPredicate::RealPredicateFalse => unreachable!(), + RealPredicate::RealOEQ => false, + RealPredicate::RealOGT => false, + RealPredicate::RealOGE => false, + RealPredicate::RealOLT => false, + RealPredicate::RealOLE => false, + RealPredicate::RealONE => false, + RealPredicate::RealORD => unreachable!(), + RealPredicate::RealUNO => unreachable!(), + RealPredicate::RealUEQ => false, + RealPredicate::RealUGT => true, + RealPredicate::RealUGE => true, + RealPredicate::RealULT => true, + RealPredicate::RealULE => true, + RealPredicate::RealUNE => false, + RealPredicate::RealPredicateTrue => unreachable!(), + }; + + let cmp = self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs); + + if must_handle_nan { + let is_nan = self.context.new_binary_op( + self.location, + BinaryOp::LogicalOr, + self.cx.bool_type, + // compare a value to itself to check whether it is NaN + self.context.new_comparison(self.location, ComparisonOp::NotEquals, lhs, lhs), + self.context.new_comparison(self.location, ComparisonOp::NotEquals, rhs, rhs), + ); + + self.context.new_binary_op( + self.location, + BinaryOp::LogicalOr, + self.cx.bool_type, + is_nan, + cmp, + ) + } else { + cmp + } } /* Miscellaneous instructions */ diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 082958bfe1f8..579ac3749e95 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -5,7 +5,6 @@ tests/ui/asm/x86_64/multiple-clobber-abi.rs tests/ui/functions-closures/parallel-codegen-closures.rs tests/ui/linkage-attr/linkage1.rs tests/ui/lto/dylib-works.rs -tests/ui/numbers-arithmetic/saturating-float-casts.rs tests/ui/sepcomp/sepcomp-cci.rs tests/ui/sepcomp/sepcomp-extern.rs tests/ui/sepcomp/sepcomp-fns-backwards.rs diff --git a/tests/run/float.rs b/tests/run/float.rs new file mode 100644 index 000000000000..e0a57e6fed1a --- /dev/null +++ b/tests/run/float.rs @@ -0,0 +1,32 @@ +// Compiler: +// +// Run-time: +// status: 0 + +#![feature(const_black_box)] + +/* + * Code + */ + +fn main() { + use std::hint::black_box; + + macro_rules! check { + ($ty:ty, $expr:expr) => {{ + const EXPECTED: $ty = $expr; + assert_eq!($expr, EXPECTED); + }}; + } + + check!(i32, (black_box(0.0f32) as i32)); + + check!(u64, (black_box(f32::NAN) as u64)); + check!(u128, (black_box(f32::NAN) as u128)); + + check!(i64, (black_box(f64::NAN) as i64)); + check!(u64, (black_box(f64::NAN) as u64)); + + check!(i16, (black_box(f32::MIN) as i16)); + check!(i16, (black_box(f32::MAX) as i16)); +} From 4f59a687f136ac0ce29ad68ea02066e06fb9fc88 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 12 Feb 2025 19:54:51 -0500 Subject: [PATCH 032/106] Support sysv64 and ms ABIs --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- src/abi.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/context.rs | 8 +++++++- src/declare.rs | 25 ++++++++++++++----------- src/lib.rs | 4 ++-- 6 files changed, 74 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 636e75b94a3f..832603aa7925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8" +checksum = "2895ddec764de7ac76fe6c056050c4801a80109c066f177a00a9cc8dee02b29b" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d" +checksum = "ac133db68db8a6a8b2c51ef4b18d8ea16682d5814c4641272fe37bbbc223d5f3" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 63d37358561e..b50f2a626d57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -gccjit = "2.4" +gccjit = "2.5" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } # Local copy. diff --git a/src/abi.rs b/src/abi.rs index 14fc23593f0e..35e9b356741e 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; +#[cfg(feature = "master")] +use rustc_target::callconv::Conv; use crate::builder::Builder; use crate::context::CodegenCx; @@ -104,6 +106,8 @@ pub trait FnAbiGccExt<'gcc, 'tcx> { // TODO(antoyo): return a function pointer type instead? fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>; fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; + #[cfg(feature = "master")] + fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option>; } impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { @@ -226,4 +230,46 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { ); pointer_type } + + #[cfg(feature = "master")] + fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option> { + conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch) + } +} + +#[cfg(feature = "master")] +pub fn conv_to_fn_attribute<'gcc>(conv: Conv, _arch: &str) -> Option> { + // TODO: handle the calling conventions returning None. + let attribute = match conv { + Conv::C + | Conv::Rust + | Conv::CCmseNonSecureCall + | Conv::CCmseNonSecureEntry + | Conv::RiscvInterrupt { .. } => return None, + Conv::Cold => return None, + Conv::PreserveMost => return None, + Conv::PreserveAll => return None, + /*Conv::GpuKernel => { + if arch == "amdgpu" { + return None + } else if arch == "nvptx64" { + return None + } else { + panic!("Architecture {arch} does not support GpuKernel calling convention"); + } + }*/ + Conv::AvrInterrupt => return None, + Conv::AvrNonBlockingInterrupt => return None, + Conv::ArmAapcs => return None, + Conv::Msp430Intr => return None, + Conv::PtxKernel => return None, + Conv::X86Fastcall => return None, + Conv::X86Intr => return None, + Conv::X86Stdcall => return None, + Conv::X86ThisCall => return None, + Conv::X86VectorCall => return None, + Conv::X86_64SysV => FnAttribute::SysvAbi, + Conv::X86_64Win64 => FnAttribute::MsAbi, + }; + Some(attribute) } diff --git a/src/context.rs b/src/context.rs index 2a33beef63b9..38d012c8ca6d 100644 --- a/src/context.rs +++ b/src/context.rs @@ -23,6 +23,8 @@ use rustc_target::spec::{ HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi, }; +#[cfg(feature = "master")] +use crate::abi::conv_to_fn_attribute; use crate::callee::get_fn; use crate::common::SignType; @@ -509,7 +511,11 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn declare_c_main(&self, fn_type: Self::Type) -> Option { let entry_name = self.sess().target.entry_name.as_ref(); if !self.functions.borrow().contains_key(entry_name) { - Some(self.declare_entry_fn(entry_name, fn_type, ())) + #[cfg(feature = "master")] + let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch); + #[cfg(not(feature = "master"))] + let conv = None; + Some(self.declare_entry_fn(entry_name, fn_type, conv)) } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} diff --git a/src/declare.rs b/src/declare.rs index 442488b7fd65..d4a4d7f4b82f 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -58,7 +58,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { variadic: bool, ) -> Function<'gcc> { self.linkage.set(FunctionType::Extern); - declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, params, variadic) + declare_raw_fn(self, name, None, return_type, params, variadic) } pub fn declare_global( @@ -92,7 +92,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { &self, name: &str, _fn_type: Type<'gcc>, - callconv: (), /*llvm::CCallConv*/ + #[cfg(feature = "master")] callconv: Option>, + #[cfg(not(feature = "master"))] callconv: Option<()>, ) -> RValue<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::().make_pointer().make_pointer(); @@ -123,14 +124,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn_attributes, } = fn_abi.gcc_type(self); - let func = declare_raw_fn( - self, - name, - (), /*fn_abi.llvm_cconv()*/ - return_type, - &arguments_type, - is_c_variadic, - ); + #[cfg(feature = "master")] + let conv = fn_abi.gcc_cconv(self); + #[cfg(not(feature = "master"))] + let conv = None; + let func = declare_raw_fn(self, name, conv, return_type, &arguments_type, is_c_variadic); self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices); #[cfg(feature = "master")] for fn_attr in fn_attributes { @@ -162,7 +160,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { fn declare_raw_fn<'gcc>( cx: &CodegenCx<'gcc, '_>, name: &str, - _callconv: (), /*llvm::CallConv*/ + #[cfg(feature = "master")] callconv: Option>, + #[cfg(not(feature = "master"))] _callconv: Option<()>, return_type: Type<'gcc>, param_types: &[Type<'gcc>], variadic: bool, @@ -192,6 +191,10 @@ fn declare_raw_fn<'gcc>( let name = &mangle_name(name); let func = cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic); + #[cfg(feature = "master")] + if let Some(attribute) = callconv { + func.add_attribute(attribute); + } cx.functions.borrow_mut().insert(name.to_string(), func); #[cfg(feature = "master")] diff --git a/src/lib.rs b/src/lib.rs index f6ad0c79de54..68e0bc061add 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -187,10 +187,10 @@ impl CodegenBackend for GccCodegenBackend { crate::DEFAULT_LOCALE_RESOURCE } - fn init(&self, sess: &Session) { + fn init(&self, _sess: &Session) { #[cfg(feature = "master")] { - let target_cpu = target_cpu(sess); + let target_cpu = target_cpu(_sess); // Get the second TargetInfo with the correct CPU features by setting the arch. let context = Context::default(); From feb78f904e9e66e4fed9fe2e7e6363bb79d22be5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Feb 2025 20:08:29 +0000 Subject: [PATCH 033/106] Implement and use BikeshedGuaranteedNoDrop for union/unsafe field validity --- example/mini_core.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/mini_core.rs b/example/mini_core.rs index 5a4ee0a198ce..2ff1d757fd4e 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -54,6 +54,9 @@ impl LegacyReceiver for Box {} #[lang = "copy"] pub trait Copy {} +#[lang = "bikeshed_guaranteed_no_drop"] +pub trait BikeshedGuaranteedNoDrop {} + impl Copy for bool {} impl Copy for u8 {} impl Copy for u16 {} From 3ecc012f6f59419fbdfddd9bac3a4b21d2275078 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Feb 2025 22:05:29 +0100 Subject: [PATCH 034/106] fix clobbered or lateout registers overlapping with input registers --- libgccjit.version | 2 +- src/asm.rs | 72 +++++++++++++++++++++++++------------- tests/failing-ui-tests.txt | 1 - tests/run/asm.rs | 31 ++++++++++++++++ 4 files changed, 79 insertions(+), 27 deletions(-) diff --git a/libgccjit.version b/libgccjit.version index 417fd5b03935..dfdc222c00fc 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -e607be166673a8de9fc07f6f02c60426e556c5f2 +d6f5a708104a98199ac0f01a3b6b279a0f7c66d3 diff --git a/src/asm.rs b/src/asm.rs index 415f8affab90..9f4b84d22c08 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -36,7 +36,8 @@ use crate::type_of::LayoutGccExt; // // 3. Clobbers. GCC has a separate list of clobbers, and clobbers don't have indexes. // Contrary, Rust expresses clobbers through "out" operands that aren't tied to -// a variable (`_`), and such "clobbers" do have index. +// a variable (`_`), and such "clobbers" do have index. Input operands cannot also +// be clobbered. // // 4. Furthermore, GCC Extended Asm does not support explicit register constraints // (like `out("eax")`) directly, offering so-called "local register variables" @@ -161,6 +162,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // Also, we don't emit any asm operands immediately; we save them to // the one of the buffers to be emitted later. + let mut input_registers = vec![]; + + for op in rust_operands { + if let InlineAsmOperandRef::In { reg, .. } = *op { + if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) { + input_registers.push(reg_name); + } + } + } + // 1. Normal variables (and saving operands to buffers). for (rust_idx, op) in rust_operands.iter().enumerate() { match *op { @@ -183,25 +194,39 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { continue; } (Register(reg_name), None) => { - // `clobber_abi` can add lots of clobbers that are not supported by the target, - // such as AVX-512 registers, so we just ignore unsupported registers - let is_target_supported = - reg.reg_class().supported_types(asm_arch, true).iter().any( - |&(_, feature)| { - if let Some(feature) = feature { - self.tcx - .asm_target_features(instance.def_id()) - .contains(&feature) - } else { - true // Register class is unconditionally supported - } - }, - ); + if input_registers.contains(®_name) { + // the `clobber_abi` operand is converted into a series of + // `lateout("reg") _` operands. Of course, a user could also + // explicitly define such an output operand. + // + // GCC does not allow input registers to be clobbered, so if this out register + // is also used as an in register, do not add it to the clobbers list. + // it will be treated as a lateout register with `out_place: None` + if !late { + bug!("input registers can only be used as lateout regisers"); + } + ("r", dummy_output_type(self.cx, reg.reg_class())) + } else { + // `clobber_abi` can add lots of clobbers that are not supported by the target, + // such as AVX-512 registers, so we just ignore unsupported registers + let is_target_supported = + reg.reg_class().supported_types(asm_arch, true).iter().any( + |&(_, feature)| { + if let Some(feature) = feature { + self.tcx + .asm_target_features(instance.def_id()) + .contains(&feature) + } else { + true // Register class is unconditionally supported + } + }, + ); - if is_target_supported && !clobbers.contains(®_name) { - clobbers.push(reg_name); + if is_target_supported && !clobbers.contains(®_name) { + clobbers.push(reg_name); + } + continue; } - continue; } }; @@ -230,13 +255,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => { - let constraint = - if let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) { - constraint - } else { - // left for the next pass - continue; - }; + let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) else { + // left for the next pass + continue; + }; // Rustc frontend guarantees that input and output types are "compatible", // so we can just use input var's type for the output variable. diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 579ac3749e95..0babc748f98b 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -1,7 +1,6 @@ tests/ui/allocator/no_std-alloc-error-handler-custom.rs tests/ui/allocator/no_std-alloc-error-handler-default.rs tests/ui/asm/may_unwind.rs -tests/ui/asm/x86_64/multiple-clobber-abi.rs tests/ui/functions-closures/parallel-codegen-closures.rs tests/ui/linkage-attr/linkage1.rs tests/ui/lto/dylib-works.rs diff --git a/tests/run/asm.rs b/tests/run/asm.rs index 4e05d026868e..9ede19a061f3 100644 --- a/tests/run/asm.rs +++ b/tests/run/asm.rs @@ -174,6 +174,37 @@ fn asm() { mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3); } assert_eq!(array1, array2); + + // in and clobber registers cannot overlap. This tests that the lateout register without an + // output place (indicated by the `_`) is not added to the list of clobbered registers + let x = 8; + let y: i32; + unsafe { + asm!( + "mov rax, rdi", + in("rdi") x, + lateout("rdi") _, + out("rax") y, + ); + } + assert_eq!((x, y), (8, 8)); + + // sysv64 is the default calling convention on unix systems. The rdi register is + // used to pass arguments in the sysv64 calling convention, so this register will be clobbered + #[cfg(unix)] + { + let x = 16; + let y: i32; + unsafe { + asm!( + "mov rax, rdi", + in("rdi") x, + out("rax") y, + clobber_abi("sysv64"), + ); + } + assert_eq!((x, y), (16, 16)); + } } #[cfg(not(target_arch = "x86_64"))] From fd526a248c05b846507291a6281c06e10c2d05f7 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 13 Jan 2025 15:52:08 +0000 Subject: [PATCH 035/106] Make `-O` mean `-C opt-level=3` --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ce88ac390216..6455bcec6851 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -476,7 +476,7 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { Some(level) => match level { OptLevel::No => OptimizationLevel::None, OptLevel::Less => OptimizationLevel::Limited, - OptLevel::Default => OptimizationLevel::Standard, + OptLevel::More => OptimizationLevel::Standard, OptLevel::Aggressive => OptimizationLevel::Aggressive, OptLevel::Size | OptLevel::SizeMin => OptimizationLevel::Limited, }, From 5e0c773e8000c56fa1c258b57b2b64e453a3f57a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 5 Feb 2025 03:43:54 -0800 Subject: [PATCH 036/106] Set both `nuw` and `nsw` in slice size calculation There's an old note in the code to do this, and now that LLVM-C has an API for it, we might as well. --- src/builder.rs | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 1c3d6cc899a6..b8e37b604801 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -665,6 +665,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { a + b } + // TODO(antoyo): should we also override the `unchecked_` versions? fn sub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.gcc_sub(a, b) } @@ -832,31 +833,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { set_rvalue_location(self, self.gcc_not(a)) } - fn unchecked_sadd(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - set_rvalue_location(self, self.gcc_add(a, b)) - } - - fn unchecked_uadd(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - set_rvalue_location(self, self.gcc_add(a, b)) - } - - fn unchecked_ssub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - set_rvalue_location(self, self.gcc_sub(a, b)) - } - - fn unchecked_usub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - // TODO(antoyo): should generate poison value? - set_rvalue_location(self, self.gcc_sub(a, b)) - } - - fn unchecked_smul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - set_rvalue_location(self, self.gcc_mul(a, b)) - } - - fn unchecked_umul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - set_rvalue_location(self, self.gcc_mul(a, b)) - } - fn fadd_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. set_rvalue_location(self, lhs + rhs) From 53aa977e4bd4f5d79303061c1a6b6dbeb8cbf51c Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 13 Feb 2025 19:44:42 +0100 Subject: [PATCH 037/106] refactor and support reg_byte registers --- src/asm.rs | 213 +++++++++++++++++++++++++---------------------- tests/run/asm.rs | 22 +++++ 2 files changed, 135 insertions(+), 100 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 9f4b84d22c08..dbdf37ee6c9e 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -611,114 +611,127 @@ fn estimate_template_length( } /// Converts a register class to a GCC constraint code. -fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { - let constraint = match reg { - // For vector registers LLVM wants the register name to match the type size. +fn reg_to_gcc(reg_or_reg_class: InlineAsmRegOrRegClass) -> ConstraintOrRegister { + match reg_or_reg_class { InlineAsmRegOrRegClass::Reg(reg) => { - match reg { - InlineAsmReg::X86(_) => { - // TODO(antoyo): add support for vector register. - // - // // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 - return ConstraintOrRegister::Register(match reg.name() { - // Some of registers' names does not map 1-1 from rust to gcc - "st(0)" => "st", + ConstraintOrRegister::Register(explicit_reg_to_gcc(reg)) + } + InlineAsmRegOrRegClass::RegClass(reg_class) => { + ConstraintOrRegister::Constraint(reg_class_to_gcc(reg_class)) + } + } +} - name => name, - }); +fn explicit_reg_to_gcc(reg: InlineAsmReg) -> &'static str { + // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 + match reg { + InlineAsmReg::X86(reg) => { + // TODO(antoyo): add support for vector register. + match reg.reg_class() { + X86InlineAsmRegClass::reg_byte => { + // GCC does not support the `b` suffix, so we just strip it + // see https://github.com/rust-lang/rustc_codegen_gcc/issues/485 + reg.name().trim_end_matches('b') } + _ => match reg.name() { + // Some of registers' names does not map 1-1 from rust to gcc + "st(0)" => "st", - _ => unimplemented!(), + name => name, + }, } } - // They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html - InlineAsmRegOrRegClass::RegClass(reg) => match reg { - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x", - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", - InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", - InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", - // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for - // "define_constraint". - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h", - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r", - InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r", - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q", - InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q", - InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) - | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", - InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", - InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk", - InlineAsmRegClass::X86( - X86InlineAsmRegClass::kreg0 - | X86InlineAsmRegClass::x87_reg - | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::tmm_reg, - ) => unreachable!("clobber-only"), - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("GCC backend does not support SPIR-V") - } - InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v", - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { - unreachable!("clobber-only") - } - InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), - InlineAsmRegClass::Err => unreachable!(), - }, - }; + _ => unimplemented!(), + } +} - ConstraintOrRegister::Constraint(constraint) +/// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html +fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { + match reg_class { + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x", + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) + | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" + InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", + // https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for + // "define_constraint". + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h", + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r", + InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l", + + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) + | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r", + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q", + InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q", + InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) + | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", + InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", + InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk", + InlineAsmRegClass::X86( + X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::x87_reg + | X86InlineAsmRegClass::mmx_reg + | X86InlineAsmRegClass::tmm_reg, + ) => unreachable!("clobber-only"), + InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { + bug!("GCC backend does not support SPIR-V") + } + InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => { + unreachable!("clobber-only") + } + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"), + InlineAsmRegClass::Err => unreachable!(), + } } /// Type to use for outputs that are discarded. It doesn't really matter what diff --git a/tests/run/asm.rs b/tests/run/asm.rs index 9ede19a061f3..2dbf43be664d 100644 --- a/tests/run/asm.rs +++ b/tests/run/asm.rs @@ -205,6 +205,28 @@ fn asm() { } assert_eq!((x, y), (16, 16)); } + + // the `b` suffix for registers in the `reg_byte` register class is not supported in GCC + // and needs to be stripped in order to use these registers. + unsafe { + core::arch::asm!( + "", + out("al") _, + out("bl") _, + out("cl") _, + out("dl") _, + out("sil") _, + out("dil") _, + out("r8b") _, + out("r9b") _, + out("r10b") _, + out("r11b") _, + out("r12b") _, + out("r13b") _, + out("r14b") _, + out("r15b") _, + ); + } } #[cfg(not(target_arch = "x86_64"))] From 51911a745de6fab88f7eb75b2b8bea9787c5a153 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 14 Feb 2025 20:25:43 -0800 Subject: [PATCH 038/106] Emit `trunc nuw` for unchecked shifts and `to_immediate_scalar` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - For shifts this shrinks the IR by no longer needing an `assume` while still providing the UB information - Having this on the `i8`→`i1` truncations will hopefully help with some places that have to load `i8`s or pass those in LLVM structs without range information --- src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index b8e37b604801..76846692459d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1694,7 +1694,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { if scalar.is_bool() { - return self.trunc(val, self.cx().type_i1()); + return self.unchecked_utrunc(val, self.cx().type_i1()); } val } From 9ebb68ddda0247df044241daaf4856144c9c0998 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 15 Feb 2025 16:07:18 -0800 Subject: [PATCH 039/106] Rework `OperandRef::extract_field` to stop calling `to_immediate_scalar` on things which are already immediates That means it stops trying to truncate things that are already `i1`s. --- src/builder.rs | 12 ++++++++---- src/intrinsic/mod.rs | 11 ++++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 76846692459d..c8b7616e6450 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -989,10 +989,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.val) } else if place.layout.is_gcc_immediate() { let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align); - if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { - scalar_load_metadata(self, load, scalar); - } - OperandValue::Immediate(self.to_immediate(load, place.layout)) + OperandValue::Immediate( + if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { + scalar_load_metadata(self, load, scalar); + self.to_immediate_scalar(load, *scalar) + } else { + load + }, + ) } else if let abi::BackendRepr::ScalarPair(ref a, ref b) = place.layout.backend_repr { let b_offset = a.size(self).align_to(b.align(self).abi); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index a1123fafe2f3..5322b731d8bb 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -9,7 +9,7 @@ use gccjit::FunctionType; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; -use rustc_abi::HasDataLayout; +use rustc_abi::{BackendRepr, HasDataLayout}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; @@ -181,14 +181,19 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); + let layout = self.layout_of(tp_ty); let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) } else { - self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr) + self.volatile_load(layout.gcc_type(self), ptr) }; // TODO(antoyo): set alignment. - self.to_immediate(load, self.layout_of(tp_ty)) + if let BackendRepr::Scalar(scalar) = layout.backend_repr { + self.to_immediate_scalar(load, scalar) + } else { + load + } } sym::volatile_store => { let dst = args[0].deref(self.cx()); From be635722bd4264f0fd0de4cccb9ca4f9f74fafd9 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Sat, 25 Jan 2025 20:15:24 -0600 Subject: [PATCH 040/106] Remove `BackendRepr::Uninhabited`, replaced with an `uninhabited: bool` field in `LayoutData`. Also update comments that refered to BackendRepr::Uninhabited. --- src/intrinsic/mod.rs | 2 +- src/type_of.rs | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 5322b731d8bb..433868e238a4 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -315,7 +315,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/src/type_of.rs b/src/type_of.rs index 8b8b54753e7f..bac4fc51300a 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( false, ); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} + BackendRepr::Memory { .. } => {} } let name = match *layout.ty.kind() { @@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } From 3fe0b3d4d04dd86cbe22770217f3b42a8856d382 Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Sun, 23 Feb 2025 11:29:35 +0800 Subject: [PATCH 041/106] not lint break with label and unsafe block --- compiler/rustc_parse/src/parser/expr.rs | 14 ++++++++------ tests/ui/lint/break-with-label-and-unsafe-block.rs | 11 +++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 tests/ui/lint/break-with-label-and-unsafe-block.rs diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0e6c2177da5..21e01ff535a8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1859,13 +1859,15 @@ impl<'a> Parser<'a> { let mut expr = self.parse_expr_opt()?; if let Some(expr) = &mut expr { if label.is_some() - && matches!( - expr.kind, + && match &expr.kind { ExprKind::While(_, _, None) - | ExprKind::ForLoop { label: None, .. } - | ExprKind::Loop(_, None, _) - | ExprKind::Block(_, None) - ) + | ExprKind::ForLoop { label: None, .. } + | ExprKind::Loop(_, None, _) => true, + ExprKind::Block(block, None) => { + matches!(block.rules, BlockCheckMode::Default) + } + _ => false, + } { self.psess.buffer_lint( BREAK_WITH_LABEL_AND_LOOP, diff --git a/tests/ui/lint/break-with-label-and-unsafe-block.rs b/tests/ui/lint/break-with-label-and-unsafe-block.rs new file mode 100644 index 000000000000..a76a57614755 --- /dev/null +++ b/tests/ui/lint/break-with-label-and-unsafe-block.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![deny(break_with_label_and_loop)] + +unsafe fn foo() -> i32 { 42 } + +fn main () { + 'label: loop { + break 'label unsafe { foo() } + }; +} From aa038c2d95bb041a170cb1bbea8ef0fd2fd14ca4 Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 6 Feb 2025 21:59:36 +0800 Subject: [PATCH 042/106] Add `new_regular` and `new_allocator` to `ModuleCodegen` --- src/back/lto.rs | 9 ++++----- src/base.rs | 11 +++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index cb4caec8c326..e5221c7da319 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -632,17 +632,16 @@ pub unsafe fn optimize_thin_module( Arc::new(SyncContext::new(context)) } }; - let module = ModuleCodegen { - module_llvm: GccContext { + let module = ModuleCodegen::new_regular( + thin_module.name().to_string(), + GccContext { context, should_combine_object_files, // TODO(antoyo): use the correct relocation model here. relocation_model: RelocModel::Pic, temp_dir: None, }, - name: thin_module.name().to_string(), - kind: ModuleKind::Regular, - }; + ); /*{ let target = &*module.module_llvm.tm; let llmod = module.module_llvm.llmod(); diff --git a/src/base.rs b/src/base.rs index 962f4b161d78..9b495174a3fa 100644 --- a/src/base.rs +++ b/src/base.rs @@ -4,10 +4,10 @@ use std::sync::Arc; use std::time::Instant; use gccjit::{CType, Context, FunctionType, GlobalKind}; +use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoCodegenMethods; -use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; use rustc_middle::dep_graph; use rustc_middle::mir::mono::Linkage; #[cfg(feature = "master")] @@ -237,16 +237,15 @@ pub fn compile_codegen_unit( } } - ModuleCodegen { - name: cgu_name.to_string(), - module_llvm: GccContext { + ModuleCodegen::new_regular( + cgu_name.to_string(), + GccContext { context: Arc::new(SyncContext::new(context)), relocation_model: tcx.sess.relocation_model(), should_combine_object_files: false, temp_dir: None, }, - kind: ModuleKind::Regular, - } + ) } (module, cost) From 9b8701d27ebc49b2ade98d910b411d6f0a57a0ac Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 6 Feb 2025 22:00:19 +0800 Subject: [PATCH 043/106] Save pre-link bitcode to `ModuleCodegen` --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6455bcec6851..9d91aab72ab3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -393,7 +393,7 @@ impl WriteBackendMethods for GccCodegenBackend { unsafe fn optimize( _cgcx: &CodegenContext, _dcx: DiagCtxtHandle<'_>, - module: &ModuleCodegen, + module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level)); From 15f0dca5317ac3cac7be8f509761fa6248fad0c0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Feb 2025 17:34:50 +0100 Subject: [PATCH 044/106] remove support for rustc_intrinsic_must_be_overridden from the compiler --- example/mini_core.rs | 65 +++++++++-------------------------------- tests/run/abort1.rs | 5 +--- tests/run/abort2.rs | 5 +--- tests/run/assign.rs | 5 +--- tests/run/mut_ref.rs | 5 +--- tests/run/operations.rs | 5 +--- tests/run/static.rs | 5 +--- 7 files changed, 19 insertions(+), 76 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 2ff1d757fd4e..3dad35bc4ce4 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -591,70 +591,31 @@ pub union MaybeUninit { pub mod intrinsics { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn size_of() -> usize { - loop {} - } + pub fn size_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn size_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn size_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn min_align_of() -> usize { - loop {} - } + pub fn min_align_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn min_align_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn min_align_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize) { - loop {} - } + pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn transmute(_e: T) -> U { - loop {} - } + pub unsafe fn transmute(_e: T) -> U; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn ctlz_nonzero(_x: T) -> u32 { - loop {} - } + pub unsafe fn ctlz_nonzero(_x: T) -> u32; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn needs_drop() -> bool { - loop {} - } + pub fn needs_drop() -> bool; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bitreverse(_x: T) -> T { - loop {} - } + pub fn bitreverse(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bswap(_x: T) -> T { - loop {} - } + pub fn bswap(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize) { - loop {} - } + pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn unreachable() -> ! { - loop {} - } + pub unsafe fn unreachable() -> !; } pub mod libc { diff --git a/tests/run/abort1.rs b/tests/run/abort1.rs index 385e41a68817..fe46d9ae4184 100644 --- a/tests/run/abort1.rs +++ b/tests/run/abort1.rs @@ -36,10 +36,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } /* diff --git a/tests/run/abort2.rs b/tests/run/abort2.rs index 6c66a930e074..4123f4f4beeb 100644 --- a/tests/run/abort2.rs +++ b/tests/run/abort2.rs @@ -36,10 +36,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } /* diff --git a/tests/run/assign.rs b/tests/run/assign.rs index 4d414c577a65..286155852d50 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -59,10 +59,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index 9be64f991ee0..b0215860406e 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -61,10 +61,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/tests/run/operations.rs b/tests/run/operations.rs index c92d3cc0b8fb..8ba7a4c5ed8c 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -67,10 +67,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/tests/run/static.rs b/tests/run/static.rs index 80c8782c4b1a..c3c8121b1e19 100644 --- a/tests/run/static.rs +++ b/tests/run/static.rs @@ -49,10 +49,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } mod libc { From e92466e22a6f98f7be019a6709b8f120cc5981a3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 08:07:11 +0000 Subject: [PATCH 045/106] Remove an unnecessary lifetime --- src/common.rs | 4 ++-- src/consts.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common.rs b/src/common.rs index 20a3482aaa27..0ee13498ccad 100644 --- a/src/common.rs +++ b/src/common.rs @@ -59,7 +59,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool { typ.get_pointee().is_some() } -impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { +impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> { if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } @@ -263,7 +263,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } } - fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value { + fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { const_alloc_to_gcc(self, alloc) } diff --git a/src/consts.rs b/src/consts.rs index fb0ca31c5433..c514b7a428bc 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -302,9 +302,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn const_alloc_to_gcc<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - alloc: ConstAllocation<'tcx>, +pub fn const_alloc_to_gcc<'gcc>( + cx: &CodegenCx<'gcc, '_>, + alloc: ConstAllocation<'_>, ) -> RValue<'gcc> { let alloc = alloc.inner(); let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1); From 71c189a2effd3ea4e8d4653b938c9d90cdb78845 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 11:31:43 +0000 Subject: [PATCH 046/106] Generalize BaseTypeCodegenMethods --- src/type_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/type_.rs b/src/type_.rs index cb08723431a9..4e0a250b5509 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -123,7 +123,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -impl<'gcc, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { +impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> { fn type_i8(&self) -> Type<'gcc> { self.i8_type } From 334eb82117cddee4813e860e54d1aa9db91da461 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 12:23:45 +0000 Subject: [PATCH 047/106] Remove an unused lifetime param --- src/abi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi.rs b/src/abi.rs index 717baebcd8cd..9fe6baa3d257 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -16,7 +16,7 @@ use crate::context::CodegenCx; use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; -impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { +impl AbiBuilderMethods for Builder<'_, '_, '_> { fn get_param(&mut self, index: usize) -> Self::Value { let func = self.current_func(); let param = func.get_param(index as i32); From 78481458d172e0a85dc56a08f315d7fc6c1757cc Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 25 Feb 2025 09:20:10 +0100 Subject: [PATCH 048/106] remove `simd_fpow` and `simd_fpowi` --- src/intrinsic/simd.rs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 84cd5b002fbb..8b454ab2a424 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -772,8 +772,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( sym::simd_floor => "floor", sym::simd_fma => "fma", sym::simd_relaxed_fma => "fma", // FIXME: this should relax to non-fused multiply-add when necessary - sym::simd_fpowi => "__builtin_powi", - sym::simd_fpow => "pow", sym::simd_fsin => "sin", sym::simd_fsqrt => "sqrt", sym::simd_round => "round", @@ -788,24 +786,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let mut vector_elements = vec![]; for i in 0..in_len { let index = bx.context.new_rvalue_from_long(bx.ulong_type, i as i64); - // we have to treat fpowi specially, since fpowi's second argument is always an i32 let mut arguments = vec![]; - if name == sym::simd_fpowi { - arguments = vec![ - bx.extract_element(args[0].immediate(), index).to_rvalue(), - args[1].immediate(), - ]; - } else { - for arg in args { - let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); - // FIXME: it would probably be better to not have casts here and use the proper - // instructions. - if let Some(typ) = cast_type { - element = bx.context.new_cast(None, element, typ); - } - arguments.push(element); + for arg in args { + let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); + // FIXME: it would probably be better to not have casts here and use the proper + // instructions. + if let Some(typ) = cast_type { + element = bx.context.new_cast(None, element, typ); } - }; + arguments.push(element); + } let mut result = bx.context.new_call(None, function, &arguments); if cast_type.is_some() { result = bx.context.new_cast(None, result, elem_ty); @@ -829,8 +819,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( | sym::simd_floor | sym::simd_fma | sym::simd_relaxed_fma - | sym::simd_fpow - | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt | sym::simd_round From 7721431d57f7c8eea818d39d7a284459bb15f6e3 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 27 Feb 2025 09:09:52 -0800 Subject: [PATCH 049/106] Stop using `hash_raw_entry` in `CodegenCx::const_str` That unstable feature completed fcp-close, so the compiler needs to be migrated away to allow its removal. In this case, `cg_llvm` and `cg_gcc` were using raw entries to optimize their `const_str_cache` lookup and insertion. We can change that to separate `get` and (on miss) `insert` calls, so we still have the fast path avoiding string allocation when the cache hits. --- src/common.rs | 13 ++++++------- src/lib.rs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/common.rs b/src/common.rs index 20a3482aaa27..ce1a20088647 100644 --- a/src/common.rs +++ b/src/common.rs @@ -146,13 +146,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) { - let str_global = *self - .const_str_cache - .borrow_mut() - .raw_entry_mut() - .from_key(s) - .or_insert_with(|| (s.to_owned(), self.global_string(s))) - .1; + let mut const_str_cache = self.const_str_cache.borrow_mut(); + let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| { + let g = self.global_string(s); + const_str_cache.insert(s.to_owned(), g); + g + }); let len = s.len(); let cs = self.const_ptrcast( str_global.get_address(None), diff --git a/src/lib.rs b/src/lib.rs index 6455bcec6851..741386876790 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)] +#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] From 975dee20ef70423c00a617867fa78e7ae9f63fce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:29:07 +0100 Subject: [PATCH 050/106] =?UTF-8?q?rename=20BackendRepr::Vector=20?= =?UTF-8?q?=E2=86=92=20SimdVector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/intrinsic/mod.rs | 2 +- src/type_of.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index f8672c072999..f38622074f18 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -312,7 +312,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Vector { .. } => false, + SimdVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/src/type_of.rs b/src/type_of.rs index bac4fc51300a..ae98b3d0b56e 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -63,7 +63,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ) -> Type<'gcc> { match layout.backend_repr { BackendRepr::Scalar(_) => bug!("handled elsewhere"), - BackendRepr::Vector { ref element, count } => { + BackendRepr::SimdVector { ref element, count } => { let element = layout.scalar_gcc_type_at(cx, element, Size::ZERO); let element = // NOTE: gcc doesn't allow pointer types in vectors. @@ -178,7 +178,7 @@ pub trait LayoutGccExt<'tcx> { impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -186,9 +186,9 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { - false - } + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::Memory { .. } => false, } } From c25f12a667cd83fb79e6f7098e3191f9b1ab6416 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Mar 2025 18:41:28 +0000 Subject: [PATCH 051/106] Revert "Auto merge of #135335 - oli-obk:push-zxwssomxxtnq, r=saethlin" This reverts commit a7a6c64a657f68113301c2ffe0745b49a16442d1, reversing changes made to ebbe63891f1fae21734cb97f2f863b08b1d44bf8. --- src/common.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/common.rs b/src/common.rs index 20a3482aaa27..2052a6aa2159 100644 --- a/src/common.rs +++ b/src/common.rs @@ -64,11 +64,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } - fn is_undef(&self, _val: RValue<'gcc>) -> bool { - // FIXME: actually check for undef - false - } - fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> { let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined"); if typ.is_struct().is_some() { From ae07d7d368f3487999e68c5c2aa00a9ba2539905 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 25 Feb 2025 14:13:16 +1100 Subject: [PATCH 052/106] Simplify `implied_target_features`. Currently its argument is an iterator, but in practice it's always a singleton. --- src/gcc_util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 4e8c8aaaf5c8..6eae0c24f48a 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -48,7 +48,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec Date: Tue, 25 Feb 2025 15:25:54 +1100 Subject: [PATCH 053/106] Change signature of `target_features_cfg`. Currently it is called twice, once with `allow_unstable` set to true and once with it set to false. This results in some duplicated work. Most notably, for the LLVM backend, `LLVMRustHasFeature` is called twice for every feature, and it's moderately slow. For very short running compilations on platforms with many features (e.g. a `check` build of hello-world on x86) this is a significant fraction of runtime. This commit changes `target_features_cfg` so it is only called once, and it now returns a pair of feature sets. This halves the number of `LLVMRustHasFeature` calls. --- src/lib.rs | 68 +++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f090597f9533..d478b2af46c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -259,8 +259,8 @@ impl CodegenBackend for GccCodegenBackend { .join(sess) } - fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec { - target_features_cfg(sess, allow_unstable, &self.target_info) + fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { + target_features_cfg(sess, &self.target_info) } } @@ -486,35 +486,41 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_features_cfg( sess: &Session, - allow_unstable: bool, target_info: &LockedTargetInfo, -) -> Vec { +) -> (Vec, Vec) { // TODO(antoyo): use global_gcc_features. - sess.target - .rust_target_features() - .iter() - .filter_map(|&(feature, gate, _)| { - if allow_unstable - || (gate.in_cfg() && (sess.is_nightly_build() || gate.requires_nightly().is_none())) - { - Some(feature) - } else { - None - } - }) - .filter(|feature| { - // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. - if *feature == "neon" { - return false; - } - target_info.cpu_supports(feature) - /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ - }) - .map(Symbol::intern) - .collect() + let f = |allow_unstable| { + sess.target + .rust_target_features() + .iter() + .filter_map(|&(feature, gate, _)| { + if allow_unstable + || (gate.in_cfg() + && (sess.is_nightly_build() || gate.requires_nightly().is_none())) + { + Some(feature) + } else { + None + } + }) + .filter(|feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if *feature == "neon" { + return false; + } + target_info.cpu_supports(feature) + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ + }) + .map(Symbol::intern) + .collect() + }; + + let target_features = f(false); + let unstable_target_features = f(true); + (target_features, unstable_target_features) } From 70b588882781ff091a0bff927f8ff74c0d234798 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 20:28:38 -0800 Subject: [PATCH 054/106] compiler: Use size_of from the prelude instead of imported Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the prelude instead of importing or qualifying them. These functions were added to all preludes in Rust 1.80. --- src/builder.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index c8b7616e6450..6573b5b165e6 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -2439,9 +2439,5 @@ fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { #[cfg(not(feature = "master"))] fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { let type_ = value.get_type(); - if type_.get_pointee().is_some() { - std::mem::size_of::<*const ()>() as _ - } else { - type_.get_size() - } + if type_.get_pointee().is_some() { size_of::<*const ()>() as _ } else { type_.get_size() } } From 572da5cd261381451669d7d35c199e2227f9e6db Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Sat, 8 Mar 2025 16:47:58 +0530 Subject: [PATCH 055/106] cleaned up tests by bringing objects under `mini_core` into scope --- example/mini_core.rs | 109 +++++++++--------- tests/run/abort1.rs | 41 +------ tests/run/abort2.rs | 41 +------ tests/run/array.rs | 10 +- tests/run/assign.rs | 127 +-------------------- tests/run/closure.rs | 39 ++----- tests/run/condition.rs | 26 ++--- tests/run/empty_main.rs | 30 +---- tests/run/exit.rs | 37 +------ tests/run/exit_code.rs | 30 +---- tests/run/float.rs | 4 - tests/run/fun_ptr.rs | 9 +- tests/run/int.rs | 4 - tests/run/mut_ref.rs | 131 +--------------------- tests/run/operations.rs | 225 +------------------------------------- tests/run/ptr_cast.rs | 9 +- tests/run/return-tuple.rs | 47 +------- tests/run/slice.rs | 13 +-- tests/run/static.rs | 78 +------------ tests/run/structs.rs | 45 +------- tests/run/tuple.rs | 37 +------ 21 files changed, 124 insertions(+), 968 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index bd7a4612a92c..8d749c7a8f17 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -51,6 +51,10 @@ impl LegacyReceiver for &T {} impl LegacyReceiver for &mut T {} impl LegacyReceiver for Box {} +#[lang = "receiver"] +trait Receiver { +} + #[lang = "copy"] pub trait Copy {} @@ -139,6 +143,14 @@ impl Mul for usize { } } +impl Mul for isize { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + #[lang = "add"] pub trait Add { type Output; @@ -162,6 +174,14 @@ impl Add for i8 { } } +impl Add for i32 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + impl Add for usize { type Output = Self; @@ -193,6 +213,14 @@ impl Sub for usize { } } +impl Sub for isize { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + impl Sub for u8 { type Output = Self; @@ -588,70 +616,43 @@ pub union MaybeUninit { pub mod intrinsics { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn size_of() -> usize { - loop {} - } + pub fn size_of() -> usize; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn size_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn size_of_val(_val: *const T) -> usize; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn min_align_of() -> usize { - loop {} - } + pub fn min_align_of() -> usize; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn min_align_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn min_align_of_val(_val: *const T) -> usize; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize) { - loop {} - } + pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn transmute(_e: T) -> U { - loop {} - } + pub unsafe fn transmute(_e: T) -> U; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn ctlz_nonzero(_x: T) -> u32 { - loop {} - } + pub unsafe fn ctlz_nonzero(_x: T) -> u32; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn needs_drop() -> bool { - loop {} - } + pub fn needs_drop() -> bool; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bitreverse(_x: T) -> T { - loop {} - } + pub fn bitreverse(_x: T) -> T; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bswap(_x: T) -> T { - loop {} - } + pub fn bswap(_x: T) -> T; + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize) { - loop {} - } + pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); + #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn unreachable() -> ! { - loop {} - } + pub unsafe fn unreachable() -> !; } pub mod libc { @@ -664,6 +665,10 @@ pub mod libc { pub fn memcpy(dst: *mut u8, src: *const u8, size: usize); pub fn memmove(dst: *mut u8, src: *const u8, size: usize); pub fn strncpy(dst: *mut u8, src: *const u8, size: usize); + pub fn fflush(stream: *mut i32) -> i32; + pub fn exit(status: i32); + + pub static stdout: *mut i32; } } diff --git a/tests/run/abort1.rs b/tests/run/abort1.rs index 696197d73772..6561aaf25f6e 100644 --- a/tests/run/abort1.rs +++ b/tests/run/abort1.rs @@ -3,47 +3,12 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn test_fail() -> ! { unsafe { intrinsics::abort() }; diff --git a/tests/run/abort2.rs b/tests/run/abort2.rs index 714cd6c0f381..a9f176577fc7 100644 --- a/tests/run/abort2.rs +++ b/tests/run/abort2.rs @@ -3,47 +3,12 @@ // Run-time: // status: signal -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn fail() -> i32 { unsafe { intrinsics::abort() }; diff --git a/tests/run/array.rs b/tests/run/array.rs index c3c08c29c6db..b405102baff6 100644 --- a/tests/run/array.rs +++ b/tests/run/array.rs @@ -8,19 +8,11 @@ // 10 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; - } -} +use mini_core::*; static mut ONE: usize = 1; diff --git a/tests/run/assign.rs b/tests/run/assign.rs index 2a47f0c2966e..99a61337ada4 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -5,132 +5,12 @@ // 7 8 // 10 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i32 {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - pub fn printf(format: *const i8, ...) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn inc_ref(num: &mut isize) -> isize { *num = *num + 5; @@ -141,7 +21,6 @@ fn inc(num: isize) -> isize { num + 1 } - #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { argc = inc(argc); diff --git a/tests/run/closure.rs b/tests/run/closure.rs index 46c47bc54ed0..c8f06265c6b9 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -9,54 +9,37 @@ // Both args: 11 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { let string = "Arg: %d\n\0"; - let mut closure = || { - unsafe { - libc::printf(string as *const str as *const i8, argc); - } + let mut closure = || unsafe { + libc::printf(string as *const str as *const i8, argc); }; closure(); - let mut closure = || { - unsafe { - libc::printf("Argument: %d\n\0" as *const str as *const i8, argc); - } + let mut closure = || unsafe { + libc::printf("Argument: %d\n\0" as *const str as *const i8, argc); }; closure(); - let mut closure = |string| { - unsafe { - libc::printf(string as *const str as *const i8, argc); - } + let mut closure = |string| unsafe { + libc::printf(string as *const str as *const i8, argc); }; closure("String arg: %d\n\0"); - let mut closure = |arg: isize| { - unsafe { - libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg); - } + let mut closure = |arg: isize| unsafe { + libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg); }; closure(argc + 1); - let mut closure = |string, arg: isize| { - unsafe { - libc::printf(string as *const str as *const i8, arg); - } + let mut closure = |string, arg: isize| unsafe { + libc::printf(string as *const str as *const i8, arg); }; closure("Both args: %d\n\0", argc + 10); diff --git a/tests/run/condition.rs b/tests/run/condition.rs index 039ef94eaa71..d3714587401a 100644 --- a/tests/run/condition.rs +++ b/tests/run/condition.rs @@ -6,18 +6,11 @@ // 1 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; #[start] fn main(argc: isize, _argv: *const *const u8) -> isize { @@ -26,15 +19,14 @@ fn main(argc: isize, _argv: *const *const u8) -> isize { libc::printf(b"true\n\0" as *const u8 as *const i8); } - let string = - match argc { - 1 => b"1\n\0", - 2 => b"2\n\0", - 3 => b"3\n\0", - 4 => b"4\n\0", - 5 => b"5\n\0", - _ => b"_\n\0", - }; + let string = match argc { + 1 => b"1\n\0", + 2 => b"2\n\0", + 3 => b"3\n\0", + 4 => b"4\n\0", + 5 => b"5\n\0", + _ => b"_\n\0", + }; libc::printf(string as *const u8 as *const i8); } 0 diff --git a/tests/run/empty_main.rs b/tests/run/empty_main.rs index e66a859ad698..c4a24e9b1854 100644 --- a/tests/run/empty_main.rs +++ b/tests/run/empty_main.rs @@ -3,36 +3,12 @@ // Run-time: // status: 0 -#![feature(auto_traits, lang_items, no_core, start)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { diff --git a/tests/run/exit.rs b/tests/run/exit.rs index bf1cbeef3020..3d66d8fbdb21 100644 --- a/tests/run/exit.rs +++ b/tests/run/exit.rs @@ -3,43 +3,12 @@ // Run-time: // status: 2 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -mod libc { - #[link(name = "c")] - extern "C" { - pub fn exit(status: i32); - } -} - -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { diff --git a/tests/run/exit_code.rs b/tests/run/exit_code.rs index be7a233efdaa..b18d08879f0d 100644 --- a/tests/run/exit_code.rs +++ b/tests/run/exit_code.rs @@ -3,36 +3,12 @@ // Run-time: // status: 1 -#![feature(auto_traits, lang_items, no_core, start)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { diff --git a/tests/run/float.rs b/tests/run/float.rs index e0a57e6fed1a..424fa1cf4ad5 100644 --- a/tests/run/float.rs +++ b/tests/run/float.rs @@ -5,10 +5,6 @@ #![feature(const_black_box)] -/* - * Code - */ - fn main() { use std::hint::black_box; diff --git a/tests/run/fun_ptr.rs b/tests/run/fun_ptr.rs index ed1bf72bb275..45b4ebcd9f05 100644 --- a/tests/run/fun_ptr.rs +++ b/tests/run/fun_ptr.rs @@ -5,18 +5,11 @@ // stdout: 1 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; fn i16_as_i8(a: i16) -> i8 { a as i8 diff --git a/tests/run/int.rs b/tests/run/int.rs index bfe73c38435a..47b5dea46f8d 100644 --- a/tests/run/int.rs +++ b/tests/run/int.rs @@ -5,10 +5,6 @@ #![feature(const_black_box)] -/* - * Code - */ - fn main() { use std::hint::black_box; diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index 3ae793382164..5c91bc96ca00 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -1,4 +1,3 @@ - // Compiler: // // Run-time: @@ -7,141 +6,19 @@ // 6 // 11 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i32 {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - pub fn printf(format: *const i8, ...) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, } fn test(num: isize) -> Test { - Test { - field: num + 1, - } + Test { field: num + 1 } } fn update_num(num: &mut isize) { diff --git a/tests/run/operations.rs b/tests/run/operations.rs index 0e44fc580b8c..a298cf2a68d5 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -5,231 +5,12 @@ // 39 // 10 -#![allow(internal_features, unused_attributes)] -#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut i32 {} -impl Copy for usize {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for i32 {} - -#[lang = "deref"] -pub trait Deref { - type Target: ?Sized; - - fn deref(&self) -> &Self::Target; -} - -#[lang = "legacy_receiver"] -trait LegacyReceiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; - pub fn fflush(stream: *mut i32) -> i32; - - pub static stdout: *mut i32; - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - libc::fflush(libc::stdout); - intrinsics::abort(); - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -#[lang = "mul"] -pub trait Mul { - type Output; - - #[must_use] - fn mul(self, rhs: RHS) -> Self::Output; -} - -impl Mul for u8 { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -impl Mul for usize { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -impl Mul for isize { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - self * rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -#[track_caller] -#[lang = "panic_const_sub_overflow"] -pub fn panic_const_sub_overflow() -> ! { - panic("attempt to subtract with overflow"); -} - -#[track_caller] -#[lang = "panic_const_mul_overflow"] -pub fn panic_const_mul_overflow() -> ! { - panic("attempt to multiply with overflow"); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { diff --git a/tests/run/ptr_cast.rs b/tests/run/ptr_cast.rs index 2b8812ad51c5..eb4cf3eafd0e 100644 --- a/tests/run/ptr_cast.rs +++ b/tests/run/ptr_cast.rs @@ -5,18 +5,11 @@ // stdout: 1 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; static mut ONE: usize = 1; diff --git a/tests/run/return-tuple.rs b/tests/run/return-tuple.rs index f2a5a2e4384d..c3069933e085 100644 --- a/tests/run/return-tuple.rs +++ b/tests/run/return-tuple.rs @@ -6,53 +6,12 @@ // 10 // 42 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -#[lang = "copy"] -pub unsafe trait Copy {} - -impl Copy for bool {} -impl Copy for u8 {} -impl Copy for u16 {} -impl Copy for u32 {} -impl Copy for u64 {} -impl Copy for usize {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for i32 {} -impl Copy for isize {} -impl Copy for f32 {} -impl Copy for char {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "legacy_receiver"] -trait LegacyReceiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) { ( diff --git a/tests/run/slice.rs b/tests/run/slice.rs index fba93fc15549..6f2f8b9a9cec 100644 --- a/tests/run/slice.rs +++ b/tests/run/slice.rs @@ -5,25 +5,16 @@ // stdout: 5 #![feature(no_core, start)] - #![no_std] #![no_core] extern crate mini_core; - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} +use mini_core::*; static mut TWO: usize = 2; fn index_slice(s: &[u32]) -> u32 { - unsafe { - s[TWO] - } + unsafe { s[TWO] } } #[start] diff --git a/tests/run/static.rs b/tests/run/static.rs index a17ea2a48936..5fc167ce4e47 100644 --- a/tests/run/static.rs +++ b/tests/run/static.rs @@ -9,72 +9,12 @@ // 12 // 1 -#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "destruct"] -pub trait Destruct {} - -#[lang = "drop"] -pub trait Drop {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -#[lang = "structural_peq"] -pub trait StructuralPartialEq {} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, @@ -86,17 +26,11 @@ struct WithRef { static mut CONSTANT: isize = 10; -static mut TEST: Test = Test { - field: 12, -}; +static mut TEST: Test = Test { field: 12 }; -static mut TEST2: Test = Test { - field: 14, -}; +static mut TEST2: Test = Test { field: 14 }; -static mut WITH_REF: WithRef = WithRef { - refe: unsafe { &TEST }, -}; +static mut WITH_REF: WithRef = WithRef { refe: unsafe { &TEST } }; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { diff --git a/tests/run/structs.rs b/tests/run/structs.rs index d6455667400c..641c6c71d1e0 100644 --- a/tests/run/structs.rs +++ b/tests/run/structs.rs @@ -5,43 +5,12 @@ // stdout: 1 // 2 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; struct Test { field: isize, @@ -57,12 +26,8 @@ fn one() -> isize { #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { - let test = Test { - field: one(), - }; - let two = Two { - two: 2, - }; + let test = Test { field: one() }; + let two = Two { two: 2 }; unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); libc::printf(b"%ld\n\0" as *const u8 as *const i8, two.two); diff --git a/tests/run/tuple.rs b/tests/run/tuple.rs index 8a7d85ae867e..1f2d24eeacc5 100644 --- a/tests/run/tuple.rs +++ b/tests/run/tuple.rs @@ -4,43 +4,12 @@ // status: 0 // stdout: 3 -#![feature(auto_traits, lang_items, no_core, start, intrinsics)] -#![allow(internal_features)] - +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} - -mod libc { - #[link(name = "c")] - extern "C" { - pub fn printf(format: *const i8, ...) -> i32; - } -} - -/* - * Code - */ +extern crate mini_core; +use mini_core::*; #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { From 7989568b8edd6531ed062614b71c327677b581ba Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Mar 2025 08:03:54 +0100 Subject: [PATCH 056/106] intrinsics: remove unnecessary leading underscore from argument names --- example/mini_core.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 3dad35bc4ce4..5544aee9eaf1 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -595,25 +595,25 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn size_of() -> usize; #[rustc_intrinsic] - pub unsafe fn size_of_val(_val: *const T) -> usize; + pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub fn min_align_of() -> usize; #[rustc_intrinsic] - pub unsafe fn min_align_of_val(_val: *const T) -> usize; + pub unsafe fn min_align_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); + pub unsafe fn copy(src: *const T, dst: *mut T, count: usize); #[rustc_intrinsic] - pub unsafe fn transmute(_e: T) -> U; + pub unsafe fn transmute(e: T) -> U; #[rustc_intrinsic] - pub unsafe fn ctlz_nonzero(_x: T) -> u32; + pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] pub fn needs_drop() -> bool; #[rustc_intrinsic] - pub fn bitreverse(_x: T) -> T; + pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] - pub fn bswap(_x: T) -> T; + pub fn bswap(x: T) -> T; #[rustc_intrinsic] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); + pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); #[rustc_intrinsic] pub unsafe fn unreachable() -> !; } From b25a593b40e88019a5c76198f5c69e2fcced368d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 2 Dec 2023 14:17:33 +0000 Subject: [PATCH 057/106] Remove implicit #[no_mangle] for #[rustc_std_internal_symbol] --- src/allocator.rs | 13 +++++++------ src/lib.rs | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 416f3231a13c..f4ebd42ee2dc 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -8,6 +8,7 @@ use rustc_ast::expand::allocator::{ use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; +use rustc_symbol_mangling::mangle_internal_symbol; use crate::GccContext; #[cfg(feature = "master")] @@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen( panic!("invalid allocator output") } }; - let from_name = global_fn_name(method.name); - let to_name = default_fn_name(method.name); + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); } @@ -64,13 +65,13 @@ pub(crate) unsafe fn codegen( create_wrapper_function( tcx, context, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), + &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), &[usize, usize], None, ); - let name = OomStrategy::SYMBOL.to_string(); + let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( @@ -80,7 +81,7 @@ pub(crate) unsafe fn codegen( let value = context.new_rvalue_from_int(i8, value as i32); global.global_set_initializer_rvalue(value); - let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string(); + let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( diff --git a/src/lib.rs b/src/lib.rs index d478b2af46c2..bfa23174a19d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,6 +52,7 @@ extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +extern crate rustc_symbol_mangling; extern crate rustc_target; // This prevents duplicating functions and statics that are already part of the host rustc process. From 5743d381af27a24d12e5272043fa4e21dfa5794a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 19 Aug 2024 15:20:02 +0200 Subject: [PATCH 058/106] Rename `is_like_osx` to `is_like_darwin` --- src/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/consts.rs b/src/consts.rs index c514b7a428bc..0dc0a9182988 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -131,7 +131,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { // will use load-unaligned instructions instead, and thus avoiding the crash. // // We could remove this hack whenever we decide to drop macOS 10.10 support. - if self.tcx.sess.target.options.is_like_osx { + if self.tcx.sess.target.options.is_like_darwin { // The `inspect` method is okay here because we checked for provenance, and // because we are doing this access to inspect the final interpreter state // (not as part of the interpreter execution). From 2f5aa084c8bb6e1a4b014396a44087fd65a4c1c8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 14 Mar 2025 15:56:33 +0000 Subject: [PATCH 059/106] Avoid wrapping constant allocations in packed structs when not necessary This way LLVM will set the string merging flag if the alloc is a nul terminated string, reducing binary sizes. --- src/consts.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/consts.rs b/src/consts.rs index c514b7a428bc..474475f311f7 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -364,6 +364,7 @@ pub fn const_alloc_to_gcc<'gcc>( llvals.push(cx.const_bytes(bytes)); } + // FIXME(bjorn3) avoid wrapping in a struct when there is only a single element. cx.const_struct(&llvals, true) } From 3c3a6a299593d045141faee662ecde9aeb6ec13b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Apr 2025 23:37:30 +0000 Subject: [PATCH 060/106] Simplify temp path creation a bit --- src/back/write.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/back/write.rs b/src/back/write.rs index 51c5ba73e32b..3427b38ce830 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -24,19 +24,15 @@ pub(crate) unsafe fn codegen( { let context = &module.module_llvm.context; - let module_name = module.name.clone(); - let should_combine_object_files = module.module_llvm.should_combine_object_files; - let module_name = Some(&module_name[..]); - // NOTE: Only generate object files with GIMPLE when this environment variable is set for // now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit). // TODO(antoyo): remove this environment variable. let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); - let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); - let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); + let bc_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Bitcode, &module.name); + let obj_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Object, &module.name); if config.bitcode_needed() { if fat_lto { @@ -117,14 +113,15 @@ pub(crate) unsafe fn codegen( } if config.emit_ir { - let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); + let out = + cgcx.output_filenames.temp_path_for_cgu(OutputType::LlvmAssembly, &module.name); std::fs::write(out, "").expect("write file"); } if config.emit_asm { let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); - let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + let path = cgcx.output_filenames.temp_path_for_cgu(OutputType::Assembly, &module.name); context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str")); } From 22d3c0d70a023f3f1641b4b70e4b48949dcface3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Apr 2025 23:50:16 +0000 Subject: [PATCH 061/106] Prepend temp files with a string per invocation of rustc --- src/back/write.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/back/write.rs b/src/back/write.rs index 3427b38ce830..16c895322e88 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -31,8 +31,16 @@ pub(crate) unsafe fn codegen( // TODO(antoyo): remove this environment variable. let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); - let bc_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Bitcode, &module.name); - let obj_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Object, &module.name); + let bc_out = cgcx.output_filenames.temp_path_for_cgu( + OutputType::Bitcode, + &module.name, + cgcx.invocation_temp.as_deref(), + ); + let obj_out = cgcx.output_filenames.temp_path_for_cgu( + OutputType::Object, + &module.name, + cgcx.invocation_temp.as_deref(), + ); if config.bitcode_needed() { if fat_lto { @@ -113,15 +121,22 @@ pub(crate) unsafe fn codegen( } if config.emit_ir { - let out = - cgcx.output_filenames.temp_path_for_cgu(OutputType::LlvmAssembly, &module.name); + let out = cgcx.output_filenames.temp_path_for_cgu( + OutputType::LlvmAssembly, + &module.name, + cgcx.invocation_temp.as_deref(), + ); std::fs::write(out, "").expect("write file"); } if config.emit_asm { let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); - let path = cgcx.output_filenames.temp_path_for_cgu(OutputType::Assembly, &module.name); + let path = cgcx.output_filenames.temp_path_for_cgu( + OutputType::Assembly, + &module.name, + cgcx.invocation_temp.as_deref(), + ); context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str")); } @@ -235,6 +250,7 @@ pub(crate) unsafe fn codegen( config.emit_asm, config.emit_ir, &cgcx.output_filenames, + cgcx.invocation_temp.as_deref(), )) } From 3ee62a906e8a025834d11c46b8c2f133d3a12448 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 30 Mar 2025 18:52:25 +0000 Subject: [PATCH 062/106] Do not optimize out SwitchInt before borrowck, or if Zmir-preserve-ub --- compiler/rustc_interface/src/tests.rs | 2 +- .../src/early_otherwise_branch.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 4 +- .../rustc_mir_transform/src/match_branches.rs | 2 +- .../src/remove_place_mention.rs | 2 +- .../src/remove_unneeded_drops.rs | 2 +- compiler/rustc_mir_transform/src/simplify.rs | 35 +++++++++---- compiler/rustc_session/src/options.rs | 6 +-- src/tools/miri/src/lib.rs | 2 +- .../tests/fail/read_from_trivial_switch.rs | 14 ++++++ .../fail/read_from_trivial_switch.stderr | 15 ++++++ ....match_tuple.SimplifyCfg-initial.after.mir | 34 +++++++------ .../dead-store-elimination/place_mention.rs | 2 +- ...le_switchint.SimplifyCfg-initial.after.mir | 38 ++++++++------ ...ivial_switch.main.SimplifyCfg-initial.diff | 49 +++++++++++++++++++ tests/mir-opt/read_from_trivial_switch.rs | 15 ++++++ tests/ui/pattern/uninit-trivial.rs | 8 +++ tests/ui/pattern/uninit-trivial.stderr | 16 ++++++ 18 files changed, 197 insertions(+), 51 deletions(-) create mode 100644 src/tools/miri/tests/fail/read_from_trivial_switch.rs create mode 100644 src/tools/miri/tests/fail/read_from_trivial_switch.stderr create mode 100644 tests/mir-opt/read_from_trivial_switch.main.SimplifyCfg-initial.diff create mode 100644 tests/mir-opt/read_from_trivial_switch.rs create mode 100644 tests/ui/pattern/uninit-trivial.rs create mode 100644 tests/ui/pattern/uninit-trivial.stderr diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a8e556632572..af30a2d8aa88 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -817,8 +817,8 @@ fn test_unstable_options_tracking_hash() { tracked!(min_function_alignment, Some(Align::EIGHT)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); - tracked!(mir_keep_place_mention, true); tracked!(mir_opt_level, Some(4)); + tracked!(mir_preserve_ub, true); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 57f7893be1b8..ac97b08fbed1 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -224,7 +224,7 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { // Since this optimization adds new basic blocks and invalidates others, // clean up the cfg to make it nicer for other passes if should_cleanup { - simplify_cfg(body); + simplify_cfg(tcx, body); } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 0ab24e48d443..babee81a2ad0 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -63,7 +63,7 @@ impl<'tcx> crate::MirPass<'tcx> for Inline { let _guard = span.enter(); if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); - simplify_cfg(body); + simplify_cfg(tcx, body); deref_finder(tcx, body); } } @@ -99,7 +99,7 @@ impl<'tcx> crate::MirPass<'tcx> for ForceInline { let _guard = span.enter(); if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); - simplify_cfg(body); + simplify_cfg(tcx, body); deref_finder(tcx, body); } } diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index 0d9d0368d372..d43a35124c2a 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -45,7 +45,7 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { } if should_cleanup { - simplify_cfg(body); + simplify_cfg(tcx, body); } } diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs index 15fe77d53195..cb598ceb4dfe 100644 --- a/compiler/rustc_mir_transform/src/remove_place_mention.rs +++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs @@ -8,7 +8,7 @@ pub(super) struct RemovePlaceMention; impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - !sess.opts.unstable_opts.mir_keep_place_mention + !sess.opts.unstable_opts.mir_preserve_ub } fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs index 8a8cdafc6907..43f80508e4a8 100644 --- a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs @@ -35,7 +35,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops { // if we applied optimizations, we potentially have some cfg to cleanup to // make it easier for further passes if should_simplify { - simplify_cfg(body); + simplify_cfg(tcx, body); } } diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 84905f4a400f..6c8fa1fe9b3f 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -26,6 +26,13 @@ //! Here the block (`{ return; }`) has the return type `char`, rather than `()`, but the MIR we //! naively generate still contains the `_a = ()` write in the unreachable block "after" the //! return. +//! +//! **WARNING**: This is one of the few optimizations that runs on built and analysis MIR, and +//! so its effects may affect the type-checking, borrow-checking, and other analysis of MIR. +//! We must be extremely careful to only apply optimizations that preserve UB and all +//! non-determinism, since changes here can affect which programs compile in an insta-stable way. +//! The normal logic that a program with UB can be changed to do anything does not apply to +//! pre-"runtime" MIR! use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; @@ -66,8 +73,8 @@ impl SimplifyCfg { } } -pub(super) fn simplify_cfg(body: &mut Body<'_>) { - CfgSimplifier::new(body).simplify(); +pub(super) fn simplify_cfg<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + CfgSimplifier::new(tcx, body).simplify(); remove_dead_blocks(body); // FIXME: Should probably be moved into some kind of pass manager @@ -79,9 +86,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg { self.name() } - fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!("SimplifyCfg({:?}) - simplifying {:?}", self.name(), body.source); - simplify_cfg(body); + simplify_cfg(tcx, body); } fn is_required(&self) -> bool { @@ -90,12 +97,13 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg { } struct CfgSimplifier<'a, 'tcx> { + preserve_switch_reads: bool, basic_blocks: &'a mut IndexSlice>, pred_count: IndexVec, } impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { - fn new(body: &'a mut Body<'tcx>) -> Self { + fn new(tcx: TyCtxt<'tcx>, body: &'a mut Body<'tcx>) -> Self { let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks); // we can't use mir.predecessors() here because that counts @@ -110,9 +118,12 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } + // Preserve `SwitchInt` reads on built and analysis MIR, or if `-Zmir-preserve-ub`. + let preserve_switch_reads = matches!(body.phase, MirPhase::Built | MirPhase::Analysis(_)) + || tcx.sess.opts.unstable_opts.mir_preserve_ub; let basic_blocks = body.basic_blocks_mut(); - CfgSimplifier { basic_blocks, pred_count } + CfgSimplifier { preserve_switch_reads, basic_blocks, pred_count } } fn simplify(mut self) { @@ -253,9 +264,15 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { // turn a branch with all successors identical to a goto fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool { - match terminator.kind { - TerminatorKind::SwitchInt { .. } => {} - _ => return false, + // Removing a `SwitchInt` terminator may remove reads that result in UB, + // so we must not apply this optimization before borrowck or when + // `-Zmir-preserve-ub` is set. + if self.preserve_switch_reads { + return false; + } + + let TerminatorKind::SwitchInt { .. } = terminator.kind else { + return false; }; let first_succ = { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c70f1500d393..ea959d4ced1e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2319,12 +2319,12 @@ options! { mir_include_spans: MirIncludeSpans = (MirIncludeSpans::default(), parse_mir_include_spans, [UNTRACKED], "include extra comments in mir pretty printing, like line numbers and statement indices, \ details about types, etc. (boolean for all passes, 'nll' to enable in NLL MIR only, default: 'nll')"), - mir_keep_place_mention: bool = (false, parse_bool, [TRACKED], - "keep place mention MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ - (default: no)"), #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] mir_opt_level: Option = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), + mir_preserve_ub: bool = (false, parse_bool, [TRACKED], + "keep place mention statements and reads in trivial SwitchInt terminators, which are interpreted \ + e.g., by miri; implies -Zmir-opt-level=0 (default: no)"), mir_strip_debuginfo: MirStripDebugInfo = (MirStripDebugInfo::None, parse_mir_strip_debuginfo, [TRACKED], "Whether to remove some of the MIR debug info from methods. Default: None"), move_size_limit: Option = (None, parse_opt_number, [TRACKED], diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 03f76cfa6524..6f227e04d00f 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -169,7 +169,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zalways-encode-mir", "-Zextra-const-ub-checks", "-Zmir-emit-retag", - "-Zmir-keep-place-mention", + "-Zmir-preserve-ub", "-Zmir-opt-level=0", "-Zmir-enable-passes=-CheckAlignment,-CheckNull", // Deduplicating diagnostics means we miss events when tracking what happens during an diff --git a/src/tools/miri/tests/fail/read_from_trivial_switch.rs b/src/tools/miri/tests/fail/read_from_trivial_switch.rs new file mode 100644 index 000000000000..d34b1cd58200 --- /dev/null +++ b/src/tools/miri/tests/fail/read_from_trivial_switch.rs @@ -0,0 +1,14 @@ +// Ensure that we don't optimize out `SwitchInt` reads even if that terminator +// branches to the same basic block on every target, since the operand may have +// side-effects that affect analysis of the MIR. +// +// See . + +use std::mem::MaybeUninit; + +fn main() { + let uninit: MaybeUninit = MaybeUninit::uninit(); + let bad_ref: &i32 = unsafe { uninit.assume_init_ref() }; + let &(0 | _) = bad_ref; + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory +} diff --git a/src/tools/miri/tests/fail/read_from_trivial_switch.stderr b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr new file mode 100644 index 000000000000..6b3d4539b968 --- /dev/null +++ b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> tests/fail/read_from_trivial_switch.rs:LL:CC + | +LL | let &(0 | _) = bad_ref; + | ^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/read_from_trivial_switch.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index d52241b459eb..2a965fe67b9e 100644 --- a/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -24,43 +24,47 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { bb1: { _0 = const 0_u32; - goto -> bb10; + goto -> bb11; } bb2: { - _2 = discriminant((_1.2: std::option::Option)); - switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb1]; + switchInt(copy (_1.1: bool)) -> [0: bb3, otherwise: bb3]; } bb3: { - switchInt(copy (((_1.2: std::option::Option) as Some).0: i32)) -> [1: bb4, 8: bb4, otherwise: bb1]; + _2 = discriminant((_1.2: std::option::Option)); + switchInt(move _2) -> [0: bb5, 1: bb4, otherwise: bb1]; } bb4: { - _5 = Le(const 6_u32, copy (_1.3: u32)); - switchInt(move _5) -> [0: bb5, otherwise: bb7]; + switchInt(copy (((_1.2: std::option::Option) as Some).0: i32)) -> [1: bb5, 8: bb5, otherwise: bb1]; } bb5: { - _3 = Le(const 13_u32, copy (_1.3: u32)); - switchInt(move _3) -> [0: bb1, otherwise: bb6]; + _5 = Le(const 6_u32, copy (_1.3: u32)); + switchInt(move _5) -> [0: bb6, otherwise: bb8]; } bb6: { - _4 = Le(copy (_1.3: u32), const 16_u32); - switchInt(move _4) -> [0: bb1, otherwise: bb8]; + _3 = Le(const 13_u32, copy (_1.3: u32)); + switchInt(move _3) -> [0: bb1, otherwise: bb7]; } bb7: { - _6 = Le(copy (_1.3: u32), const 9_u32); - switchInt(move _6) -> [0: bb5, otherwise: bb8]; + _4 = Le(copy (_1.3: u32), const 16_u32); + switchInt(move _4) -> [0: bb1, otherwise: bb9]; } bb8: { - falseEdge -> [real: bb9, imaginary: bb1]; + _6 = Le(copy (_1.3: u32), const 9_u32); + switchInt(move _6) -> [0: bb6, otherwise: bb9]; } bb9: { + falseEdge -> [real: bb10, imaginary: bb1]; + } + + bb10: { StorageLive(_7); _7 = copy (_1.0: u32); StorageLive(_8); @@ -74,10 +78,10 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { StorageDead(_9); StorageDead(_8); StorageDead(_7); - goto -> bb10; + goto -> bb11; } - bb10: { + bb11: { return; } } diff --git a/tests/mir-opt/dead-store-elimination/place_mention.rs b/tests/mir-opt/dead-store-elimination/place_mention.rs index 5e4a286a2087..1848a0282975 100644 --- a/tests/mir-opt/dead-store-elimination/place_mention.rs +++ b/tests/mir-opt/dead-store-elimination/place_mention.rs @@ -2,7 +2,7 @@ // and don't remove it as a dead store. // //@ test-mir-pass: DeadStoreElimination-initial -//@ compile-flags: -Zmir-keep-place-mention +//@ compile-flags: -Zmir-preserve-ub // EMIT_MIR place_mention.main.DeadStoreElimination-initial.diff fn main() { diff --git a/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir b/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir index 889ff6f9f5e2..be0931eaa61d 100644 --- a/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir @@ -14,7 +14,7 @@ fn single_switchint() -> () { } bb1: { - switchInt(copy (_2.0: i32)) -> [3: bb8, 4: bb8, otherwise: bb7]; + switchInt(copy (_2.0: i32)) -> [3: bb9, 4: bb9, otherwise: bb8]; } bb2: { @@ -22,7 +22,7 @@ fn single_switchint() -> () { } bb3: { - falseEdge -> [real: bb12, imaginary: bb4]; + falseEdge -> [real: bb14, imaginary: bb4]; } bb4: { @@ -30,43 +30,51 @@ fn single_switchint() -> () { } bb5: { - falseEdge -> [real: bb11, imaginary: bb6]; + falseEdge -> [real: bb13, imaginary: bb6]; } bb6: { - falseEdge -> [real: bb10, imaginary: bb1]; + switchInt(copy (_2.1: bool)) -> [0: bb7, otherwise: bb7]; } bb7: { - _1 = const 5_i32; - goto -> bb13; + falseEdge -> [real: bb12, imaginary: bb1]; } bb8: { - falseEdge -> [real: bb9, imaginary: bb7]; + _1 = const 5_i32; + goto -> bb15; } bb9: { - _1 = const 4_i32; - goto -> bb13; + switchInt(copy (_2.1: bool)) -> [0: bb10, otherwise: bb10]; } bb10: { - _1 = const 3_i32; - goto -> bb13; + falseEdge -> [real: bb11, imaginary: bb8]; } bb11: { - _1 = const 2_i32; - goto -> bb13; + _1 = const 4_i32; + goto -> bb15; } bb12: { - _1 = const 1_i32; - goto -> bb13; + _1 = const 3_i32; + goto -> bb15; } bb13: { + _1 = const 2_i32; + goto -> bb15; + } + + bb14: { + _1 = const 1_i32; + goto -> bb15; + } + + bb15: { StorageDead(_2); StorageDead(_1); _0 = const (); diff --git a/tests/mir-opt/read_from_trivial_switch.main.SimplifyCfg-initial.diff b/tests/mir-opt/read_from_trivial_switch.main.SimplifyCfg-initial.diff new file mode 100644 index 000000000000..87758408a1c3 --- /dev/null +++ b/tests/mir-opt/read_from_trivial_switch.main.SimplifyCfg-initial.diff @@ -0,0 +1,49 @@ +- // MIR for `main` before SimplifyCfg-initial ++ // MIR for `main` after SimplifyCfg-initial + + fn main() -> () { + let mut _0: (); + let _1: &i32; + let _2: i32; + scope 1 { + debug ref_ => _1; + scope 2 { + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const 1_i32; + _1 = &_2; + FakeRead(ForLet(None), _1); + PlaceMention(_1); +- switchInt(copy (*_1)) -> [0: bb2, otherwise: bb1]; ++ switchInt(copy (*_1)) -> [0: bb1, otherwise: bb1]; + } + + bb1: { +- goto -> bb5; +- } +- +- bb2: { +- goto -> bb5; +- } +- +- bb3: { +- goto -> bb1; +- } +- +- bb4: { +- FakeRead(ForMatchedPlace(None), _1); +- unreachable; +- } +- +- bb5: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/read_from_trivial_switch.rs b/tests/mir-opt/read_from_trivial_switch.rs new file mode 100644 index 000000000000..1c64c1d45e83 --- /dev/null +++ b/tests/mir-opt/read_from_trivial_switch.rs @@ -0,0 +1,15 @@ +// Ensure that we don't optimize out `SwitchInt` reads even if that terminator +// branches to the same basic block on every target, since the operand may have +// side-effects that affect analysis of the MIR. +// +// See . + +//@ test-mir-pass: SimplifyCfg-initial +//@ compile-flags: -Zmir-preserve-ub + +// EMIT_MIR read_from_trivial_switch.main.SimplifyCfg-initial.diff +fn main() { + let ref_ = &1i32; + // CHECK: switchInt + let &(0 | _) = ref_; +} diff --git a/tests/ui/pattern/uninit-trivial.rs b/tests/ui/pattern/uninit-trivial.rs new file mode 100644 index 000000000000..6ea6796c1c1f --- /dev/null +++ b/tests/ui/pattern/uninit-trivial.rs @@ -0,0 +1,8 @@ +// Regression test for the semantic changes in +// . + +fn main() { + let x; + let (0 | _) = x; + //~^ ERROR used binding `x` isn't initialized +} diff --git a/tests/ui/pattern/uninit-trivial.stderr b/tests/ui/pattern/uninit-trivial.stderr new file mode 100644 index 000000000000..2ff8557c9454 --- /dev/null +++ b/tests/ui/pattern/uninit-trivial.stderr @@ -0,0 +1,16 @@ +error[E0381]: used binding `x` isn't initialized + --> $DIR/uninit-trivial.rs:6:10 + | +LL | let x; + | - binding declared here but left uninitialized +LL | let (0 | _) = x; + | ^^^^^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x = 42; + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`. From 830bd8b6f4feb8665c8865beb20ffb424e8d8ee6 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 6 Apr 2025 07:06:10 +0000 Subject: [PATCH 063/106] Implement Default for raw pointers --- library/core/src/ptr/const_ptr.rs | 8 ++++++++ library/core/src/ptr/mut_ptr.rs | 8 ++++++++ library/coretests/tests/ptr.rs | 17 +++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 0854e31c1997..2d869958b85c 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1739,3 +1739,11 @@ impl PartialOrd for *const T { *self >= *other } } + +#[stable(feature = "raw_ptr_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for *const T { + /// Returns the default value of [`null()`][crate::ptr::null]. + fn default() -> Self { + crate::ptr::null() + } +} diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e29774963db0..df49eedb3509 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2156,3 +2156,11 @@ impl PartialOrd for *mut T { *self >= *other } } + +#[stable(feature = "raw_ptr_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for *mut T { + /// Returns the default value of [`null_mut()`][crate::ptr::null_mut]. + fn default() -> Self { + crate::ptr::null_mut() + } +} diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index cc5f7946863a..7d6e4eac1e21 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -1020,3 +1020,20 @@ fn test_ptr_swap_nonoverlapping_is_untyped() { ptr_swap_nonoverlapping_is_untyped_inner(); const { ptr_swap_nonoverlapping_is_untyped_inner() }; } + +#[test] +fn test_ptr_default() { + #[derive(Default)] + struct PtrDefaultTest { + ptr: *const u64, + } + let default = PtrDefaultTest::default(); + assert!(default.ptr.is_null()); + + #[derive(Default)] + struct PtrMutDefaultTest { + ptr: *mut u64, + } + let default = PtrMutDefaultTest::default(); + assert!(default.ptr.is_null()); +} From d1e82ba37c3dd1998808665971bbee4e1ae028b8 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Mon, 14 Apr 2025 21:43:53 -0700 Subject: [PATCH 064/106] Setup editor file associations for non-rs extensions .gitattributes lists *.fixed, *.pp, and *.mir as file extensions which should be treated as Rust source code. Do the same for VS Code and Zed. This only does syntax highlighting, which is appropriate, as MIR isn't really Rust code. At the same time, consistently order `rust-analyzer.linkedProjects` between editors. For some reason, Eglot didn't include library/Cargo.toml. --- src/bootstrap/src/core/build_steps/setup.rs | 3 +++ src/etc/rust_analyzer_eglot.el | 7 ++++--- src/etc/rust_analyzer_settings.json | 11 ++++++++--- src/etc/rust_analyzer_zed.json | 13 ++++++++----- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 80d92135dd37..83083e12ef1f 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -584,6 +584,7 @@ Select which editor you would like to set up [default: None]: "; "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", + "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", ], EditorKind::Helix => &[ "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", @@ -602,10 +603,12 @@ Select which editor you would like to set up [default: None]: "; "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", ], EditorKind::Zed => &[ "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", + "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", ], } } diff --git a/src/etc/rust_analyzer_eglot.el b/src/etc/rust_analyzer_eglot.el index 6b40371d9af1..90bd38aa8947 100644 --- a/src/etc/rust_analyzer_eglot.el +++ b/src/etc/rust_analyzer_eglot.el @@ -8,10 +8,11 @@ "check" "--json-output"]) :linkedProjects ["Cargo.toml" - "src/bootstrap/Cargo.toml" - "src/tools/rust-analyzer/Cargo.toml" "compiler/rustc_codegen_cranelift/Cargo.toml" - "compiler/rustc_codegen_gcc/Cargo.toml"] + "compiler/rustc_codegen_gcc/Cargo.toml" + "library/Cargo.toml" + "src/bootstrap/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml"] :rustfmt ( :overrideCommand ["build/host/rustfmt/bin/rustfmt" "--edition=2021"]) :procMacro ( :server "build/host/stage0/libexec/rust-analyzer-proc-macro-srv" diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index da7d326a512c..5ce886a9b659 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -9,11 +9,11 @@ ], "rust-analyzer.linkedProjects": [ "Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", "library/Cargo.toml", "src/bootstrap/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml" ], "rust-analyzer.rustfmt.overrideCommand": [ "${workspaceFolder}/build/host/rustfmt/bin/rustfmt", @@ -36,5 +36,10 @@ }, "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "nightly" + }, + "files.associations": { + "*.fixed": "rust", + "*.pp": "rust", + "*.mir": "rust" } } diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json index abc6ddbc213c..3461ff887d9b 100644 --- a/src/etc/rust_analyzer_zed.json +++ b/src/etc/rust_analyzer_zed.json @@ -21,15 +21,15 @@ }, "linkedProjects": [ "Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", "library/Cargo.toml", "src/bootstrap/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml" ], "procMacro": { - "enable": true, - "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv" + "enable": true, + "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv" }, "rustc": { "source": "./Cargo.toml" @@ -47,5 +47,8 @@ } } } + }, + "file_types": { + "Rust": ["fixed", "pp", "mir"] } } From 1dd77cd24acd5a960c4ddaa7a368d1518a995407 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 27 Mar 2025 18:30:51 +0100 Subject: [PATCH 065/106] Implement `pin!()` using `super let`. --- compiler/rustc_span/src/symbol.rs | 1 - library/core/src/pin.rs | 137 +++++------------- library/coretests/tests/pin_macro.rs | 1 + .../feature-gate-unsafe_pin_internals.rs | 16 -- .../feature-gate-unsafe_pin_internals.stderr | 15 -- tests/ui/pin-macro/cant_access_internals.rs | 12 -- .../ui/pin-macro/cant_access_internals.stderr | 12 -- 7 files changed, 36 insertions(+), 158 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs delete mode 100644 tests/ui/feature-gates/feature-gate-unsafe_pin_internals.stderr delete mode 100644 tests/ui/pin-macro/cant_access_internals.rs delete mode 100644 tests/ui/pin-macro/cant_access_internals.stderr diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d1f3eb16e4e4..4f6e64dc1271 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2215,7 +2215,6 @@ symbols! { unsafe_extern_blocks, unsafe_fields, unsafe_no_drop_flag, - unsafe_pin_internals, unsafe_pinned, unsafe_unpin, unsize, diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 48ed5ae451e4..9e6acf04bf72 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1092,24 +1092,15 @@ pub use self::unsafe_pinned::UnsafePinned; #[rustc_pub_transparent] #[derive(Copy, Clone)] pub struct Pin { - // FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to: - // - deter downstream users from accessing it (which would be unsound!), - // - let the `pin!` macro access it (such a macro requires using struct - // literal syntax in order to benefit from lifetime extension). - // - // However, if the `Deref` impl exposes a field with the same name as this - // field, then the two will collide, resulting in a confusing error when the - // user attempts to access the field through a `Pin`. Therefore, the - // name `__pointer` is designed to be unlikely to collide with any other - // field. Long-term, macro hygiene is expected to offer a more robust - // alternative, alongside `unsafe` fields. - #[unstable(feature = "unsafe_pin_internals", issue = "none")] - #[doc(hidden)] - pub __pointer: Ptr, + /// Only public for bootstrap. + #[cfg(bootstrap)] + pub pointer: Ptr, + #[cfg(not(bootstrap))] + pointer: Ptr, } // The following implementations aren't derived in order to avoid soundness -// issues. `&self.__pointer` should not be accessible to untrusted trait +// issues. `&self.pointer` should not be accessible to untrusted trait // implementations. // // See for more details. @@ -1223,7 +1214,7 @@ impl> Pin { #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const fn into_inner(pin: Pin) -> Ptr { - pin.__pointer + pin.pointer } } @@ -1360,7 +1351,7 @@ impl Pin { #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin { - Pin { __pointer: pointer } + Pin { pointer } } /// Gets a shared reference to the pinned value this [`Pin`] points to. @@ -1374,7 +1365,7 @@ impl Pin { #[inline(always)] pub fn as_ref(&self) -> Pin<&Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&*self.__pointer) } + unsafe { Pin::new_unchecked(&*self.pointer) } } } @@ -1418,7 +1409,7 @@ impl Pin { #[inline(always)] pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&mut *self.__pointer) } + unsafe { Pin::new_unchecked(&mut *self.pointer) } } /// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer. @@ -1485,7 +1476,7 @@ impl Pin { where Ptr::Target: Sized, { - *(self.__pointer) = value; + *(self.pointer) = value; } } @@ -1513,7 +1504,7 @@ impl Pin { #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const unsafe fn into_inner_unchecked(pin: Pin) -> Ptr { - pin.__pointer + pin.pointer } } @@ -1539,7 +1530,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { U: ?Sized, F: FnOnce(&T) -> &U, { - let pointer = &*self.__pointer; + let pointer = &*self.pointer; let new_pointer = func(pointer); // SAFETY: the safety contract for `new_unchecked` must be @@ -1569,7 +1560,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn get_ref(self) -> &'a T { - self.__pointer + self.pointer } } @@ -1580,7 +1571,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn into_ref(self) -> Pin<&'a T> { - Pin { __pointer: self.__pointer } + Pin { pointer: self.pointer } } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1600,7 +1591,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { where T: Unpin, { - self.__pointer + self.pointer } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1618,7 +1609,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[stable(feature = "pin", since = "1.33.0")] #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { - self.__pointer + self.pointer } /// Constructs a new pin by mapping the interior value. @@ -1705,21 +1696,21 @@ impl LegacyReceiver for Pin {} #[stable(feature = "pin", since = "1.33.0")] impl fmt::Debug for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.__pointer, f) + fmt::Debug::fmt(&self.pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl fmt::Display for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.__pointer, f) + fmt::Display::fmt(&self.pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl fmt::Pointer for Pin { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&self.__pointer, f) + fmt::Pointer::fmt(&self.pointer, f) } } @@ -1945,80 +1936,22 @@ unsafe impl PinCoerceUnsized for *mut T {} /// constructor. /// /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin +#[cfg(not(bootstrap))] #[stable(feature = "pin_macro", since = "1.68.0")] #[rustc_macro_transparency = "semitransparent"] -#[allow_internal_unstable(unsafe_pin_internals)] -#[rustc_macro_edition_2021] +#[allow_internal_unstable(super_let)] pub macro pin($value:expr $(,)?) { - // This is `Pin::new_unchecked(&mut { $value })`, so, for starters, let's - // review such a hypothetical macro (that any user-code could define): - // - // ```rust - // macro_rules! pin {( $value:expr ) => ( - // match &mut { $value } { at_value => unsafe { // Do not wrap `$value` in an `unsafe` block. - // $crate::pin::Pin::<&mut _>::new_unchecked(at_value) - // }} - // )} - // ``` - // - // Safety: - // - `type P = &mut _`. There are thus no pathological `Deref{,Mut}` impls - // that would break `Pin`'s invariants. - // - `{ $value }` is braced, making it a _block expression_, thus **moving** - // the given `$value`, and making it _become an **anonymous** temporary_. - // By virtue of being anonymous, it can no longer be accessed, thus - // preventing any attempts to `mem::replace` it or `mem::forget` it, _etc._ - // - // This gives us a `pin!` definition that is sound, and which works, but only - // in certain scenarios: - // - If the `pin!(value)` expression is _directly_ fed to a function call: - // `let poll = pin!(fut).poll(cx);` - // - If the `pin!(value)` expression is part of a scrutinee: - // ```rust - // match pin!(fut) { pinned_fut => { - // pinned_fut.as_mut().poll(...); - // pinned_fut.as_mut().poll(...); - // }} // <- `fut` is dropped here. - // ``` - // Alas, it doesn't work for the more straight-forward use-case: `let` bindings. - // ```rust - // let pinned_fut = pin!(fut); // <- temporary value is freed at the end of this statement - // pinned_fut.poll(...) // error[E0716]: temporary value dropped while borrowed - // // note: consider using a `let` binding to create a longer lived value - // ``` - // - Issues such as this one are the ones motivating https://github.com/rust-lang/rfcs/pull/66 - // - // This makes such a macro incredibly unergonomic in practice, and the reason most macros - // out there had to take the path of being a statement/binding macro (_e.g._, `pin!(future);`) - // instead of featuring the more intuitive ergonomics of an expression macro. - // - // Luckily, there is a way to avoid the problem. Indeed, the problem stems from the fact that a - // temporary is dropped at the end of its enclosing statement when it is part of the parameters - // given to function call, which has precisely been the case with our `Pin::new_unchecked()`! - // For instance, - // ```rust - // let p = Pin::new_unchecked(&mut ); - // ``` - // becomes: - // ```rust - // let p = { let mut anon = ; &mut anon }; - // ``` - // - // However, when using a literal braced struct to construct the value, references to temporaries - // can then be taken. This makes Rust change the lifespan of such temporaries so that they are, - // instead, dropped _at the end of the enscoping block_. - // For instance, - // ```rust - // let p = Pin { __pointer: &mut }; - // ``` - // becomes: - // ```rust - // let mut anon = ; - // let p = Pin { __pointer: &mut anon }; - // ``` - // which is *exactly* what we want. - // - // See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension - // for more info. - $crate::pin::Pin::<&mut _> { __pointer: &mut { $value } } + { + super let mut pinned = $value; + // SAFETY: The value is pinned: it is the local above which cannot be named outside this macro. + unsafe { $crate::pin::Pin::new_unchecked(&mut pinned) } + } +} + +/// Only for bootstrap. +#[cfg(bootstrap)] +#[stable(feature = "pin_macro", since = "1.68.0")] +#[rustc_macro_transparency = "semitransparent"] +pub macro pin($value:expr $(,)?) { + $crate::pin::Pin::<&mut _> { pointer: &mut { $value } } } diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs index bfbfa8d280fa..3174c91a6498 100644 --- a/library/coretests/tests/pin_macro.rs +++ b/library/coretests/tests/pin_macro.rs @@ -38,6 +38,7 @@ fn rust_2024_expr() { } #[test] +#[cfg(not(bootstrap))] fn temp_lifetime() { // Check that temporary lifetimes work as in Rust 2021. // Regression test for https://github.com/rust-lang/rust/issues/138596 diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs deleted file mode 100644 index deb5a2f691b8..000000000000 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ edition:2018 -#![forbid(internal_features, unsafe_code)] -#![feature(unsafe_pin_internals)] -//~^ ERROR the feature `unsafe_pin_internals` is internal to the compiler or standard library - -use core::{marker::PhantomPinned, pin::Pin}; - -/// The `unsafe_pin_internals` is indeed unsound. -fn non_unsafe_pin_new_unchecked(pointer: &mut T) -> Pin<&mut T> { - Pin { __pointer: pointer } -} - -fn main() { - let mut self_referential = PhantomPinned; - let _: Pin<&mut PhantomPinned> = non_unsafe_pin_new_unchecked(&mut self_referential); -} diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.stderr b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.stderr deleted file mode 100644 index fc9bcd90e52e..000000000000 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: the feature `unsafe_pin_internals` is internal to the compiler or standard library - --> $DIR/feature-gate-unsafe_pin_internals.rs:3:12 - | -LL | #![feature(unsafe_pin_internals)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: using it is strongly discouraged -note: the lint level is defined here - --> $DIR/feature-gate-unsafe_pin_internals.rs:2:11 - | -LL | #![forbid(internal_features, unsafe_code)] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/pin-macro/cant_access_internals.rs b/tests/ui/pin-macro/cant_access_internals.rs deleted file mode 100644 index 36a47d0fdf93..000000000000 --- a/tests/ui/pin-macro/cant_access_internals.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ edition:2018 - -use core::{ - marker::PhantomPinned, - mem, - pin::{pin, Pin}, -}; - -fn main() { - let mut phantom_pinned = pin!(PhantomPinned); - mem::take(phantom_pinned.__pointer); //~ ERROR use of unstable library feature `unsafe_pin_internals` -} diff --git a/tests/ui/pin-macro/cant_access_internals.stderr b/tests/ui/pin-macro/cant_access_internals.stderr deleted file mode 100644 index 8ad897bbbb95..000000000000 --- a/tests/ui/pin-macro/cant_access_internals.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: use of unstable library feature `unsafe_pin_internals` - --> $DIR/cant_access_internals.rs:11:15 - | -LL | mem::take(phantom_pinned.__pointer); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(unsafe_pin_internals)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. From d20b270b4e431a010e9149a64e816a9ff2b3dec9 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 28 Mar 2025 09:41:31 +0100 Subject: [PATCH 066/106] Don't name macro internals in "does not live long enough" errors. --- .../src/diagnostics/conflict_errors.rs | 16 +++++++++++----- .../src/diagnostics/explain_borrow.rs | 4 +++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8a8ecc3b96e3..2853ae0239e7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2959,21 +2959,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - let mut err = self.path_does_not_live_long_enough(borrow_span, &format!("`{name}`")); + let name = if borrow_span.in_external_macro(self.infcx.tcx.sess.source_map()) { + // Don't name local variables in external macros. + "value".to_string() + } else { + format!("`{name}`") + }; + + let mut err = self.path_does_not_live_long_enough(borrow_span, &name); if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { let region_name = annotation.emit(self, &mut err); err.span_label( borrow_span, - format!("`{name}` would have to be valid for `{region_name}`..."), + format!("{name} would have to be valid for `{region_name}`..."), ); err.span_label( drop_span, format!( - "...but `{}` will be dropped here, when the {} returns", - name, + "...but {name} will be dropped here, when the {} returns", self.infcx .tcx .opt_item_name(self.mir_def_id().to_def_id()) @@ -3011,7 +3017,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } else { err.span_label(borrow_span, "borrowed value does not live long enough"); - err.span_label(drop_span, format!("`{name}` dropped here while still borrowed")); + err.span_label(drop_span, format!("{name} dropped here while still borrowed")); borrow_spans.args_subdiag(&mut err, |args_span| { crate::session_diagnostics::CaptureArgLabel::Capture { diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index f77dda0d386a..a845431facac 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -95,7 +95,9 @@ impl<'tcx> BorrowExplanation<'tcx> { && let hir::def::Res::Local(hir_id) = p.res && let hir::Node::Pat(pat) = tcx.hir_node(hir_id) { - err.span_label(pat.span, format!("binding `{ident}` declared here")); + if !ident.span.in_external_macro(tcx.sess.source_map()) { + err.span_label(pat.span, format!("binding `{ident}` declared here")); + } } } } From 1ca930098911d5059b810b473941a94185cb29ff Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 27 Mar 2025 18:32:53 +0100 Subject: [PATCH 067/106] Update tests. --- ...ine_coroutine.main.Inline.panic-abort.diff | 2 +- ...ne_coroutine.main.Inline.panic-unwind.diff | 2 +- ...y.run2-{closure#0}.Inline.panic-abort.diff | 6 +++--- ....run2-{closure#0}.Inline.panic-unwind.diff | 6 +++--- tests/pretty/postfix-yield.rs | 3 ++- .../pin-ergonomics/reborrow-once.stderr | 2 +- tests/ui/coroutine/postfix-yield.rs | 2 +- .../lifetime_errors_on_promotion_misusage.rs | 4 ++-- ...fetime_errors_on_promotion_misusage.stderr | 20 +++++++------------ tests/ui/pin-macro/pin_move.stderr | 5 +++++ 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 56d4d50e967e..151580da19e0 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -33,7 +33,7 @@ - _4 = g() -> [return: bb1, unwind unreachable]; + _4 = {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { __pointer: copy _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { pointer: copy _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index 751916a00f14..6196fc0d0c6b 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -33,7 +33,7 @@ - _4 = g() -> [return: bb1, unwind continue]; + _4 = {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { __pointer: copy _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { pointer: copy _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index e49d7cea28e5..1e9a6dd4f5c8 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -121,7 +121,7 @@ - } - - bb2: { -+ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { __pointer: copy _5 }; ++ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { pointer: copy _5 }; StorageDead(_5); StorageLive(_6); StorageLive(_7); @@ -218,7 +218,7 @@ + _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); -+ _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 }; ++ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 }; + StorageDead(_20); + StorageLive(_22); + StorageLive(_23); @@ -239,7 +239,7 @@ + _48 = &mut (_19.0: &mut std::future::Ready<()>); + _45 = copy (_19.0: &mut std::future::Ready<()>); + StorageDead(_48); -+ _47 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _45 }; ++ _47 = Pin::<&mut std::future::Ready<()>> { pointer: copy _45 }; + StorageDead(_47); + _44 = &mut ((*_45).0: std::option::Option<()>); + StorageLive(_49); diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index e7aed556f2d7..94b89a310baa 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -123,7 +123,7 @@ - } - - bb2: { -+ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { __pointer: copy _5 }; ++ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { pointer: copy _5 }; StorageDead(_5); StorageLive(_6); StorageLive(_7); @@ -235,7 +235,7 @@ + _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); -+ _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 }; ++ _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 }; + StorageDead(_20); + StorageLive(_22); + StorageLive(_23); @@ -256,7 +256,7 @@ + _50 = &mut (_19.0: &mut std::future::Ready<()>); + _47 = copy (_19.0: &mut std::future::Ready<()>); + StorageDead(_50); -+ _49 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _47 }; ++ _49 = Pin::<&mut std::future::Ready<()>> { pointer: copy _47 }; + StorageDead(_49); + _46 = &mut ((*_47).0: std::option::Option<()>); + StorageLive(_51); diff --git a/tests/pretty/postfix-yield.rs b/tests/pretty/postfix-yield.rs index f76e8142ae86..60380a4071c5 100644 --- a/tests/pretty/postfix-yield.rs +++ b/tests/pretty/postfix-yield.rs @@ -2,7 +2,8 @@ //@ edition: 2024 //@ pp-exact -#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)] +#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr, +stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::pin; diff --git a/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr b/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr index a1ea2b4a57a7..dc8e424ad2a4 100644 --- a/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr +++ b/tests/ui/async-await/pin-ergonomics/reborrow-once.stderr @@ -1,4 +1,4 @@ -error[E0499]: cannot borrow `*x.__pointer` as mutable more than once at a time +error[E0499]: cannot borrow `*x.pointer` as mutable more than once at a time --> $DIR/reborrow-once.rs:12:14 | LL | twice(x, x); diff --git a/tests/ui/coroutine/postfix-yield.rs b/tests/ui/coroutine/postfix-yield.rs index ff843138c8c2..f2fdcebdaa9a 100644 --- a/tests/ui/coroutine/postfix-yield.rs +++ b/tests/ui/coroutine/postfix-yield.rs @@ -3,7 +3,7 @@ //@ run-pass //@ edition: 2024 -#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)] +#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::pin; diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs index 8a0244e8145a..e505fe435207 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs @@ -9,14 +9,14 @@ use core::{ fn function_call_stops_borrow_extension() { let phantom_pinned = identity(pin!(PhantomPinned)); - //~^ ERROR temporary value dropped while borrowed + //~^ ERROR does not live long enough stuff(phantom_pinned) } fn promotion_only_works_for_the_innermost_block() { let phantom_pinned = { let phantom_pinned = pin!(PhantomPinned); - //~^ ERROR temporary value dropped while borrowed + //~^ ERROR does not live long enough phantom_pinned }; stuff(phantom_pinned) diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr index 9df7f0ffd0c3..43fb82be7c2f 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr @@ -1,35 +1,29 @@ -error[E0716]: temporary value dropped while borrowed +error[E0597]: value does not live long enough --> $DIR/lifetime_errors_on_promotion_misusage.rs:11:35 | LL | let phantom_pinned = identity(pin!(PhantomPinned)); - | ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | ^^^^^^^^^^^^^^^^^^^ - value dropped here while still borrowed | | - | creates a temporary value which is freed while still in use + | borrowed value does not live long enough LL | LL | stuff(phantom_pinned) | -------------- borrow later used here | = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider using a `let` binding to create a longer lived value - | -LL ~ let binding = pin!(PhantomPinned); -LL ~ let phantom_pinned = identity(binding); - | -error[E0716]: temporary value dropped while borrowed +error[E0597]: value does not live long enough --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30 | LL | let phantom_pinned = { | -------------- borrow later stored here LL | let phantom_pinned = pin!(PhantomPinned); - | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use + | ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough ... LL | }; - | - temporary value is freed at the end of this statement + | - value dropped here while still borrowed | - = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0716`. +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/pin-macro/pin_move.stderr b/tests/ui/pin-macro/pin_move.stderr index c9b8ad9b2021..3f4660209885 100644 --- a/tests/ui/pin-macro/pin_move.stderr +++ b/tests/ui/pin-macro/pin_move.stderr @@ -31,6 +31,11 @@ LL | struct NotCopy(T); LL | let mut pointee = NotCopy(PhantomPinned); LL | pin!(*&mut pointee); | ------------- you could clone this value +help: consider removing the dereference here + | +LL - pin!(*&mut pointee); +LL + pin!(&mut pointee); + | error: aborting due to 2 previous errors From 2f0ba6791944fbbc9236ea4138389039ebbffd4a Mon Sep 17 00:00:00 2001 From: Lyndon Brown Date: Wed, 16 Apr 2025 14:42:11 +0100 Subject: [PATCH 068/106] fix incorrect type in cstr `to_string_lossy()` docs Restoring what it said prior to commit 67065fe in which it was changed incorrectly with no supporting explanation. Closes #139835. --- library/alloc/src/ffi/c_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index f6743c657109..ef8548d24293 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -1116,7 +1116,7 @@ impl CStr { /// with the corresponding &[str] slice. Otherwise, it will /// replace any invalid UTF-8 sequences with /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a - /// [Cow]::[Owned]\(&[str]) with the result. + /// [Cow]::[Owned]\([String]) with the result. /// /// [str]: prim@str "str" /// [Borrowed]: Cow::Borrowed From 5a38550a39a99b1cd98f9be769e4f1face3d1256 Mon Sep 17 00:00:00 2001 From: Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Date: Wed, 2 Apr 2025 20:33:37 -0400 Subject: [PATCH 069/106] Deduplicate nix code And clean it up a little. --- src/tools/nix-dev-shell/flake.nix | 46 +++++++--------- src/tools/nix-dev-shell/shell.nix | 38 +++++++------ src/tools/nix-dev-shell/x/default.nix | 77 ++++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 50 deletions(-) diff --git a/src/tools/nix-dev-shell/flake.nix b/src/tools/nix-dev-shell/flake.nix index 1b838bd2f7b3..b8287de5fcf0 100644 --- a/src/tools/nix-dev-shell/flake.nix +++ b/src/tools/nix-dev-shell/flake.nix @@ -1,32 +1,24 @@ { description = "rustc dev shell"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - outputs = { self, nixpkgs, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - x = import ./x { inherit pkgs; }; - in - { - devShells.default = with pkgs; mkShell { - name = "rustc-dev-shell"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1`. - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; - }; - } - ); + outputs = + { + self, + nixpkgs, + }: + let + inherit (nixpkgs) lib; + forEachSystem = lib.genAttrs lib.systems.flakeExposed; + in + { + devShells = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./shell.nix { }; + }); + + packages = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./x { }; + }); + }; } diff --git a/src/tools/nix-dev-shell/shell.nix b/src/tools/nix-dev-shell/shell.nix index a3f5969bd812..0adbacf7e8d5 100644 --- a/src/tools/nix-dev-shell/shell.nix +++ b/src/tools/nix-dev-shell/shell.nix @@ -1,18 +1,26 @@ -{ pkgs ? import {} }: -let - x = import ./x { inherit pkgs; }; +{ + pkgs ? import { }, +}: +let + inherit (pkgs.lib) lists attrsets; + + x = pkgs.callPackage ./x { }; + inherit (x.passthru) cacert env; in pkgs.mkShell { - name = "rustc"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1` - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; + name = "rustc-shell"; + + inputsFrom = [ x ]; + packages = [ + pkgs.git + pkgs.nix + x + # Get the runtime deps of the x wrapper + ] ++ lists.flatten (attrsets.attrValues env); + + env = { + # Avoid creating text files for ICEs. + RUSTC_ICE = 0; + SSL_CERT_FILE = cacert; + }; } diff --git a/src/tools/nix-dev-shell/x/default.nix b/src/tools/nix-dev-shell/x/default.nix index e6dfbad6f19c..422c1c4a2aed 100644 --- a/src/tools/nix-dev-shell/x/default.nix +++ b/src/tools/nix-dev-shell/x/default.nix @@ -1,22 +1,83 @@ { - pkgs ? import { }, + pkgs, + lib, + stdenv, + rustc, + python3, + makeBinaryWrapper, + # Bootstrap + curl, + pkg-config, + libiconv, + openssl, + patchelf, + cacert, + zlib, + # LLVM Deps + ninja, + cmake, + glibc, }: -pkgs.stdenv.mkDerivation { - name = "x"; +stdenv.mkDerivation (self: { + strictDeps = true; + name = "x-none"; + + outputs = [ + "out" + "unwrapped" + ]; src = ./x.rs; dontUnpack = true; - nativeBuildInputs = with pkgs; [ rustc ]; + nativeBuildInputs = [ + rustc + makeBinaryWrapper + ]; + env.PYTHON = python3.interpreter; buildPhase = '' - PYTHON=${pkgs.lib.getExe pkgs.python3} rustc -Copt-level=3 --crate-name x $src --out-dir $out/bin + rustc -Copt-level=3 --crate-name x $src --out-dir $unwrapped/bin ''; - meta = with pkgs.lib; { + installPhase = + let + inherit (self.passthru) cacert env; + in + '' + makeWrapper $unwrapped/bin/x $out/bin/x \ + --set-default SSL_CERT_FILE ${cacert} \ + --prefix CPATH ";" "${lib.makeSearchPath "include" env.cpath}" \ + --prefix PATH : ${lib.makeBinPath env.path} \ + --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath env.ldLib} + ''; + + # For accessing them in the devshell + passthru = { + env = { + cpath = [ libiconv ]; + path = [ + python3 + patchelf + curl + pkg-config + cmake + ninja + stdenv.cc + ]; + ldLib = [ + openssl + zlib + stdenv.cc.cc.lib + ]; + }; + cacert = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + }; + + meta = { description = "Helper for rust-lang/rust x.py"; homepage = "https://github.com/rust-lang/rust/blob/master/src/tools/x"; - license = licenses.mit; + license = lib.licenses.mit; mainProgram = "x"; }; -} +}) From c1d21003bb6d9f1f1bd3f0e5f6edc453c602dcad Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 17 Apr 2025 08:34:54 -0400 Subject: [PATCH 070/106] Update to nightly-2025-04-17 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 940b3de9f745..fd898c59707b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-01-12" +channel = "nightly-2025-04-17" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From cc81c706e460c2d8a97a7006664136b62fd2c59e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 09:22:28 -0400 Subject: [PATCH 071/106] Fix patches --- ...022-core-Disable-not-compiling-tests.patch | 44 ------------------- ...0028-core-Disable-long-running-tests.patch | 26 +++++------ 2 files changed, 13 insertions(+), 57 deletions(-) delete mode 100644 patches/0022-core-Disable-not-compiling-tests.patch diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch deleted file mode 100644 index 70e3e2ba7fee..000000000000 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ /dev/null @@ -1,44 +0,0 @@ -From af0e237f056fa838c77463381a19b0dc993c0a35 Mon Sep 17 00:00:00 2001 -From: None -Date: Sun, 1 Sep 2024 11:42:17 -0400 -Subject: [PATCH] Disable not compiling tests - ---- - library/core/tests/Cargo.toml | 14 ++++++++++++++ - library/core/tests/lib.rs | 1 + - 2 files changed, 15 insertions(+) - create mode 100644 library/core/tests/Cargo.toml - -diff --git a/library/core/tests/Cargo.toml b/library/core/tests/Cargo.toml -new file mode 100644 -index 0000000..ca326ac ---- /dev/null -+++ b/library/core/tests/Cargo.toml -@@ -0,0 +1,14 @@ -+[workspace] -+ -+[package] -+name = "coretests" -+version = "0.0.0" -+edition = "2021" -+ -+[lib] -+name = "coretests" -+path = "lib.rs" -+ -+[dependencies] -+rand = { version = "0.8.5", default-features = false } -+rand_xorshift = { version = "0.3.0", default-features = false } -diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index a4a7946..ecfe43f 100644 ---- a/library/core/tests/lib.rs -+++ b/library/core/tests/lib.rs -@@ -1,4 +1,5 @@ - // tidy-alphabetical-start -+#![cfg(test)] - #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] - #![cfg_attr(test, feature(cfg_match))] - #![feature(alloc_layout_extra)] --- -2.47.1 - diff --git a/patches/0028-core-Disable-long-running-tests.patch b/patches/0028-core-Disable-long-running-tests.patch index dc1beae6d2e7..20df4245cfdf 100644 --- a/patches/0028-core-Disable-long-running-tests.patch +++ b/patches/0028-core-Disable-long-running-tests.patch @@ -1,17 +1,17 @@ -From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001 -From: bjorn3 -Date: Fri, 3 Dec 2021 12:16:30 +0100 +From ec2d0dc77fb484d926b45bb626b0db6a4bb0ab5c Mon Sep 17 00:00:00 2001 +From: None +Date: Thu, 27 Mar 2025 09:20:41 -0400 Subject: [PATCH] Disable long running tests --- - library/core/tests/slice.rs | 2 ++ + library/coretests/tests/slice.rs | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs -index 8402833..84592e0 100644 ---- a/library/core/tests/slice.rs -+++ b/library/core/tests/slice.rs -@@ -2462,6 +2462,7 @@ take_tests! { +diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs +index d17e681..fba5cd6 100644 +--- a/library/coretests/tests/slice.rs ++++ b/library/coretests/tests/slice.rs +@@ -2486,6 +2486,7 @@ split_off_tests! { #[cfg(not(miri))] // unused in Miri const EMPTY_MAX: &'static [()] = &[(); usize::MAX]; @@ -19,14 +19,14 @@ index 8402833..84592e0 100644 // can't be a constant due to const mutability rules #[cfg(not(miri))] // unused in Miri macro_rules! empty_max_mut { -@@ -2485,6 +2486,7 @@ take_tests! { - (take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), - (take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), +@@ -2509,6 +2510,7 @@ split_off_tests! { + (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), + (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), } +*/ #[test] fn test_slice_from_ptr_range() { -- -2.26.2.7.g19db9cfb68 +2.49.0 From be75a58538154cbe901efea7807d7830d3d064c4 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 13 Apr 2025 07:48:56 -0400 Subject: [PATCH 072/106] Fix compilation --- src/abi.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index 1f522f64c9cf..3b0ab9f00426 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; -use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; #[cfg(feature = "master")] use rustc_target::callconv::Conv; @@ -239,7 +239,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } #[cfg(feature = "master")] -pub fn conv_to_fn_attribute<'gcc>(conv: Conv, _arch: &str) -> Option> { +pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option> { // TODO: handle the calling conventions returning None. let attribute = match conv { Conv::C @@ -250,20 +250,19 @@ pub fn conv_to_fn_attribute<'gcc>(conv: Conv, _arch: &str) -> Option return None, Conv::PreserveMost => return None, Conv::PreserveAll => return None, - /*Conv::GpuKernel => { + Conv::GpuKernel => { if arch == "amdgpu" { return None } else if arch == "nvptx64" { return None } else { - panic!("Architecture {arch} does not support GpuKernel calling convention"); + panic!("Architecture {} does not support GpuKernel calling convention", arch); } - }*/ + } Conv::AvrInterrupt => return None, Conv::AvrNonBlockingInterrupt => return None, Conv::ArmAapcs => return None, Conv::Msp430Intr => return None, - Conv::PtxKernel => return None, Conv::X86Fastcall => return None, Conv::X86Intr => return None, Conv::X86Stdcall => return None, From 5c832e5ece3c55295bbc8c9f58962a2a57e75147 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 14:28:56 -0400 Subject: [PATCH 073/106] Remove most of builtins hack since it's not necessary anymore --- src/context.rs | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/context.rs b/src/context.rs index 964f1f265591..73718994e641 100644 --- a/src/context.rs +++ b/src/context.rs @@ -215,33 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let bool_type = context.new_type::(); let mut functions = FxHashMap::default(); - let builtins = [ - "__builtin_unreachable", - "abort", - "__builtin_expect", /*"__builtin_expect_with_probability",*/ - "__builtin_constant_p", - "__builtin_add_overflow", - "__builtin_mul_overflow", - "__builtin_saddll_overflow", - /*"__builtin_sadd_overflow",*/ - "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ - "__builtin_ssubll_overflow", - /*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow", - "__builtin_uaddll_overflow", - "__builtin_uadd_overflow", - "__builtin_umulll_overflow", - "__builtin_umul_overflow", - "__builtin_usubll_overflow", - "__builtin_usub_overflow", - "__builtin_powif", - "__builtin_powi", - "fabsf", - "fabs", - "copysignf", - "copysign", - "nearbyintf", - "nearbyint", - ]; + let builtins = ["abort"]; for builtin in builtins.iter() { functions.insert(builtin.to_string(), context.get_builtin_function(builtin)); From e1fa74b4a9ed699d0abf3c98113b3cc11baa81d6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 12:14:14 -0400 Subject: [PATCH 074/106] Implement copysignf128 --- src/intrinsic/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index f38622074f18..d22f4229e237 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -78,6 +78,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::maxnumf64 => "fmax", sym::copysignf32 => "copysignf", sym::copysignf64 => "copysign", + sym::copysignf128 => "copysignl", sym::floorf32 => "floorf", sym::floorf64 => "floor", sym::ceilf32 => "ceilf", From 9a453d46f42c40b91d004064a4cc12f7c28c7fc7 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 14:33:03 -0400 Subject: [PATCH 075/106] Update other patches --- ...001-Disable-libstd-and-libtest-dylib.patch | 18 ++++++----- ...0001-core-Disable-portable-simd-test.patch | 32 ++++++++----------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch index c220f53040f0..fa360fe9e74e 100644 --- a/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch +++ b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch @@ -1,19 +1,18 @@ -From 966beefe08be6045bfcca26079b76a7a80413080 Mon Sep 17 00:00:00 2001 +From b2911e732d1bf0e28872495c4c47af1dad3c7911 Mon Sep 17 00:00:00 2001 From: None -Date: Thu, 28 Sep 2023 17:37:38 -0400 +Date: Thu, 27 Mar 2025 14:30:10 -0400 Subject: [PATCH] Disable libstd and libtest dylib --- - library/std/Cargo.toml | 2 +- - library/test/Cargo.toml | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + library/std/Cargo.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml -index 5b21355..cb0c49b 100644 +index 176da60..c183cdb 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml -@@ -9,7 +9,7 @@ description = "The Rust Standard Library" - edition = "2021" +@@ -10,7 +10,7 @@ edition = "2024" + autobenches = false [lib] -crate-type = ["dylib", "rlib"] @@ -21,3 +20,6 @@ index 5b21355..cb0c49b 100644 [dependencies] alloc = { path = "../alloc", public = true } +-- +2.49.0 + diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 9ef5e0e4f467..9d5b2dc537d2 100644 --- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -1,25 +1,17 @@ -From 124a11ce086952a5794d5cfbaa45175809497b81 Mon Sep 17 00:00:00 2001 +From 1a8f6b8e39f343959d4d2e6b6957a6d780ac3fc0 Mon Sep 17 00:00:00 2001 From: None -Date: Sat, 18 Nov 2023 10:50:36 -0500 -Subject: [PATCH] [core] Disable portable-simd test +Date: Thu, 27 Mar 2025 14:32:14 -0400 +Subject: [PATCH] Disable portable-simd test --- - library/core/tests/lib.rs | 2 -- - 1 file changed, 2 deletions(-) + library/coretests/tests/lib.rs | 1 - + 1 file changed, 1 deletion(-) -diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index b71786c..cf484d5 100644 ---- a/library/core/tests/lib.rs -+++ b/library/core/tests/lib.rs -@@ -87,7 +87,6 @@ - #![feature(numfmt)] - #![feature(pattern)] - #![feature(pointer_is_aligned_to)] --#![feature(portable_simd)] - #![feature(ptr_metadata)] - #![feature(slice_from_ptr_range)] - #![feature(slice_internals)] -@@ -155,7 +154,6 @@ mod pin; +diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs +index 79022fe..9223b2f 100644 +--- a/library/coretests/tests/lib.rs ++++ b/library/coretests/tests/lib.rs +@@ -165,7 +165,6 @@ mod pin; mod pin_macro; mod ptr; mod result; @@ -27,4 +19,6 @@ index b71786c..cf484d5 100644 mod slice; mod str; mod str_lossy; --- 2.45.2 +-- +2.49.0 + From f9822772e8781ed30a89aa4494e47c42b4397133 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 14:33:38 -0400 Subject: [PATCH 076/106] Fix libcore tests --- build_system/src/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 297cd7d71316..df4ac85233b0 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -678,7 +678,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[TEST] libcore"); - let path = get_sysroot_dir().join("sysroot_src/library/core/tests"); + let path = get_sysroot_dir().join("sysroot_src/library/coretests"); let _ = remove_dir_all(path.join("target")); run_cargo_command(&[&"test"], Some(&path), env, args)?; Ok(()) From 5cf2bbc4e2c82961f2e82fbacc39fcf5f332e371 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 14:34:44 -0400 Subject: [PATCH 077/106] Fix clippy warnings --- src/abi.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/abi.rs b/src/abi.rs index 3b0ab9f00426..6fdb03fb85b5 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -251,6 +251,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option return None, Conv::PreserveAll => return None, Conv::GpuKernel => { + // TODO(antoyo): remove clippy allow attribute when this is implemented. + #[allow(clippy::if_same_then_else)] if arch == "amdgpu" { return None } else if arch == "nvptx64" { From ecf0a1eea3714a9c9f79bf1f3a53e6feb6c631f5 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 13 Apr 2025 08:28:02 -0400 Subject: [PATCH 078/106] Update GCC version --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index dfdc222c00fc..125b04004b07 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -d6f5a708104a98199ac0f01a3b6b279a0f7c66d3 +0ea98a1365b81f7488073512c850e8ee951a4afd From ec44cfdfb4a74d19f522984e2e2e226a3b76df9a Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 15:28:31 -0400 Subject: [PATCH 079/106] Fix tests --- example/mini_core.rs | 16 ++++++++++++++++ tests/run/abort1.rs | 2 +- tests/run/abort2.rs | 2 +- tests/run/assign.rs | 2 +- tests/run/closure.rs | 2 +- tests/run/mut_ref.rs | 2 +- tests/run/static.rs | 2 +- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 32501530cfac..c554a87b8256 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -138,6 +138,14 @@ impl Mul for u8 { } } +impl Mul for i32 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + impl Mul for usize { type Output = Self; @@ -248,6 +256,14 @@ impl Sub for i16 { } } +impl Sub for i32 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + #[lang = "rem"] pub trait Rem { type Output; diff --git a/tests/run/abort1.rs b/tests/run/abort1.rs index ae7e457d1cd3..ff2bb75ece22 100644 --- a/tests/run/abort1.rs +++ b/tests/run/abort1.rs @@ -3,7 +3,7 @@ // Run-time: // status: signal -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] #![no_main] diff --git a/tests/run/abort2.rs b/tests/run/abort2.rs index 28fad0107f75..781f518e0b22 100644 --- a/tests/run/abort2.rs +++ b/tests/run/abort2.rs @@ -3,7 +3,7 @@ // Run-time: // status: signal -#![feature(no_core, start)] +#![feature(no_core)] #![no_std] #![no_core] #![no_main] diff --git a/tests/run/assign.rs b/tests/run/assign.rs index a54d0b20def3..4535ab5778e9 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -23,7 +23,7 @@ fn inc(num: isize) -> isize { } #[no_mangle] -extern "C" fn main(mut argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 { argc = inc(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); diff --git a/tests/run/closure.rs b/tests/run/closure.rs index b827a2614002..a8a3fadfed47 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -17,7 +17,7 @@ extern crate mini_core; use mini_core::*; #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 { let string = "Arg: %d\n\0"; let mut closure = || unsafe { libc::printf(string as *const str as *const i8, argc); diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index 5fa5df751a32..fa50d5bc5d3d 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -27,7 +27,7 @@ fn update_num(num: &mut isize) { } #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 { let mut test = test(argc); unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); diff --git a/tests/run/static.rs b/tests/run/static.rs index c58151f8417b..1e36cf4f3d31 100644 --- a/tests/run/static.rs +++ b/tests/run/static.rs @@ -34,7 +34,7 @@ static mut TEST2: Test = Test { field: 14 }; static mut WITH_REF: WithRef = WithRef { refe: unsafe { &TEST } }; #[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { +extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 { unsafe { libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT); libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field); From bc0bc8d5e1a1a38ee5a342e614e490e490bc5604 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 27 Mar 2025 15:36:15 -0400 Subject: [PATCH 080/106] Fix int_to_float_cast for f128 --- src/int.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/int.rs b/src/int.rs index f3552d9b12fc..b5fcb534747d 100644 --- a/src/int.rs +++ b/src/int.rs @@ -905,6 +905,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let name_suffix = match self.type_kind(dest_typ) { TypeKind::Float => "tisf", TypeKind::Double => "tidf", + TypeKind::FP128 => "tixf", kind => panic!("cannot cast a non-native integer to type {:?}", kind), }; let sign = if signed { "" } else { "un" }; From 6504f4c09ce9e3c72084e647fab8e6565d79573e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 13 Apr 2025 08:40:42 -0400 Subject: [PATCH 081/106] Format --- src/abi.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index 6fdb03fb85b5..a96b18e01c08 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -9,9 +9,9 @@ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; -use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; #[cfg(feature = "master")] use rustc_target::callconv::Conv; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -254,9 +254,9 @@ pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option Date: Sun, 13 Apr 2025 08:58:32 -0400 Subject: [PATCH 082/106] Fix tests --- tests/failing-ui-tests.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 0babc748f98b..12dc7f726aab 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -31,7 +31,6 @@ tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/consts/missing_span_in_backtrace.rs tests/ui/drop/dynamic-drop.rs -tests/ui/issues/issue-40883.rs tests/ui/issues/issue-43853.rs tests/ui/issues/issue-47364.rs tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs @@ -100,14 +99,12 @@ tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs -tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs -tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs @@ -115,8 +112,8 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs -tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs tests/ui/simd/simd-bitmask-notpow2.rs +tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs From 0d773175cc41901f1a558a9b45239c67c3fa0df6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 13 Apr 2025 10:25:10 -0400 Subject: [PATCH 083/106] Add support for simd_insert_dyn and simd_extract_dyn --- src/intrinsic/simd.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 8b454ab2a424..6d40d5297f1a 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -399,7 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - if name == sym::simd_insert { + if name == sym::simd_insert || name == sym::simd_insert_dyn { require!( in_elem == arg_tys[2], InvalidMonomorphization::InsertedType { @@ -410,6 +410,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( out_ty: arg_tys[2] } ); + + // TODO(antoyo): For simd_insert, check if the index is a constant of the correct size. let vector = args[0].immediate(); let index = args[1].immediate(); let value = args[2].immediate(); @@ -422,13 +424,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - if name == sym::simd_extract { + if name == sym::simd_extract || name == sym::simd_extract_dyn { require!( ret_ty == in_elem, InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); + // TODO(antoyo): For simd_extract, check if the index is a constant of the correct size. let vector = args[0].immediate(); - return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); + let index = args[1].immediate(); + return Ok(bx.context.new_vector_access(None, vector, index).to_rvalue()); } if name == sym::simd_select { From 4b5940ad77cf9a95cf78bef1ecc6fa84ef1fc0ce Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 15 Apr 2025 12:51:28 -0400 Subject: [PATCH 084/106] Fix overflow operations --- src/int.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/int.rs b/src/int.rs index b5fcb534747d..9b5b0fde6e2f 100644 --- a/src/int.rs +++ b/src/int.rs @@ -404,7 +404,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); - let result = if ret_indirect { + let call = if ret_indirect { let res_value = self.current_func().new_local(self.location, res_type, "result_value"); let res_addr = res_value.get_address(self.location); let res_param_type = res_type.make_pointer(); @@ -432,8 +432,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { ); self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr]) }; + // NOTE: we must assign the result of the operation to a variable at this point to make + // sure it will be evaluated by libgccjit now. + // Otherwise, it will only be evaluated when the rvalue for the call is used somewhere else + // and overflow_value will not be initialized at the correct point in the program. + let result = self.current_func().new_local(self.location, res_type, "result"); + self.block.add_assignment(self.location, result, call); - (result, self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue()) + ( + result.to_rvalue(), + self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue(), + ) } pub fn gcc_icmp( @@ -865,6 +874,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let value_type = value.get_type(); if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type) { + // TODO: use self.location. self.context.new_cast(None, value, dest_typ) } else if self.is_native_int_type_or_bool(dest_typ) { self.context.new_cast(None, self.low(value), dest_typ) From 06af88e06cd464809bbe3c2ab073d2d575d185e6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 15 Apr 2025 13:28:27 -0400 Subject: [PATCH 085/106] Add new failing test --- tests/failing-ui-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 12dc7f726aab..499c1a962311 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -117,3 +117,4 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs tests/ui/simd/simd-bitmask-notpow2.rs tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs +tests/ui/uninhabited/uninhabited-transparent-return-abi.rs From 5523c87c41b357fe3c3047dabf603f18830eeaf8 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Apr 2025 21:16:58 +0200 Subject: [PATCH 086/106] Update libcore.natvis for Pin. --- src/etc/natvis/libcore.natvis | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 8a441cf20935..8fe87a999895 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -69,9 +69,9 @@ - Pin({(void*)__pointer}: {__pointer}) + Pin({(void*)pointer}: {pointer}) - __pointer + pointer From 136171c8d8c81ff8de4446fb4bb339a1bd475a49 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 18 Apr 2025 00:58:04 -0400 Subject: [PATCH 087/106] skip llvm-config in autodiff check builds, when its unavailable --- src/bootstrap/src/core/build_steps/compile.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index dab58fccf5e6..106a04de5d9a 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1194,8 +1194,7 @@ pub fn rustc_cargo( let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib"); cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path")); - if !builder.config.dry_run() { - let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + if let Some(llvm_config) = builder.llvm_config(builder.config.build) { let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); } From 1b393025718ca9c75d67e82b55a390e3506e536c Mon Sep 17 00:00:00 2001 From: roblabla Date: Fri, 18 Apr 2025 13:30:26 +0200 Subject: [PATCH 088/106] Disable has_thread_local on i686-win7-windows-msvc On Windows 7 32-bit, the alignment characteristic of the TLS Directory don't appear to be respected by the PE Loader, leading to crashes. As a result, let's disable has_thread_local to make sure TLS goes through the emulation layer. --- .../rustc_target/src/spec/targets/i686_win7_windows_msvc.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs index 233a1c4fd7a5..91ab31110978 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs @@ -7,6 +7,12 @@ pub(crate) fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; + // On Windows 7 32-bit, the alignment characteristic of the TLS Directory + // don't appear to be respected by the PE Loader, leading to crashes. As + // a result, let's disable has_thread_local to make sure TLS goes through + // the emulation layer. + // See https://github.com/rust-lang/rust/issues/138903 + base.has_thread_local = false; base.add_pre_link_args( LinkerFlavor::Msvc(Lld::No), From 8f6ef1f1f6a4fcec0325e4ff6fa50b8f42f853aa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 13:35:49 +0200 Subject: [PATCH 089/106] Improve `clean_maybe_renamed_item` function code a bit --- src/librustdoc/clean/mod.rs | 47 ++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fe9dc9a9e214..a693d9f8564e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2797,10 +2797,35 @@ fn clean_maybe_renamed_item<'tcx>( ) -> Vec { use hir::ItemKind; - let def_id = item.owner_id.to_def_id(); - let mut name = if renamed.is_some() { renamed } else { cx.tcx.hir_opt_name(item.hir_id()) }; + fn get_name( + cx: &DocContext<'_>, + item: &hir::Item<'_>, + renamed: Option, + ) -> Option { + renamed.or_else(|| cx.tcx.hir_opt_name(item.hir_id())) + } + let def_id = item.owner_id.to_def_id(); cx.with_param_env(def_id, |cx| { + // These kinds of item either don't need a `name` or accept a `None` one so we handle them + // before. + match item.kind { + ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), + ItemKind::Use(path, kind) => { + return clean_use_statement( + item, + get_name(cx, item, renamed), + path, + kind, + cx, + &mut FxHashSet::default(), + ); + } + _ => {} + } + + let mut name = get_name(cx, item, renamed).unwrap(); + let kind = match item.kind { ItemKind::Static(_, ty, mutability, body_id) => StaticItem(Static { type_: Box::new(clean_ty(ty, cx)), @@ -2839,7 +2864,7 @@ fn clean_maybe_renamed_item<'tcx>( item_type: Some(type_), })), item.owner_id.def_id.to_def_id(), - name.unwrap(), + name, import_id, renamed, )); @@ -2862,17 +2887,14 @@ fn clean_maybe_renamed_item<'tcx>( generics: clean_generics(generics, cx), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), - ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro { - source: display_macro_source(cx, name.unwrap(), macro_def), + source: display_macro_source(cx, name, macro_def), macro_rules: macro_def.macro_rules, }), - ItemKind::Macro(_, _, macro_kind) => { - clean_proc_macro(item, name.as_mut().unwrap(), macro_kind, cx) - } + ItemKind::Macro(_, _, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), // proc macros can have a name set by attributes ItemKind::Fn { ref sig, generics, body: body_id, .. } => { - clean_fn_or_proc_macro(item, sig, generics, body_id, name.as_mut().unwrap(), cx) + clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } ItemKind::Trait(_, _, _, generics, bounds, item_ids) => { let items = item_ids @@ -2888,10 +2910,7 @@ fn clean_maybe_renamed_item<'tcx>( })) } ItemKind::ExternCrate(orig_name, _) => { - return clean_extern_crate(item, name.unwrap(), orig_name, cx); - } - ItemKind::Use(path, kind) => { - return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default()); + return clean_extern_crate(item, name, orig_name, cx); } _ => span_bug!(item.span, "not yet converted"), }; @@ -2900,7 +2919,7 @@ fn clean_maybe_renamed_item<'tcx>( cx, kind, item.owner_id.def_id.to_def_id(), - name.unwrap(), + name, import_id, renamed, )] From 65b87aae21096c0f22d141ceaf7030ebdf6edbe4 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 17 Apr 2025 15:05:06 -0400 Subject: [PATCH 090/106] Support new target builtins --- src/intrinsic/llvm.rs | 245 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 1 deletion(-) diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 2b172cdfed3a..e030e3b4ff28 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1,11 +1,86 @@ use std::borrow::Cow; -use gccjit::{CType, Context, Function, FunctionPtrType, RValue, ToRValue}; +use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue, Type}; use rustc_codegen_ssa::traits::BuilderMethods; use crate::builder::Builder; use crate::context::CodegenCx; +fn encode_key_128_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u32_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let encode_type = builder.context.new_struct_type( + None, + "EncodeKey128Output", + &[field1, field2, field3, field4, field5, field6, field7], + ); + encode_type.as_type().set_packed(); + (encode_type.as_type(), field1, field2) +} + +fn encode_key_256_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u32_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let field8 = builder.context.new_field(None, m128i, "field8"); + let encode_type = builder.context.new_struct_type( + None, + "EncodeKey256Output", + &[field1, field2, field3, field4, field5, field6, field7, field8], + ); + encode_type.as_type().set_packed(); + (encode_type.as_type(), field1, field2) +} + +fn aes_output_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u8_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let aes_output_type = builder.context.new_struct_type(None, "AesOutput", &[field1, field2]); + let typ = aes_output_type.as_type(); + typ.set_packed(); + (typ, field1, field2) +} + +fn wide_aes_output_type<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, +) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) { + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let field1 = builder.context.new_field(None, builder.u8_type, "field1"); + let field2 = builder.context.new_field(None, m128i, "field2"); + let field3 = builder.context.new_field(None, m128i, "field3"); + let field4 = builder.context.new_field(None, m128i, "field4"); + let field5 = builder.context.new_field(None, m128i, "field5"); + let field6 = builder.context.new_field(None, m128i, "field6"); + let field7 = builder.context.new_field(None, m128i, "field7"); + let field8 = builder.context.new_field(None, m128i, "field8"); + let field9 = builder.context.new_field(None, m128i, "field9"); + let aes_output_type = builder.context.new_struct_type( + None, + "WideAesOutput", + &[field1, field2, field3, field4, field5, field6, field7, field8, field9], + ); + aes_output_type.as_type().set_packed(); + (aes_output_type.as_type(), field1, field2) +} + #[cfg_attr(not(feature = "master"), allow(unused_variables))] pub fn adjust_function<'gcc>( context: &'gcc Context<'gcc>, @@ -503,6 +578,74 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( let arg4 = builder.context.new_rvalue_from_int(arg4_type, -1); args = vec![a, b, c, arg4, new_args[3]].into(); } + "__builtin_ia32_encodekey128_u32" => { + let mut new_args = args.to_vec(); + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let array_type = builder.context.new_array_type(None, m128i, 6); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + args = new_args.into(); + } + "__builtin_ia32_encodekey256_u32" => { + let mut new_args = args.to_vec(); + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let array_type = builder.context.new_array_type(None, m128i, 7); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + args = new_args.into(); + } + "__builtin_ia32_aesenc128kl_u8" + | "__builtin_ia32_aesdec128kl_u8" + | "__builtin_ia32_aesenc256kl_u8" + | "__builtin_ia32_aesdec256kl_u8" => { + let mut new_args = vec![]; + // TODO: directly create a variable of type m128i instead of the whole struct? + let (aes_output_type, _, field2) = aes_output_type(builder); + let result = builder.current_func().new_local(None, aes_output_type, "result"); + let field2 = result.access_field(None, field2); + new_args.push(field2.get_address(None)); + new_args.extend(args.to_vec()); + args = new_args.into(); + } + "__builtin_ia32_aesencwide128kl_u8" + | "__builtin_ia32_aesdecwide128kl_u8" + | "__builtin_ia32_aesencwide256kl_u8" + | "__builtin_ia32_aesdecwide256kl_u8" => { + let mut new_args = vec![]; + + let mut old_args = args.to_vec(); + let handle = old_args.swap_remove(0); // Called __P in GCC. + let first_value = old_args.swap_remove(0); + + let element_type = first_value.get_type(); + let array_type = builder.context.new_array_type(None, element_type, 8); + let result = builder.current_func().new_local(None, array_type, "result"); + new_args.push(result.get_address(None)); + + let array = builder.current_func().new_local(None, array_type, "array"); + let input = builder.context.new_array_constructor( + None, + array_type, + &[ + first_value, + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + old_args.swap_remove(0), + ], + ); + builder.llbb().add_assignment(None, array, input); + let input_ptr = array.get_address(None); + let arg2_type = gcc_func.get_param_type(1); + let input_ptr = builder.context.new_cast(None, input_ptr, arg2_type); + new_args.push(input_ptr); + + new_args.push(handle); + args = new_args.into(); + } _ => (), } } else { @@ -700,6 +843,96 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( let f16_type = builder.context.new_c_type(CType::Float16); return_value = builder.context.new_cast(None, return_value, f16_type); } + "__builtin_ia32_encodekey128_u32" => { + // The builtin __builtin_ia32_encodekey128_u32 writes the result in its pointer argument while + // llvm.x86.encodekey128 returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (encode_type, field1, field2) = encode_key_128_type(builder); + let result = builder.current_func().new_local(None, encode_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 6); + let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } + "__builtin_ia32_encodekey256_u32" => { + // The builtin __builtin_ia32_encodekey256_u32 writes the result in its pointer argument while + // llvm.x86.encodekey256 returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (encode_type, field1, field2) = encode_key_256_type(builder); + let result = builder.current_func().new_local(None, encode_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 7); + let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } + "__builtin_ia32_aesdec128kl_u8" + | "__builtin_ia32_aesenc128kl_u8" + | "__builtin_ia32_aesdec256kl_u8" + | "__builtin_ia32_aesenc256kl_u8" => { + // The builtin for aesdec/aesenc writes the result in its pointer argument while + // llvm.x86.aesdec128kl returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (aes_output_type, field1, field2) = aes_output_type(builder); + let result = builder.current_func().new_local(None, aes_output_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let ptr = builder.context.new_cast( + None, + args[0], + field2.to_rvalue().get_type().make_pointer(), + ); + builder.llbb().add_assignment(None, field2, ptr.dereference(None)); + return_value = result.to_rvalue(); + } + "__builtin_ia32_aesencwide128kl_u8" + | "__builtin_ia32_aesdecwide128kl_u8" + | "__builtin_ia32_aesencwide256kl_u8" + | "__builtin_ia32_aesdecwide256kl_u8" => { + // The builtin for aesdecwide/aesencwide writes the result in its pointer argument while + // llvm.x86.aesencwide128kl returns a value. + // We added a result pointer argument and now need to assign its value to the return_value expected by + // the LLVM intrinsic. + let (aes_output_type, field1, field2) = wide_aes_output_type(builder); + let result = builder.current_func().new_local(None, aes_output_type, "result"); + let field1 = result.access_field(None, field1); + builder.llbb().add_assignment(None, field1, return_value); + let field2 = result.access_field(None, field2); + let field2_type = field2.to_rvalue().get_type(); + let array_type = builder.context.new_array_type(None, field2_type, 8); + let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer()); + let field2_ptr = + builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); + builder.llbb().add_assignment( + None, + field2_ptr.dereference(None), + ptr.dereference(None), + ); + return_value = result.to_rvalue(); + } _ => (), } @@ -1284,6 +1517,16 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.avx512fp16.mask.vfmadd.cph.256" => "__builtin_ia32_vfmaddcph256_mask3", "llvm.x86.avx512fp16.mask.vfcmadd.cph.128" => "__builtin_ia32_vfcmaddcph128_mask3", "llvm.x86.avx512fp16.mask.vfmadd.cph.128" => "__builtin_ia32_vfmaddcph128_mask3", + "llvm.x86.encodekey128" => "__builtin_ia32_encodekey128_u32", + "llvm.x86.encodekey256" => "__builtin_ia32_encodekey256_u32", + "llvm.x86.aesenc128kl" => "__builtin_ia32_aesenc128kl_u8", + "llvm.x86.aesdec128kl" => "__builtin_ia32_aesdec128kl_u8", + "llvm.x86.aesenc256kl" => "__builtin_ia32_aesenc256kl_u8", + "llvm.x86.aesdec256kl" => "__builtin_ia32_aesdec256kl_u8", + "llvm.x86.aesencwide128kl" => "__builtin_ia32_aesencwide128kl_u8", + "llvm.x86.aesdecwide128kl" => "__builtin_ia32_aesdecwide128kl_u8", + "llvm.x86.aesencwide256kl" => "__builtin_ia32_aesencwide256kl_u8", + "llvm.x86.aesdecwide256kl" => "__builtin_ia32_aesdecwide256kl_u8", // TODO: support the tile builtins: "llvm.x86.ldtilecfg" => "__builtin_trap", From 98dd5a30b32c1311d5a44ebb2c0667a8ff0ef76a Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 18 Apr 2025 11:45:30 -0400 Subject: [PATCH 091/106] Fix for libgccjit 12 --- src/intrinsic/llvm.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index e030e3b4ff28..befb2e17960c 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -22,6 +22,7 @@ fn encode_key_128_type<'a, 'gcc, 'tcx>( "EncodeKey128Output", &[field1, field2, field3, field4, field5, field6, field7], ); + #[cfg(feature = "master")] encode_type.as_type().set_packed(); (encode_type.as_type(), field1, field2) } @@ -43,6 +44,7 @@ fn encode_key_256_type<'a, 'gcc, 'tcx>( "EncodeKey256Output", &[field1, field2, field3, field4, field5, field6, field7, field8], ); + #[cfg(feature = "master")] encode_type.as_type().set_packed(); (encode_type.as_type(), field1, field2) } @@ -55,6 +57,7 @@ fn aes_output_type<'a, 'gcc, 'tcx>( let field2 = builder.context.new_field(None, m128i, "field2"); let aes_output_type = builder.context.new_struct_type(None, "AesOutput", &[field1, field2]); let typ = aes_output_type.as_type(); + #[cfg(feature = "master")] typ.set_packed(); (typ, field1, field2) } @@ -77,6 +80,7 @@ fn wide_aes_output_type<'a, 'gcc, 'tcx>( "WideAesOutput", &[field1, field2, field3, field4, field5, field6, field7, field8, field9], ); + #[cfg(feature = "master")] aes_output_type.as_type().set_packed(); (aes_output_type.as_type(), field1, field2) } From 52b06872fe92811e5ae5d87bbb3508924525723b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 18 Apr 2025 12:07:10 -0400 Subject: [PATCH 092/106] Simplify handling of some SIMD intrinsics --- src/intrinsic/llvm.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index befb2e17960c..0eebd21001a9 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -603,11 +603,9 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( | "__builtin_ia32_aesenc256kl_u8" | "__builtin_ia32_aesdec256kl_u8" => { let mut new_args = vec![]; - // TODO: directly create a variable of type m128i instead of the whole struct? - let (aes_output_type, _, field2) = aes_output_type(builder); - let result = builder.current_func().new_local(None, aes_output_type, "result"); - let field2 = result.access_field(None, field2); - new_args.push(field2.get_address(None)); + let m128i = builder.context.new_vector_type(builder.i64_type, 2); + let result = builder.current_func().new_local(None, m128i, "result"); + new_args.push(result.get_address(None)); new_args.extend(args.to_vec()); args = new_args.into(); } From 59477a8ab21480a5c3da0313ef5a235091d8cbee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 16 Apr 2025 15:12:05 +0200 Subject: [PATCH 093/106] Make rustdoc JSON Span column 1-based, just like line numbers --- src/librustdoc/json/conversions.rs | 4 ++-- src/rustdoc-json-types/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index dab23f8e42a3..f446c9fbbd8b 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -84,8 +84,8 @@ impl JsonRenderer<'_> { let lo = span.lo(self.sess()); Some(Span { filename: local_path, - begin: (lo.line, lo.col.to_usize()), - end: (hi.line, hi.col.to_usize()), + begin: (lo.line, lo.col.to_usize() + 1), + end: (hi.line, hi.col.to_usize() + 1), }) } else { None diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 7247950545ad..875857f96511 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -205,9 +205,9 @@ pub struct Item { pub struct Span { /// The path to the source file for this span relative to the path `rustdoc` was invoked with. pub filename: PathBuf, - /// Zero indexed Line and Column of the first character of the `Span` + /// One indexed Line and Column of the first character of the `Span`. pub begin: (usize, usize), - /// Zero indexed Line and Column of the last character of the `Span` + /// One indexed Line and Column of the last character of the `Span`. pub end: (usize, usize), } From ba9a008d90ad7b9c11379a00766f9e4ebbcdc126 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 16 Apr 2025 15:28:28 +0200 Subject: [PATCH 094/106] Add regression test for span 1-indexed check --- tests/rustdoc-json/impls/auto.rs | 4 ++-- tests/rustdoc-json/span.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 tests/rustdoc-json/span.rs diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index f94f7338480b..ce47d1be690f 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -15,8 +15,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 0]" -//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 1]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 1]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 2]" // FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91 // is "$.index[?(@.inner.impl.is_synthetic==true)].span" null pub struct Foo; diff --git a/tests/rustdoc-json/span.rs b/tests/rustdoc-json/span.rs new file mode 100644 index 000000000000..c96879d0e684 --- /dev/null +++ b/tests/rustdoc-json/span.rs @@ -0,0 +1,4 @@ +pub mod bar {} +// This test ensures that spans are 1-indexed. +//@ is "$.index[?(@.name=='span')].span.begin" "[1, 1]" +//@ is "$.index[?(@.name=='bar')].span.begin" "[1, 1]" From 076016d55afdf760c7e30e23c5df8f0c079cd85b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 20:34:56 +0200 Subject: [PATCH 095/106] Update rustdoc-json-types `FORMAT_VERSION` to 45 --- src/rustdoc-json-types/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 875857f96511..64223b5b7589 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap = HashMap; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 44; +pub const FORMAT_VERSION: u32 = 45; /// The root of the emitted JSON blob. /// From c123dc63ea5f765488e4d56aa55bf4467fce7d27 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 21:21:15 +0200 Subject: [PATCH 096/106] Fix `rustc_codegen_gcc/tests/run/return-tuple.rs` test --- compiler/rustc_codegen_gcc/tests/run/return-tuple.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs index c6e1ba7ce394..c1254c51ce91 100644 --- a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs +++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs @@ -6,13 +6,7 @@ // 10 // 42 -<<<<<<< HEAD -#![feature(auto_traits, lang_items, no_core, intrinsics)] -#![allow(internal_features)] - -======= #![feature(no_core)] ->>>>>>> db1a31c243a649e1fe20f5466ba181da5be35c14 #![no_std] #![no_core] #![no_main] From fb3cae08ab3fad5b915e04adc60b164ddd1612c4 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Thu, 17 Apr 2025 20:31:58 -0500 Subject: [PATCH 097/106] std: Use fstatat() on illumos --- library/std/src/sys/fs/unix.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 687fc322e598..bc8817bac704 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -12,10 +12,11 @@ use libc::c_char; all(target_os = "linux", not(target_env = "musl")), target_os = "android", target_os = "fuchsia", - target_os = "hurd" + target_os = "hurd", + target_os = "illumos", ))] use libc::dirfd; -#[cfg(target_os = "fuchsia")] +#[cfg(any(target_os = "fuchsia", target_os = "illumos"))] use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; @@ -892,7 +893,8 @@ impl DirEntry { all(target_os = "linux", not(target_env = "musl")), target_os = "android", target_os = "fuchsia", - target_os = "hurd" + target_os = "hurd", + target_os = "illumos", ), not(miri) // no dirfd on Miri ))] @@ -922,6 +924,7 @@ impl DirEntry { target_os = "android", target_os = "fuchsia", target_os = "hurd", + target_os = "illumos", )), miri ))] From 84f582665ef64467e2ca8f65448f75f14b12edf5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 22:46:43 +0200 Subject: [PATCH 098/106] Fix compilation error in GCC backend --- compiler/rustc_codegen_gcc/src/int.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index 906d7eaceb6b..9b5b0fde6e2f 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -404,7 +404,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); - let result = if ret_indirect { + let call = if ret_indirect { let res_value = self.current_func().new_local(self.location, res_type, "result_value"); let res_addr = res_value.get_address(self.location); let res_param_type = res_type.make_pointer(); From cc359b8bb6c693086f69adf013430163992b1807 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Apr 2025 23:02:07 +0200 Subject: [PATCH 099/106] Fix import --- compiler/rustc_codegen_gcc/src/abi.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 890a25e6a7ca..a96b18e01c08 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -10,7 +10,8 @@ use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] use rustc_session::config; #[cfg(feature = "master")] -use rustc_target::callconv::{ArgAttributes, CastTarget, Conv, FnAbi, PassMode}; +use rustc_target::callconv::Conv; +use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; From bd5c43835ab77b30086b818e17c3a566849c2af3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 18 Apr 2025 23:34:37 +0000 Subject: [PATCH 100/106] Remove early exits from JumpThreading. --- .../rustc_mir_transform/src/jump_threading.rs | 135 +++++++++--------- 1 file changed, 64 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 8b4b214a3d45..9732225e48dd 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -90,11 +90,7 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading { }; for bb in body.basic_blocks.indices() { - let old_len = finder.opportunities.len(); - // If we have any const-eval errors discard any opportunities found - if finder.start_from_switch(bb).is_none() { - finder.opportunities.truncate(old_len); - } + finder.start_from_switch(bb); } let opportunities = finder.opportunities; @@ -201,28 +197,26 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { /// Recursion entry point to find threading opportunities. #[instrument(level = "trace", skip(self))] - fn start_from_switch(&mut self, bb: BasicBlock) -> Option<()> { + fn start_from_switch(&mut self, bb: BasicBlock) { let bbdata = &self.body[bb]; if bbdata.is_cleanup || self.loop_headers.contains(bb) { - return Some(()); + return; } - let Some((discr, targets)) = bbdata.terminator().kind.as_switch() else { return Some(()) }; - let Some(discr) = discr.place() else { return Some(()) }; + let Some((discr, targets)) = bbdata.terminator().kind.as_switch() else { return }; + let Some(discr) = discr.place() else { return }; debug!(?discr, ?bb); let discr_ty = discr.ty(self.body, self.tcx).ty; - let Ok(discr_layout) = self.ecx.layout_of(discr_ty) else { - return Some(()); - }; + let Ok(discr_layout) = self.ecx.layout_of(discr_ty) else { return }; - let Some(discr) = self.map.find(discr.as_ref()) else { return Some(()) }; + let Some(discr) = self.map.find(discr.as_ref()) else { return }; debug!(?discr); let cost = CostChecker::new(self.tcx, self.typing_env, None, self.body); let mut state = State::new_reachable(); let conds = if let Some((value, then, else_)) = targets.as_static_if() { - let value = ScalarInt::try_from_uint(value, discr_layout.size)?; + let Some(value) = ScalarInt::try_from_uint(value, discr_layout.size) else { return }; self.arena.alloc_from_iter([ Condition { value, polarity: Polarity::Eq, target: then }, Condition { value, polarity: Polarity::Ne, target: else_ }, @@ -248,10 +242,10 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { mut state: State>, mut cost: CostChecker<'_, 'tcx>, depth: usize, - ) -> Option<()> { + ) { // Do not thread through loop headers. if self.loop_headers.contains(bb) { - return Some(()); + return; } debug!(cost = ?cost.cost()); @@ -259,16 +253,16 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { self.body.basic_blocks[bb].statements.iter().enumerate().rev() { if self.is_empty(&state) { - return Some(()); + return; } cost.visit_statement(stmt, Location { block: bb, statement_index }); if cost.cost() > MAX_COST { - return Some(()); + return; } // Attempt to turn the `current_condition` on `lhs` into a condition on another place. - self.process_statement(bb, stmt, &mut state)?; + self.process_statement(bb, stmt, &mut state); // When a statement mutates a place, assignments to that place that happen // above the mutation cannot fulfill a condition. @@ -280,7 +274,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { } if self.is_empty(&state) || depth >= MAX_BACKTRACK { - return Some(()); + return; } let last_non_rec = self.opportunities.len(); @@ -293,9 +287,9 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { match term.kind { TerminatorKind::SwitchInt { ref discr, ref targets } => { self.process_switch_int(discr, targets, bb, &mut state); - self.find_opportunity(pred, state, cost, depth + 1)?; + self.find_opportunity(pred, state, cost, depth + 1); } - _ => self.recurse_through_terminator(pred, || state, &cost, depth)?, + _ => self.recurse_through_terminator(pred, || state, &cost, depth), } } else if let &[ref predecessors @ .., last_pred] = &predecessors[..] { for &pred in predecessors { @@ -320,13 +314,12 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { let first = &mut new_tos[0]; *first = ThreadingOpportunity { chain: vec![bb], target: first.target }; self.opportunities.truncate(last_non_rec + 1); - return Some(()); + return; } for op in self.opportunities[last_non_rec..].iter_mut() { op.chain.push(bb); } - Some(()) } /// Extract the mutated place from a statement. @@ -440,23 +433,23 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { lhs: PlaceIndex, rhs: &Operand<'tcx>, state: &mut State>, - ) -> Option<()> { + ) { match rhs { // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`. Operand::Constant(constant) => { - let constant = self - .ecx - .eval_mir_constant(&constant.const_, constant.span, None) - .discard_err()?; + let Some(constant) = + self.ecx.eval_mir_constant(&constant.const_, constant.span, None).discard_err() + else { + return; + }; self.process_constant(bb, lhs, constant, state); } // Transfer the conditions on the copied rhs. Operand::Move(rhs) | Operand::Copy(rhs) => { - let Some(rhs) = self.map.find(rhs.as_ref()) else { return Some(()) }; + let Some(rhs) = self.map.find(rhs.as_ref()) else { return }; state.insert_place_idx(rhs, lhs, &self.map); } } - Some(()) } #[instrument(level = "trace", skip(self))] @@ -466,18 +459,14 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { lhs_place: &Place<'tcx>, rhs: &Rvalue<'tcx>, state: &mut State>, - ) -> Option<()> { - let Some(lhs) = self.map.find(lhs_place.as_ref()) else { - return Some(()); - }; + ) { + let Some(lhs) = self.map.find(lhs_place.as_ref()) else { return }; match rhs { - Rvalue::Use(operand) => self.process_operand(bb, lhs, operand, state)?, + Rvalue::Use(operand) => self.process_operand(bb, lhs, operand, state), // Transfer the conditions on the copy rhs. - Rvalue::CopyForDeref(rhs) => { - self.process_operand(bb, lhs, &Operand::Copy(*rhs), state)? - } + Rvalue::CopyForDeref(rhs) => self.process_operand(bb, lhs, &Operand::Copy(*rhs), state), Rvalue::Discriminant(rhs) => { - let Some(rhs) = self.map.find_discr(rhs.as_ref()) else { return Some(()) }; + let Some(rhs) = self.map.find_discr(rhs.as_ref()) else { return }; state.insert_place_idx(rhs, lhs, &self.map); } // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`. @@ -485,7 +474,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { let agg_ty = lhs_place.ty(self.body, self.tcx).ty; let lhs = match kind { // Do not support unions. - AggregateKind::Adt(.., Some(_)) => return Some(()), + AggregateKind::Adt(.., Some(_)) => return, AggregateKind::Adt(_, variant_index, ..) if agg_ty.is_enum() => { if let Some(discr_target) = self.map.apply(lhs, TrackElem::Discriminant) && let Some(discr_value) = self @@ -498,23 +487,23 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { if let Some(idx) = self.map.apply(lhs, TrackElem::Variant(*variant_index)) { idx } else { - return Some(()); + return; } } _ => lhs, }; for (field_index, operand) in operands.iter_enumerated() { if let Some(field) = self.map.apply(lhs, TrackElem::Field(field_index)) { - self.process_operand(bb, field, operand, state)?; + self.process_operand(bb, field, operand, state); } } } // Transfer the conditions on the copy rhs, after inverting the value of the condition. Rvalue::UnaryOp(UnOp::Not, Operand::Move(place) | Operand::Copy(place)) => { let layout = self.ecx.layout_of(place.ty(self.body, self.tcx).ty).unwrap(); - let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return Some(()) }; - let Some(place) = self.map.find(place.as_ref()) else { return Some(()) }; - let conds = conditions.map(self.arena, |mut cond| { + let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return }; + let Some(place) = self.map.find(place.as_ref()) else { return }; + let Some(conds) = conditions.map(self.arena, |mut cond| { cond.value = self .ecx .unary_op(UnOp::Not, &ImmTy::from_scalar_int(cond.value, layout)) @@ -522,7 +511,9 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { .to_scalar_int() .discard_err()?; Some(cond) - })?; + }) else { + return; + }; state.insert_value_idx(place, conds, &self.map); } // We expect `lhs ?= A`. We found `lhs = Eq(rhs, B)`. @@ -532,34 +523,38 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { box (Operand::Move(place) | Operand::Copy(place), Operand::Constant(value)) | box (Operand::Constant(value), Operand::Move(place) | Operand::Copy(place)), ) => { - let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return Some(()) }; - let Some(place) = self.map.find(place.as_ref()) else { return Some(()) }; + let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return }; + let Some(place) = self.map.find(place.as_ref()) else { return }; let equals = match op { BinOp::Eq => ScalarInt::TRUE, BinOp::Ne => ScalarInt::FALSE, - _ => return Some(()), + _ => return, }; if value.const_.ty().is_floating_point() { // Floating point equality does not follow bit-patterns. // -0.0 and NaN both have special rules for equality, // and therefore we cannot use integer comparisons for them. // Avoid handling them, though this could be extended in the future. - return Some(()); + return; } - let value = value.const_.try_eval_scalar_int(self.tcx, self.typing_env)?; - let conds = conditions.map(self.arena, |c| { + let Some(value) = value.const_.try_eval_scalar_int(self.tcx, self.typing_env) + else { + return; + }; + let Some(conds) = conditions.map(self.arena, |c| { Some(Condition { value, polarity: if c.matches(equals) { Polarity::Eq } else { Polarity::Ne }, ..c }) - })?; + }) else { + return; + }; state.insert_value_idx(place, conds, &self.map); } _ => {} } - Some(()) } #[instrument(level = "trace", skip(self))] @@ -568,7 +563,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { bb: BasicBlock, stmt: &Statement<'tcx>, state: &mut State>, - ) -> Option<()> { + ) { let register_opportunity = |c: Condition| { debug!(?bb, ?c.target, "register"); self.opportunities.push(ThreadingOpportunity { chain: vec![bb], target: c.target }) @@ -581,32 +576,30 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { // If we expect `discriminant(place) ?= A`, // we have an opportunity if `variant_index ?= A`. StatementKind::SetDiscriminant { box place, variant_index } => { - let Some(discr_target) = self.map.find_discr(place.as_ref()) else { - return Some(()); - }; + let Some(discr_target) = self.map.find_discr(place.as_ref()) else { return }; let enum_ty = place.ty(self.body, self.tcx).ty; // `SetDiscriminant` guarantees that the discriminant is now `variant_index`. // Even if the discriminant write does nothing due to niches, it is UB to set the // discriminant when the data does not encode the desired discriminant. - let discr = - self.ecx.discriminant_for_variant(enum_ty, *variant_index).discard_err()?; - self.process_immediate(bb, discr_target, discr, state); + let Some(discr) = + self.ecx.discriminant_for_variant(enum_ty, *variant_index).discard_err() + else { + return; + }; + self.process_immediate(bb, discr_target, discr, state) } // If we expect `lhs ?= true`, we have an opportunity if we assume `lhs == true`. StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume( Operand::Copy(place) | Operand::Move(place), )) => { - let Some(conditions) = state.try_get(place.as_ref(), &self.map) else { - return Some(()); - }; - conditions.iter_matches(ScalarInt::TRUE).for_each(register_opportunity); + let Some(conditions) = state.try_get(place.as_ref(), &self.map) else { return }; + conditions.iter_matches(ScalarInt::TRUE).for_each(register_opportunity) } StatementKind::Assign(box (lhs_place, rhs)) => { - self.process_assign(bb, lhs_place, rhs, state)?; + self.process_assign(bb, lhs_place, rhs, state) } _ => {} } - Some(()) } #[instrument(level = "trace", skip(self, state, cost))] @@ -617,7 +610,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { state: impl FnOnce() -> State>, cost: &CostChecker<'_, 'tcx>, depth: usize, - ) -> Option<()> { + ) { let term = self.body.basic_blocks[bb].terminator(); let place_to_flood = match term.kind { // We come from a target, so those are not possible. @@ -632,9 +625,9 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Yield { .. } => bug!("{term:?} invalid"), // Cannot reason about inline asm. - TerminatorKind::InlineAsm { .. } => return Some(()), + TerminatorKind::InlineAsm { .. } => return, // `SwitchInt` is handled specially. - TerminatorKind::SwitchInt { .. } => return Some(()), + TerminatorKind::SwitchInt { .. } => return, // We can recurse, no thing particular to do. TerminatorKind::Goto { .. } => None, // Flood the overwritten place, and progress through. From d863f81671459712627e2bf1a106b0b3e6b1bbce Mon Sep 17 00:00:00 2001 From: Sky Date: Fri, 18 Apr 2025 21:40:53 -0400 Subject: [PATCH 101/106] Re-remove `AdtFlags::IS_ANONYMOUS` --- compiler/rustc_middle/src/ty/adt.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 66517c97a687..d92b4f9c06be 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -55,8 +55,6 @@ bitflags::bitflags! { const IS_UNSAFE_CELL = 1 << 9; /// Indicates whether the type is `UnsafePinned`. const IS_UNSAFE_PINNED = 1 << 10; - /// Indicates whether the type is anonymous. - const IS_ANONYMOUS = 1 << 11; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } From 1f491dccba0d593ba6ba87ae830a59e571b9309f Mon Sep 17 00:00:00 2001 From: Jonathan Gruner Date: Tue, 8 Apr 2025 17:17:21 +0200 Subject: [PATCH 102/106] add next_index to Enumerate --- library/core/src/iter/adapters/enumerate.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index bd093e279c38..1f2cf3244b35 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -23,6 +23,18 @@ impl Enumerate { pub(in crate::iter) fn new(iter: I) -> Enumerate { Enumerate { iter, count: 0 } } + + /// Retrieve the current position of the iterator. + /// + /// If the iterator has not advanced, the position returned will be 0. + /// + /// The position may also exceed the bounds of the iterator to allow for calculating + /// the displacement of the iterator from following calls to [`Iterator::next`]. + #[inline] + #[unstable(feature = "next_index", issue = "130711")] + pub fn next_index(&self) -> usize { + self.count + } } #[stable(feature = "rust1", since = "1.0.0")] From 5a71fabe297ab172eb873a03ab5e057ca55f78db Mon Sep 17 00:00:00 2001 From: Jonathan Gruner Date: Sat, 19 Apr 2025 12:06:30 +0200 Subject: [PATCH 103/106] added doctest for Enumerate::next_index --- library/core/src/iter/adapters/enumerate.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 1f2cf3244b35..f7b9f0b7a5e9 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -30,6 +30,27 @@ impl Enumerate { /// /// The position may also exceed the bounds of the iterator to allow for calculating /// the displacement of the iterator from following calls to [`Iterator::next`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(next_index)] + /// + /// let arr = ['a', 'b']; + /// + /// let mut iter = arr.iter().enumerate(); + /// + /// assert_eq!(iter.next_index(), 0); + /// assert_eq!(iter.next(), Some((0, &'a'))); + /// + /// assert_eq!(iter.next_index(), 1); + /// assert_eq!(iter.next_index(), 1); + /// assert_eq!(iter.next(), Some((1, &'b'))); + /// + /// assert_eq!(iter.next_index(), 2); + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next_index(), 2); + /// ``` #[inline] #[unstable(feature = "next_index", issue = "130711")] pub fn next_index(&self) -> usize { From f121c7c3605d195a05a9802735994e3576be9d62 Mon Sep 17 00:00:00 2001 From: Jonathan Gruner Date: Sat, 19 Apr 2025 12:26:57 +0200 Subject: [PATCH 104/106] added test for Enumerate::next_index on empty iterator --- library/coretests/tests/iter/adapters/enumerate.rs | 10 ++++++++++ library/coretests/tests/lib.rs | 1 + 2 files changed, 11 insertions(+) diff --git a/library/coretests/tests/iter/adapters/enumerate.rs b/library/coretests/tests/iter/adapters/enumerate.rs index b57d51c077e9..2294f856b58d 100644 --- a/library/coretests/tests/iter/adapters/enumerate.rs +++ b/library/coretests/tests/iter/adapters/enumerate.rs @@ -120,3 +120,13 @@ fn test_double_ended_enumerate() { assert_eq!(it.next_back(), Some((2, 3))); assert_eq!(it.next(), None); } + +#[test] +fn test_empty_iterator_enumerate_next_index() { + let mut it = empty::().enumerate(); + assert_eq!(it.next_index(), 0); + assert_eq!(it.next_index(), 0); + assert_eq!(it.next(), None); + assert_eq!(it.next_index(), 0); + assert_eq!(it.next_index(), 0); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1c43bfe0ed4a..ac1115759383 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -63,6 +63,7 @@ #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(never_type)] +#![feature(next_index)] #![feature(numfmt)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] From 1d87d14cdbbcff685569509ab2b9b06cb605c759 Mon Sep 17 00:00:00 2001 From: apiraino Date: Sat, 19 Apr 2025 14:42:02 +0200 Subject: [PATCH 105/106] Add option for stable backport poll skip-checks: true --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 226f024c156b..0f17d022fbb8 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -659,6 +659,7 @@ message_on_add = [ """\ /poll Approve stable backport of #{number}? approve +approve (but does not justify new dot release on its own) decline don't know """, From 32fe60bc57ccdc234eb51bd22f74f3b55f2941e8 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 20 Apr 2025 04:52:36 +0000 Subject: [PATCH 106/106] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 2d7b6a650aef..ce1b8fabac70 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -2ef78586529b5f68cc42bcbe9b10b4afe56a942a +90fd16eb5be9255006c95e8af12a0d43854dc1a9