From c59b70841c36277464b51161e3fcf12dfcb667e0 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 7 Mar 2025 10:13:30 +0800 Subject: Emit warning while outputs is not exe and prints linkage info Signed-off-by: xizheyin --- compiler/rustc_codegen_ssa/src/back/link.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 323538969d7..ffa888a17d0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -68,6 +68,23 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { } } +fn check_link_info_print_request(sess: &Session, crate_type: CrateType) { + let print_native_static_libs = + sess.opts.prints.iter().any(|p| p.kind == PrintKind::NativeStaticLibs); + if print_native_static_libs { + if crate_type != CrateType::Staticlib { + sess.dcx() + .warn(format!("cannot output linkage information without staticlib crate-type")); + sess.dcx() + .note(format!("consider `--crate-type staticlib` to print linkage information")); + } else if !sess.opts.output_types.should_link() { + sess.dcx().warn(format!( + "skipping link step due to conflict: cannot output linkage information without emitting link" + )); + } + } +} + /// Performs the linkage portion of the compilation phase. This will generate all /// of the requested outputs for this compilation session. pub fn link_binary( @@ -178,6 +195,8 @@ pub fn link_binary( tempfiles_for_stdout_output.push(out_filename); } } + + check_link_info_print_request(sess, crate_type); } // Remove the temporary object file and metadata if we aren't saving temps. -- cgit 1.4.1-3-g733a5 From 98bb597c05c32365abbd6898f278b097352774ed Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 2 May 2025 22:37:33 +0800 Subject: Update compiler/rustc_codegen_ssa/src/back/link.rs Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ffa888a17d0..28c7b5b2745 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -79,7 +79,7 @@ fn check_link_info_print_request(sess: &Session, crate_type: CrateType) { .note(format!("consider `--crate-type staticlib` to print linkage information")); } else if !sess.opts.output_types.should_link() { sess.dcx().warn(format!( - "skipping link step due to conflict: cannot output linkage information without emitting link" + "cannot output linkage information when --emit link is not passed" )); } } -- cgit 1.4.1-3-g733a5 From 72a9219e82c157041bfc8dfd378c9cb2b09c0650 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 2 May 2025 22:56:27 +0800 Subject: check all crate-type to find staticlib Signed-off-by: xizheyin --- compiler/rustc_codegen_ssa/src/back/link.rs | 12 ++++++------ .../emit-warning-while-exe-and-print-link-info.rs | 2 +- .../emit-warning-while-exe-and-print-link-info.stderr | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 28c7b5b2745..1e9d9338b13 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -68,19 +68,19 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { } } -fn check_link_info_print_request(sess: &Session, crate_type: CrateType) { +fn check_link_info_print_request(sess: &Session, crate_types: &[CrateType]) { let print_native_static_libs = sess.opts.prints.iter().any(|p| p.kind == PrintKind::NativeStaticLibs); + let has_staticlib = crate_types.iter().any(|ct| *ct == CrateType::Staticlib); if print_native_static_libs { - if crate_type != CrateType::Staticlib { + if !has_staticlib { sess.dcx() .warn(format!("cannot output linkage information without staticlib crate-type")); sess.dcx() .note(format!("consider `--crate-type staticlib` to print linkage information")); } else if !sess.opts.output_types.should_link() { - sess.dcx().warn(format!( - "cannot output linkage information when --emit link is not passed" - )); + sess.dcx() + .warn(format!("cannot output linkage information when --emit link is not passed")); } } } @@ -196,7 +196,7 @@ pub fn link_binary( } } - check_link_info_print_request(sess, crate_type); + check_link_info_print_request(sess, &codegen_results.crate_info.crate_types); } // Remove the temporary object file and metadata if we aren't saving temps. diff --git a/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.rs b/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.rs index 48f5475c884..3e9ca457a9c 100644 --- a/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.rs +++ b/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.rs @@ -1,3 +1,3 @@ //@ compile-flags: --print native-static-libs --crate-type staticlib --emit metadata //@ check-pass -//~? WARN skipping link step due to conflict: cannot output linkage information without emitting link +//~? WARN cannot output linkage information when --emit link is not passed diff --git a/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.stderr b/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.stderr index 0b46d2f6848..b32e1437d6b 100644 --- a/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.stderr +++ b/tests/ui/print-request/emit-warning-while-exe-and-print-link-info.stderr @@ -1,4 +1,4 @@ -warning: skipping link step due to conflict: cannot output linkage information without emitting link +warning: cannot output linkage information when --emit link is not passed warning: 1 warning emitted -- cgit 1.4.1-3-g733a5 From f66787a08d57dc1296619b314d2be596085bfeef Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 2 May 2025 23:14:18 +0800 Subject: Update compiler/rustc_codegen_ssa/src/back/link.rs Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> Signed-off-by: xizheyin --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1e9d9338b13..62c389ec791 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -195,10 +195,10 @@ pub fn link_binary( tempfiles_for_stdout_output.push(out_filename); } } - - check_link_info_print_request(sess, &codegen_results.crate_info.crate_types); } + check_link_info_print_request(sess, &codegen_results.crate_info.crate_types); + // Remove the temporary object file and metadata if we aren't saving temps. sess.time("link_binary_remove_temps", || { // If the user requests that temporaries are saved, don't delete any. -- cgit 1.4.1-3-g733a5 From 3b7ca287a7ecb80185f2c679e663cd9c94cdc9f4 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Fri, 14 Mar 2025 10:48:02 +0100 Subject: Describe lifetime of call argument temporaries passed indirectly --- compiler/rustc_codegen_ssa/src/mir/block.rs | 48 ++++++++++----- tests/codegen/align-byval-alignment-mismatch.rs | 7 ++- tests/codegen/call-tmps-lifetime.rs | 68 ++++++++++++++++++++++ .../issues/issue-98156-const-arg-temp-lifetime.rs | 27 --------- 4 files changed, 108 insertions(+), 42 deletions(-) create mode 100644 tests/codegen/call-tmps-lifetime.rs delete mode 100644 tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 950f19a6f0f..1530ee85647 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1,6 +1,6 @@ use std::cmp; -use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange}; +use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, Size, WrappingRange}; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::packed::Pu128; @@ -158,7 +158,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { llargs: &[Bx::Value], destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>, mut unwind: mir::UnwindAction, - copied_constant_arguments: &[PlaceRef<'tcx, ::Value>], + lifetime_ends_after_call: &[(Bx::Value, Size)], instance: Option>, mergeable_succ: bool, ) -> MergingSucc { @@ -245,8 +245,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { if let Some((ret_dest, target)) = destination { bx.switch_to_block(fx.llbb(target)); fx.set_debug_loc(bx, self.terminator.source_info); - for tmp in copied_constant_arguments { - bx.lifetime_end(tmp.val.llval, tmp.layout.size); + for &(tmp, size) in lifetime_ends_after_call { + bx.lifetime_end(tmp, size); } fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret); } @@ -259,8 +259,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } if let Some((ret_dest, target)) = destination { - for tmp in copied_constant_arguments { - bx.lifetime_end(tmp.val.llval, tmp.layout.size); + for &(tmp, size) in lifetime_ends_after_call { + bx.lifetime_end(tmp, size); } fx.store_return(bx, ret_dest, &fn_abi.ret, llret); self.funclet_br(fx, bx, target, mergeable_succ) @@ -1048,7 +1048,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (args, None) }; - let mut copied_constant_arguments = vec![]; + // When generating arguments we sometimes introduce temporary allocations with lifetime + // that extend for the duration of a call. Keep track of those allocations and their sizes + // to generate `lifetime_end` when the call returns. + let mut lifetime_ends_after_call: Vec<(Bx::Value, Size)> = Vec::new(); 'make_args: for (i, arg) in first_args.iter().enumerate() { let mut op = self.codegen_operand(bx, &arg.node); @@ -1136,12 +1139,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.lifetime_start(tmp.val.llval, tmp.layout.size); op.val.store(bx, tmp); op.val = Ref(tmp.val); - copied_constant_arguments.push(tmp); + lifetime_ends_after_call.push((tmp.val.llval, tmp.layout.size)); } _ => {} } - self.codegen_argument(bx, op, &mut llargs, &fn_abi.args[i]); + self.codegen_argument( + bx, + op, + &mut llargs, + &fn_abi.args[i], + &mut lifetime_ends_after_call, + ); } let num_untupled = untuple.map(|tup| { self.codegen_arguments_untupled( @@ -1149,6 +1158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &tup.node, &mut llargs, &fn_abi.args[first_args.len()..], + &mut lifetime_ends_after_call, ) }); @@ -1173,7 +1183,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); let last_arg = fn_abi.args.last().unwrap(); - self.codegen_argument(bx, location, &mut llargs, last_arg); + self.codegen_argument( + bx, + location, + &mut llargs, + last_arg, + &mut lifetime_ends_after_call, + ); } let fn_ptr = match (instance, llfn) { @@ -1189,7 +1205,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &llargs, destination, unwind, - &copied_constant_arguments, + &lifetime_ends_after_call, instance, mergeable_succ, ) @@ -1479,6 +1495,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { op: OperandRef<'tcx, Bx::Value>, llargs: &mut Vec, arg: &ArgAbi<'tcx, Ty<'tcx>>, + lifetime_ends_after_call: &mut Vec<(Bx::Value, Size)>, ) { match arg.mode { PassMode::Ignore => return, @@ -1517,7 +1534,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => arg.layout.align.abi, }; let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + bx.lifetime_start(scratch.llval, arg.layout.size); op.val.store(bx, scratch.with_type(arg.layout)); + lifetime_ends_after_call.push((scratch.llval, arg.layout.size)); (scratch.llval, scratch.align, true) } PassMode::Cast { .. } => { @@ -1538,7 +1557,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // alignment requirements may be higher than the type's alignment, so copy // to a higher-aligned alloca. let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + bx.lifetime_start(scratch.llval, arg.layout.size); bx.typed_place_copy(scratch, op_place_val, op.layout); + lifetime_ends_after_call.push((scratch.llval, arg.layout.size)); (scratch.llval, scratch.align, true) } else { (op_place_val.llval, op_place_val.align, true) @@ -1620,6 +1641,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { operand: &mir::Operand<'tcx>, llargs: &mut Vec, args: &[ArgAbi<'tcx, Ty<'tcx>>], + lifetime_ends_after_call: &mut Vec<(Bx::Value, Size)>, ) -> usize { let tuple = self.codegen_operand(bx, operand); @@ -1632,13 +1654,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { for i in 0..tuple.layout.fields.count() { let field_ptr = tuple_ptr.project_field(bx, i); let field = bx.load_operand(field_ptr); - self.codegen_argument(bx, field, llargs, &args[i]); + self.codegen_argument(bx, field, llargs, &args[i], lifetime_ends_after_call); } } else { // If the tuple is immediate, the elements are as well. for i in 0..tuple.layout.fields.count() { let op = tuple.extract_field(self, bx, i); - self.codegen_argument(bx, op, llargs, &args[i]); + self.codegen_argument(bx, op, llargs, &args[i], lifetime_ends_after_call); } } tuple.layout.fields.count() diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs index 46cfb2972df..c69fc2de9d2 100644 --- a/tests/codegen/align-byval-alignment-mismatch.rs +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -2,9 +2,10 @@ //@ add-core-stubs //@ revisions:i686-linux x86_64-linux -//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu -C panic=abort +//@ compile-flags: -Cno-prepopulate-passes -Copt-level=1 -Cpanic=abort +//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu //@[i686-linux] needs-llvm-components: x86 -//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu -C panic=abort +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu //@[x86_64-linux] needs-llvm-components: x86 // Tests that we correctly copy arguments into allocas when the alignment of the byval argument @@ -54,8 +55,10 @@ extern "C" { pub unsafe fn rust_to_c_increases_alignment(x: Align1) { // i686-linux: start: // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca [48 x i8], align 4 + // i686-linux-NEXT: call void @llvm.lifetime.start.p0(i64 48, ptr {{.*}}[[ALLOCA]]) // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 4 {{.*}}[[ALLOCA]], ptr {{.*}}align 1 {{.*}}%x // i686-linux-NEXT: call void @extern_c_align1({{.+}} [[ALLOCA]]) + // i686-linux-NEXT: call void @llvm.lifetime.end.p0(i64 48, ptr {{.*}}[[ALLOCA]]) // x86_64-linux: start: // x86_64-linux-NEXT: call void @extern_c_align1 diff --git a/tests/codegen/call-tmps-lifetime.rs b/tests/codegen/call-tmps-lifetime.rs new file mode 100644 index 00000000000..7b7b6e17bdd --- /dev/null +++ b/tests/codegen/call-tmps-lifetime.rs @@ -0,0 +1,68 @@ +// Test that temporary allocas used for call arguments have their lifetimes described by +// intrinsics. +// +//@ add-core-stubs +//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes --crate-type=lib --target i686-unknown-linux-gnu +//@ needs-llvm-components: x86 +#![feature(no_core)] +#![no_std] +#![no_core] +extern crate minicore; +use minicore::*; + +// Const operand. Regression test for #98156. +// +// CHECK-LABEL: define void @const_indirect( +// CHECK-NEXT: start: +// CHECK-NEXT: [[B:%.*]] = alloca +// CHECK-NEXT: [[A:%.*]] = alloca +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[A]]) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 4096, i1 false) +// CHECK-NEXT: call void %h(ptr {{.*}} [[A]]) +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[A]]) +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[B]]) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 4096, i1 false) +// CHECK-NEXT: call void %h(ptr {{.*}} [[B]]) +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[B]]) +#[no_mangle] +pub fn const_indirect(h: extern "C" fn([u32; 1024])) { + const C: [u32; 1024] = [0; 1024]; + h(C); + h(C); +} + +#[repr(C)] +pub struct Str { + pub ptr: *const u8, + pub len: usize, +} + +// Pair of immediates. Regression test for #132014. +// +// CHECK-LABEL: define void @immediate_indirect(ptr {{.*}}%s.0, i32 {{.*}}%s.1, ptr {{.*}}%g) +// CHECK-NEXT: start: +// CHECK-NEXT: [[A:%.*]] = alloca +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[A]]) +// CHECK-NEXT: store ptr %s.0, ptr [[A]] +// CHECK-NEXT: [[B:%.]] = getelementptr inbounds i8, ptr [[A]], i32 4 +// CHECK-NEXT: store i32 %s.1, ptr [[B]] +// CHECK-NEXT: call void %g(ptr {{.*}} [[A]]) +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[A]]) +#[no_mangle] +pub fn immediate_indirect(s: Str, g: extern "C" fn(Str)) { + g(s); +} + +// Indirect argument with a higher alignment requirement than the type's. +// +// CHECK-LABEL: define void @align_indirect(ptr{{.*}} align 1{{.*}} %a, ptr{{.*}} %fun) +// CHECK-NEXT: start: +// CHECK-NEXT: [[A:%.*]] = alloca [1024 x i8], align 4 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1024, ptr [[A]]) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 1 %a, i32 1024, i1 false) +// CHECK-NEXT: call void %fun(ptr {{.*}} [[A]]) +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1024, ptr [[A]]) +#[no_mangle] +pub fn align_indirect(a: [u8; 1024], fun: extern "C" fn([u8; 1024])) { + fun(a); +} diff --git a/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs b/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs deleted file mode 100644 index aecb81caf22..00000000000 --- a/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs +++ /dev/null @@ -1,27 +0,0 @@ -// This test checks that temporaries for indirectly-passed arguments get lifetime markers. - -//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes -Zmir-opt-level=0 - -#![crate_type = "lib"] - -extern "Rust" { - fn f(x: [u8; 1024]); -} - -const A: [u8; 1024] = [0; 1024]; - -// CHECK-LABEL: @const_arg_indirect -#[no_mangle] -pub unsafe fn const_arg_indirect() { - // Ensure that the live ranges for the two argument temporaries don't overlap. - - // CHECK: call void @llvm.lifetime.start - // CHECK: call void @f - // CHECK: call void @llvm.lifetime.end - // CHECK: call void @llvm.lifetime.start - // CHECK: call void @f - // CHECK: call void @llvm.lifetime.end - - f(A); - f(A); -} -- cgit 1.4.1-3-g733a5 From 849cabf4c4a97f0a1c6320993b08bf8e6068e58f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 22 May 2025 11:55:22 +1000 Subject: Rename `kw::Empty` as `sym::empty`. Because the empty string is not a keyword. --- compiler/rustc_ast_lowering/src/format.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 6 ++--- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 6 ++--- compiler/rustc_resolve/src/rustdoc.rs | 6 ++--- compiler/rustc_span/src/symbol.rs | 27 +++++++++++----------- compiler/rustc_symbol_mangling/src/v0.rs | 4 ++-- .../clippy/clippy_lints/src/manual_string_new.rs | 4 ++-- .../clippy/clippy_lints/src/methods/or_fun_call.rs | 4 ++-- 9 files changed, 31 insertions(+), 32 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 0de0319c667..17b443b8ecc 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -6,7 +6,7 @@ use rustc_ast::*; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_session::config::FmtDebug; -use rustc_span::{Ident, Span, Symbol, kw, sym}; +use rustc_span::{Ident, Span, Symbol, sym}; use super::LoweringContext; @@ -418,7 +418,7 @@ fn expand_format_args<'hir>( &FormatArgsPiece::Placeholder(_) => { // Inject empty string before placeholders when not already preceded by a literal piece. if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) { - Some(ctx.expr_str(fmt.span, kw::Empty)) + Some(ctx.expr_str(fmt.span, sym::empty)) } else { None } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 5924c8991ad..f731613d67e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{Instance, Ty}; use rustc_middle::{bug, mir, ty}; use rustc_session::config::DebugInfo; -use rustc_span::{BytePos, Span, Symbol, hygiene, kw}; +use rustc_span::{BytePos, Span, Symbol, hygiene, sym}; use super::operand::{OperandRef, OperandValue}; use super::place::{PlaceRef, PlaceValue}; @@ -283,7 +283,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // (after #67586 gets fixed). None } else { - let name = kw::Empty; + let name = sym::empty; let decl = &self.mir.local_decls[local]; let dbg_var = if full_debug_info { self.adjusted_span_and_dbg_scope(decl.source_info).map( @@ -318,7 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None } else { Some(match whole_local_var.or(fallback_var.clone()) { - Some(var) if var.name != kw::Empty => var.name.to_string(), + Some(var) if var.name != sym::empty => var.name.to_string(), _ => format!("{local:?}"), }) }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fa1d1ec0a86..f63ab303689 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -85,7 +85,7 @@ impl From for LifetimeSyntax { fn from(ident: Ident) -> Self { let name = ident.name; - if name == kw::Empty { + if name == sym::empty { unreachable!("A lifetime name should never be empty"); } else if name == kw::UnderscoreLifetime { LifetimeSyntax::Anonymous diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5c0d0cf4796..1d024694049 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -35,7 +35,7 @@ use rustc_session::lint::builtin::{ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, }; use rustc_session::parse::feature_err; -use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, kw, sym}; +use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; @@ -936,7 +936,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span()); let attr_str = &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); - if doc_alias == kw::Empty { + if doc_alias == sym::empty { tcx.dcx().emit_err(errors::DocAliasEmpty { span, attr_str }); return; } @@ -1068,7 +1068,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } let doc_keyword = match meta.value_str() { - Some(value) if value != kw::Empty => value, + Some(value) if value != sym::empty => value, _ => return self.doc_attr_str_error(meta, "keyword"), }; diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index a32fe699016..d701410e4dc 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, sym}; use thin_vec::ThinVec; use tracing::{debug, trace}; @@ -157,7 +157,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { }; for fragment in docs { - if fragment.doc == kw::Empty { + if fragment.doc == sym::empty { continue; } @@ -177,7 +177,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { /// /// Note: remove the trailing newline where appropriate pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) { - if frag.doc == kw::Empty { + if frag.doc == sym::empty { out.push('\n'); return; } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fbe3b4ca6f5..befc5bbff52 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -34,17 +34,8 @@ symbols! { // unnamed method parameters, crate root module, error recovery etc. // Matching predicates: `is_special`/`is_reserved` // - // Notes about `kw::Empty`: - // - Its use can blur the lines between "empty symbol" and "no symbol". - // Using `Option` is preferable, where possible, because that - // is unambiguous. - // - For dummy symbols that are never used and absolutely must be - // present, it's better to use `sym::dummy` than `kw::Empty`, because - // it's clearer that it's intended as a dummy value, and more likely - // to be detected if it accidentally does get used. // tidy-alphabetical-start DollarCrate: "$crate", - Empty: "", PathRoot: "{{root}}", Underscore: "_", // tidy-alphabetical-end @@ -864,7 +855,7 @@ symbols! { drop_types_in_const, dropck_eyepatch, dropck_parametricity, - dummy: "", // use this instead of `kw::Empty` for symbols that won't be used + dummy: "", // use this instead of `sym::empty` for symbols that won't be used dummy_cgu_name, dylib, dyn_compatible_for_dispatch, @@ -883,6 +874,14 @@ symbols! { emit_enum_variant_arg, emit_struct, emit_struct_field, + // Notes about `sym::empty`: + // - It should only be used when it genuinely means "empty symbol". Use + // `Option` when "no symbol" is a possibility. + // - For dummy symbols that are never used and absolutely must be + // present, it's better to use `sym::dummy` than `sym::empty`, because + // it's clearer that it's intended as a dummy value, and more likely + // to be detected if it accidentally does get used. + empty: "", emscripten_wasm_eh, enable, encode, @@ -2362,7 +2361,7 @@ impl Ident { #[inline] /// Constructs a new identifier from a symbol and a span. pub fn new(name: Symbol, span: Span) -> Ident { - debug_assert_ne!(name, kw::Empty); + debug_assert_ne!(name, sym::empty); Ident { name, span } } @@ -2584,7 +2583,7 @@ impl Symbol { } pub fn is_empty(self) -> bool { - self == kw::Empty + self == sym::empty } /// This method is supposed to be used in error messages, so it's expected to be @@ -2593,7 +2592,7 @@ impl Symbol { /// or edition, so we have to guess the rawness using the global edition. pub fn to_ident_string(self) -> String { // Avoid creating an empty identifier, because that asserts in debug builds. - if self == kw::Empty { String::new() } else { Ident::with_dummy_span(self).to_string() } + if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() } } } @@ -2773,7 +2772,7 @@ impl Symbol { /// Returns `true` if this symbol can be a raw identifier. pub fn can_be_raw(self) -> bool { - self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword() + self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword() } /// Was this symbol predefined in the compiler's `symbols!` macro diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 4a99ce09b39..644031af859 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{ self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, UintTy, }; -use rustc_span::kw; +use rustc_span::sym; pub(super) fn mangle<'tcx>( tcx: TyCtxt<'tcx>, @@ -902,7 +902,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { print_prefix, ns, disambiguated_data.disambiguator as u64, - name.unwrap_or(kw::Empty).as_str(), + name.unwrap_or(sym::empty).as_str(), ) } diff --git a/src/tools/clippy/clippy_lints/src/manual_string_new.rs b/src/tools/clippy/clippy_lints/src/manual_string_new.rs index 7ca3b712066..73ee1c3c78a 100644 --- a/src/tools/clippy/clippy_lints/src/manual_string_new.rs +++ b/src/tools/clippy/clippy_lints/src/manual_string_new.rs @@ -5,7 +5,7 @@ use rustc_hir::{Expr, ExprKind, PathSegment, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::declare_lint_pass; -use rustc_span::{Span, sym, symbol}; +use rustc_span::{Span, sym}; declare_clippy_lint! { /// ### What it does @@ -67,7 +67,7 @@ impl LateLintPass<'_> for ManualStringNew { fn is_expr_kind_empty_str(expr_kind: &ExprKind<'_>) -> bool { if let ExprKind::Lit(lit) = expr_kind && let LitKind::Str(value, _) = lit.node - && value == symbol::kw::Empty + && value == sym::empty { return true; } diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index c74c42e9e5b..38cb4d51ca0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -12,7 +12,7 @@ use rustc_errors::Applicability; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Span; -use rustc_span::symbol::{self, Symbol}; +use rustc_span::Symbol; use {rustc_ast as ast, rustc_hir as hir}; use super::{OR_FUN_CALL, UNWRAP_OR_DEFAULT}; @@ -265,7 +265,7 @@ fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) && ident.name == sym::to_string && let hir::Expr { kind, .. } = self_arg && let hir::ExprKind::Lit(lit) = kind - && let ast::LitKind::Str(symbol::kw::Empty, _) = lit.node + && let ast::LitKind::Str(rustc_span::sym::empty, _) = lit.node { return true; } -- cgit 1.4.1-3-g733a5 From 3c020e59a24a7739968fbd891a09e316a86c7b40 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 1 May 2025 11:34:52 +0200 Subject: make enabling the neon target feature a FCW --- compiler/rustc_codegen_ssa/messages.ftl | 2 + compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 1 + compiler/rustc_codegen_ssa/src/errors.rs | 4 ++ compiler/rustc_codegen_ssa/src/target_features.rs | 23 +++++++-- compiler/rustc_lint_defs/src/builtin.rs | 58 +++++++++++++++++++--- ...bi-incompatible-target-feature-attribute-fcw.rs | 14 ++++++ ...ncompatible-target-feature-attribute-fcw.stderr | 31 ++++++++++++ 7 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs create mode 100644 tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 2621935eecf..acb4cbaa13f 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -1,5 +1,7 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender +codegen_ssa_aarch64_softfloat_neon = enabling the `neon` target feature on the current target is unsound due to ABI issues + codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index aa55a0e0f14..b3bda784d43 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -299,6 +299,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } from_target_feature_attr( tcx, + did, attr, rust_target_features, &mut codegen_fn_attrs.target_features, diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index d49aac75d05..572d7b1e06a 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1316,3 +1316,7 @@ pub(crate) struct XcrunSdkPathWarning { pub sdk_name: &'static str, pub stderr: String, } + +#[derive(LintDiagnostic)] +#[diag(codegen_ssa_aarch64_softfloat_neon)] +pub(crate) struct Aarch64SoftfloatNeon; diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 3ecea522837..6bb3150c1c5 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -8,6 +8,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_middle::middle::codegen_fn_attrs::TargetFeature; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; +use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; use rustc_target::target_features::{self, Stability}; @@ -18,6 +19,7 @@ use crate::errors; /// Enabled target features are added to `target_features`. pub(crate) fn from_target_feature_attr( tcx: TyCtxt<'_>, + did: LocalDefId, attr: &hir::Attribute, rust_target_features: &UnordMap, target_features: &mut Vec, @@ -92,11 +94,22 @@ pub(crate) fn from_target_feature_attr( // generating code so "it's fine". if !tcx.sess.opts.actually_rustdoc { if abi_feature_constraints.incompatible.contains(&name.as_str()) { - tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { - span: item.span(), - feature: name.as_str(), - reason: "this feature is incompatible with the target ABI", - }); + // For "neon" specifically, we emit an FCW instead of a hard error. + // See . + if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" { + tcx.emit_node_span_lint( + AARCH64_SOFTFLOAT_NEON, + tcx.local_def_id_to_hir_id(did), + item.span(), + errors::Aarch64SoftfloatNeon, + ); + } else { + tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { + span: item.span(), + feature: name.as_str(), + reason: "this feature is incompatible with the target ABI", + }); + } } } target_features.push(TargetFeature { name, implied: name != feature_sym }) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3cea24634fe..b8d242bad86 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -16,6 +16,7 @@ declare_lint_pass! { /// that are used by other parts of the compiler. HardwiredLints => [ // tidy-alphabetical-start + AARCH64_SOFTFLOAT_NEON, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_ASSOCIATED_ITEMS, AMBIGUOUS_GLOB_IMPORTS, @@ -5043,14 +5044,14 @@ declare_lint! { /// /// ```text /// error: this function function definition is affected by the wasm ABI transition: it passes an argument of non-scalar type `MyType` - /// --> $DIR/wasm_c_abi_transition.rs:17:1 - /// | - /// | pub extern "C" fn my_fun(_x: MyType) {} - /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - /// | - /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - /// = note: for more information, see issue #138762 - /// = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target + /// --> $DIR/wasm_c_abi_transition.rs:17:1 + /// | + /// | pub extern "C" fn my_fun(_x: MyType) {} + /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// | + /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + /// = note: for more information, see issue #138762 + /// = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target /// ``` /// /// ### Explanation @@ -5067,3 +5068,44 @@ declare_lint! { reference: "issue #138762 ", }; } + +declare_lint! { + /// The `aarch64_softfloat_neon` lint detects usage of `#[target_feature(enable = "neon")]` on + /// softfloat aarch64 targets. Enabling this target feature causes LLVM to alter the ABI of + /// function calls, making this attribute unsound to use. + /// + /// ### Example + /// + /// ```rust,ignore (needs aarch64-unknown-none-softfloat) + /// #[target_feature(enable = "neon")] + /// fn with_neon() {} + /// ``` + /// + /// This will produce: + /// + /// ```text + /// error: enabling the `neon` target feature on the current target is unsound due to ABI issues + /// --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18 + /// | + /// | #[target_feature(enable = "neon")] + /// | ^^^^^^^^^^^^^^^ + /// | + /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + /// = note: for more information, see issue #134375 + /// ``` + /// + /// ### Explanation + /// + /// If a function like `with_neon` above ends up containing calls to LLVM builtins, those will + /// not use the correct ABI. This is caused by a lack of support in LLVM for mixing code with + /// and without the `neon` target feature. The target feature should never have been stabilized + /// on this target due to this issue, but the problem was not known at the time of + /// stabilization. + pub AARCH64_SOFTFLOAT_NEON, + Warn, + "detects code that could be affected by ABI issues on aarch64 softfloat targets", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reference: "issue #134375 ", + }; +} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs new file mode 100644 index 00000000000..270874a9f58 --- /dev/null +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --crate-type=lib +//@ compile-flags: --target=aarch64-unknown-none-softfloat +//@ needs-llvm-components: aarch64 +#![feature(no_core, lang_items)] +#![no_core] +#![deny(aarch64_softfloat_neon)] + +#[lang = "sized"] +pub trait Sized {} + +#[target_feature(enable = "neon")] +//~^ERROR: enabling the `neon` target feature on the current target is unsound +//~|WARN: previously accepted +pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr new file mode 100644 index 00000000000..bf745291a5a --- /dev/null +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr @@ -0,0 +1,31 @@ +error: enabling the `neon` target feature on the current target is unsound due to ABI issues + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18 + | +LL | #[target_feature(enable = "neon")] + | ^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #134375 +note: the lint level is defined here + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:6:9 + | +LL | #![deny(aarch64_softfloat_neon)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: enabling the `neon` target feature on the current target is unsound due to ABI issues + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18 + | +LL | #[target_feature(enable = "neon")] + | ^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #134375 +note: the lint level is defined here + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:6:9 + | +LL | #![deny(aarch64_softfloat_neon)] + | ^^^^^^^^^^^^^^^^^^^^^^ + -- cgit 1.4.1-3-g733a5 From caf665e692d74085e28a62ce4497eb7f02c5f37f Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Wed, 21 May 2025 16:21:00 -0700 Subject: Use the fn_span when emitting function calls for better debug info. This especially improves the developer experience for long chains of function calls that span multiple lines, which is common with builder patterns, chains of iterator/future combinators, etc. --- compiler/rustc_codegen_ssa/src/mir/block.rs | 1 + tests/debuginfo/multiline-calls.rs | 35 ++++++++++++++++++++++ .../ui/panics/location-detail-unwrap-multiline.rs | 11 +++++++ 3 files changed, 47 insertions(+) create mode 100644 tests/debuginfo/multiline-calls.rs create mode 100644 tests/ui/panics/location-detail-unwrap-multiline.rs (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 950f19a6f0f..600d6ff6801 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1181,6 +1181,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (_, Some(llfn)) => llfn, _ => span_bug!(span, "no instance or llfn for call"), }; + self.set_debug_loc(bx, mir::SourceInfo { span: fn_span, ..source_info }); helper.do_call( self, bx, diff --git a/tests/debuginfo/multiline-calls.rs b/tests/debuginfo/multiline-calls.rs new file mode 100644 index 00000000000..724ad29729f --- /dev/null +++ b/tests/debuginfo/multiline-calls.rs @@ -0,0 +1,35 @@ +//@ compile-flags:-g +//@ min-gdb-version: 16.0 + +// === GDB TESTS =================================================================================== + +// gdb-command: run +// gdb-check:[...]#break[...] +// gdb-command: up +// gdb-check:[...]zzz[...] + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-check:[...]#break[...] +// lldb-command: up +// lldb-check:[...]zzz[...] + +struct Foo; + +impl Foo { + fn bar(self) -> Foo { + println!("bar"); + self + } + fn baz(self) -> Foo { + println!("baz"); // #break + self + } +} + +fn main() { + let f = Foo; + f.bar() // aaa + .baz(); // zzz +} diff --git a/tests/ui/panics/location-detail-unwrap-multiline.rs b/tests/ui/panics/location-detail-unwrap-multiline.rs new file mode 100644 index 00000000000..afe15a579c4 --- /dev/null +++ b/tests/ui/panics/location-detail-unwrap-multiline.rs @@ -0,0 +1,11 @@ +//@ run-fail +//@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only -Copt-level=0 +//@ exec-env:RUST_BACKTRACE=1 +//@ regex-error-pattern: location-detail-unwrap-multiline\.rs:10(:10)?\n +//@ needs-unwind + +fn main() { + let opt: Option = None; + opt + .unwrap(); +} -- cgit 1.4.1-3-g733a5 From fa2bb599bcf36b5390d5c8156cba6bc980ddbfca Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sat, 24 May 2025 19:50:11 +0200 Subject: Cleanup CodegenFnAttrFlags - Rename `USED` to `USED_COMPILER` to better reflect its behavior. - Reorder some items to group the used and allocator flags together - Renumber them without gaps --- compiler/rustc_codegen_gcc/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/consts.rs | 4 +- .../rustc_codegen_ssa/src/back/symbol_export.rs | 2 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +- .../rustc_middle/src/middle/codegen_fn_attrs.rs | 45 ++++++++++------------ compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 2 +- src/tools/miri/src/bin/miri.rs | 2 +- src/tools/miri/src/helpers.rs | 2 +- 9 files changed, 31 insertions(+), 34 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 033afc0f8fb..8aed04c836a 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -154,7 +154,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): set link section. } - if attrs.flags.contains(CodegenFnAttrFlags::USED) + if attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { self.add_used_global(global.to_rvalue()); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index bf81eb648f8..fe2f2027327 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -527,7 +527,7 @@ impl<'ll> CodegenCx<'ll, '_> { base::set_variable_sanitizer_attrs(g, attrs); - if attrs.flags.contains(CodegenFnAttrFlags::USED) { + if attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) { // `USED` and `USED_LINKER` can't be used together. assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)); @@ -551,7 +551,7 @@ impl<'ll> CodegenCx<'ll, '_> { } if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { // `USED` and `USED_LINKER` can't be used together. - assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED)); + assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)); self.add_used_global(g); } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 96aec9769d2..e26f999773d 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -128,7 +128,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap, did: LocalDefId) -> CodegenFnAttrs { ) .emit(); } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER; } Some(_) => { tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() }); @@ -220,7 +220,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { || tcx.sess.target.is_like_windows || tcx.sess.target.is_like_wasm); codegen_fn_attrs.flags |= if is_like_elf { - CodegenFnAttrFlags::USED + CodegenFnAttrFlags::USED_COMPILER } else { CodegenFnAttrFlags::USED_LINKER }; diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 00da1a6aeec..f21cf5fa45e 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -96,49 +96,46 @@ bitflags::bitflags! { /// `#[cold]`: a hint to LLVM that this function, when called, is never on /// the hot path. const COLD = 1 << 0; - /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this - /// function is never null and the function has no side effects other than allocating. - const ALLOCATOR = 1 << 1; - /// An indicator that function will never unwind. Will become obsolete - /// once C-unwind is fully stabilized. - const NEVER_UNWIND = 1 << 3; + /// `#[rustc_nounwind]`: An indicator that function will never unwind. + const NEVER_UNWIND = 1 << 1; /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue /// should be generated. - const NAKED = 1 << 4; + const NAKED = 1 << 2; /// `#[no_mangle]`: an indicator that the function's name should be the same /// as its symbol. - const NO_MANGLE = 1 << 5; + const NO_MANGLE = 1 << 3; /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a /// "weird symbol" for the standard library in that it has slightly /// different linkage, visibility, and reachability rules. - const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6; + const RUSTC_STD_INTERNAL_SYMBOL = 1 << 4; /// `#[thread_local]`: indicates a static is actually a thread local /// piece of memory - const THREAD_LOCAL = 1 << 8; - /// `#[used]`: indicates that LLVM can't eliminate this function (but the + const THREAD_LOCAL = 1 << 5; + /// `#[used(compiler)]`: indicates that LLVM can't eliminate this function (but the /// linker can!). - const USED = 1 << 9; + const USED_COMPILER = 1 << 6; + /// `#[used(linker)]`: + /// indicates that neither LLVM nor the linker will eliminate this function. + const USED_LINKER = 1 << 7; /// `#[track_caller]`: allow access to the caller location - const TRACK_CALLER = 1 << 10; + const TRACK_CALLER = 1 << 8; /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function /// declaration. - const FFI_PURE = 1 << 11; + const FFI_PURE = 1 << 9; /// #[ffi_const]: applies clang's `const` attribute to a foreign function /// declaration. - const FFI_CONST = 1 << 12; - // (Bit 13 was used for `#[cmse_nonsecure_entry]`, but is now unused.) - // (Bit 14 was used for `#[coverage(off)]`, but is now unused.) - /// `#[used(linker)]`: - /// indicates that neither LLVM nor the linker will eliminate this function. - const USED_LINKER = 1 << 15; + const FFI_CONST = 1 << 10; + /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this + /// function is never null and the function has no side effects other than allocating. + const ALLOCATOR = 1 << 11; /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory. - const DEALLOCATOR = 1 << 16; + const DEALLOCATOR = 1 << 12; /// `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory. - const REALLOCATOR = 1 << 17; + const REALLOCATOR = 1 << 13; /// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory. - const ALLOCATOR_ZEROED = 1 << 18; + const ALLOCATOR_ZEROED = 1 << 14; /// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function. - const NO_BUILTINS = 1 << 19; + const NO_BUILTINS = 1 << 15; } } rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 0060e726a8e..6e5357d8007 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -707,7 +707,7 @@ fn has_allow_dead_code_or_lang_attr( // #[used], #[no_mangle], #[export_name], etc also keeps the item alive // forcefully, e.g., for placing it in a specific section. cg_attrs.contains_extern_indicator() - || cg_attrs.flags.contains(CodegenFnAttrFlags::USED) + || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f0e8fa986fe..7e15267a953 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -427,7 +427,7 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 469fc264970..7098ef5130d 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -281,7 +281,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { } let codegen_fn_attrs = tcx.codegen_fn_attrs(local_def_id); if codegen_fn_attrs.contains_extern_indicator() - || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED) + || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { Some(( diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index ff2ec1b3e60..6a6adc966a8 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -135,7 +135,7 @@ pub fn iter_exported_symbols<'tcx>( let codegen_attrs = tcx.codegen_fn_attrs(def_id); codegen_attrs.contains_extern_indicator() || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) }; if exported { -- cgit 1.4.1-3-g733a5 From 1e9e17704adfc6bd6b01a0031b73fbc1682a0f1f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 21 May 2025 15:34:15 +0000 Subject: Move some code around in codegen_call_terminator --- compiler/rustc_codegen_ssa/src/mir/block.rs | 202 ++++++++++++++-------------- 1 file changed, 103 insertions(+), 99 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 922b8a5824b..de827a475c4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -8,7 +8,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::ty::{self, Instance, List, Ty}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::source_map::Spanned; @@ -827,7 +827,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { helper: &TerminatorCodegenHelper<'tcx>, bx: &mut Bx, intrinsic: ty::IntrinsicDef, - instance: Option>, + instance: Instance<'tcx>, source_info: mir::SourceInfo, target: Option, unwind: mir::UnwindAction, @@ -837,7 +837,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // These are intrinsics that compile to panics so that we can get a message // which mentions the offending type, even from a const context. if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) { - let ty = instance.unwrap().args.type_at(0); + let ty = instance.args.type_at(0); let do_panic = !bx .tcx() @@ -910,35 +910,116 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let callee = self.codegen_operand(bx, func); let (instance, mut llfn) = match *callee.layout.ty.kind() { - ty::FnDef(def_id, args) => ( - Some(ty::Instance::expect_resolve( + ty::FnDef(def_id, generic_args) => { + let instance = ty::Instance::expect_resolve( bx.tcx(), bx.typing_env(), def_id, - args, + generic_args, fn_span, - )), - None, - ), + ); + + let instance = match instance.def { + // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, + // it is `func returning noop future` + ty::InstanceKind::DropGlue(_, None) => { + // Empty drop glue; a no-op. + let target = target.unwrap(); + return helper.funclet_br(self, bx, target, mergeable_succ); + } + ty::InstanceKind::Intrinsic(def_id) => { + let intrinsic = bx.tcx().intrinsic(def_id).unwrap(); + if let Some(merging_succ) = self.codegen_panic_intrinsic( + &helper, + bx, + intrinsic, + instance, + source_info, + target, + unwind, + mergeable_succ, + ) { + return merging_succ; + } + + let fn_abi = bx.fn_abi_of_instance(instance, List::empty()); + + let mut llargs = Vec::with_capacity(1); + let ret_dest = self.make_return_dest( + bx, + destination, + &fn_abi.ret, + &mut llargs, + Some(intrinsic), + ); + let dest = match ret_dest { + _ if fn_abi.ret.is_indirect() => llargs[0], + ReturnDest::Nothing => bx.const_undef(bx.type_ptr()), + ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => { + dst.val.llval + } + ReturnDest::DirectOperand(_) => { + bug!("Cannot use direct operand with an intrinsic call") + } + }; + + let args: Vec<_> = + args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect(); + + if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) + { + let location = self.get_caller_location( + bx, + mir::SourceInfo { span: fn_span, ..source_info }, + ); + + assert_eq!(llargs, []); + if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { + location.val.store(bx, tmp); + } + self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); + return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); + } + + match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) + { + Ok(()) => { + if let ReturnDest::IndirectOperand(dst, _) = ret_dest { + self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval); + } + + return if let Some(target) = target { + helper.funclet_br(self, bx, target, mergeable_succ) + } else { + bx.unreachable(); + MergingSucc::False + }; + } + Err(instance) => { + if intrinsic.must_be_overridden { + span_bug!( + span, + "intrinsic {} must be overridden by codegen backend, but isn't", + intrinsic.name, + ); + } + instance + } + } + } + _ => instance, + }; + + (Some(instance), None) + } ty::FnPtr(..) => (None, Some(callee.immediate())), _ => bug!("{} is not callable", callee.layout.ty), }; - let def = instance.map(|i| i.def); - - // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, - // it is `func returning noop future` - if let Some(ty::InstanceKind::DropGlue(_, None)) = def { - // Empty drop glue; a no-op. - let target = target.unwrap(); - return helper.funclet_br(self, bx, target, mergeable_succ); - } - // FIXME(eddyb) avoid computing this if possible, when `instance` is // available - right now `sig` is only needed for getting the `abi` // and figuring out how many extra args were passed to a C-variadic `fn`. let sig = callee.layout.ty.fn_sig(bx.tcx()); - let abi = sig.abi(); let extra_args = &args[sig.inputs().skip_binder().len()..]; let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| { @@ -954,83 +1035,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; - let instance = match def { - Some(ty::InstanceKind::Intrinsic(def_id)) => { - let intrinsic = bx.tcx().intrinsic(def_id).unwrap(); - if let Some(merging_succ) = self.codegen_panic_intrinsic( - &helper, - bx, - intrinsic, - instance, - source_info, - target, - unwind, - mergeable_succ, - ) { - return merging_succ; - } - - let mut llargs = Vec::with_capacity(1); - let ret_dest = self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - Some(intrinsic), - ); - let dest = match ret_dest { - _ if fn_abi.ret.is_indirect() => llargs[0], - ReturnDest::Nothing => bx.const_undef(bx.type_ptr()), - ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.val.llval, - ReturnDest::DirectOperand(_) => { - bug!("Cannot use direct operand with an intrinsic call") - } - }; - - let args: Vec<_> = - args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect(); - - if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) { - let location = self - .get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); - - assert_eq!(llargs, []); - if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { - location.val.store(bx, tmp); - } - self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); - return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); - } - - let instance = *instance.as_ref().unwrap(); - match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) { - Ok(()) => { - if let ReturnDest::IndirectOperand(dst, _) = ret_dest { - self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval); - } - - return if let Some(target) = target { - helper.funclet_br(self, bx, target, mergeable_succ) - } else { - bx.unreachable(); - MergingSucc::False - }; - } - Err(instance) => { - if intrinsic.must_be_overridden { - span_bug!( - span, - "intrinsic {} must be overridden by codegen backend, but isn't", - intrinsic.name, - ); - } - Some(instance) - } - } - } - _ => instance, - }; - let mut llargs = Vec::with_capacity(arg_count); // We still need to call `make_return_dest` even if there's no `target`, since @@ -1040,7 +1044,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let destination = target.map(|target| (return_dest, target)); // Split the rust-call tupled arguments off. - let (first_args, untuple) = if abi == ExternAbi::RustCall + let (first_args, untuple) = if sig.abi() == ExternAbi::RustCall && let Some((tup, args)) = args.split_last() { (args, Some(tup)) @@ -1055,7 +1059,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { 'make_args: for (i, arg) in first_args.iter().enumerate() { let mut op = self.codegen_operand(bx, &arg.node); - if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, def) { + if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, instance.map(|i| i.def)) { match op.val { Pair(data_ptr, meta) => { // In the case of Rc, we need to explicitly pass a -- cgit 1.4.1-3-g733a5 From e4700e76d83428a99f2c7a8b19d3bf50606cf7e1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 11:17:51 +0000 Subject: Always use fn_span in codegen_call_terminator --- compiler/rustc_codegen_ssa/src/mir/block.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index de827a475c4..beb13ba28bc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -903,8 +903,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_span: Span, mergeable_succ: bool, ) -> MergingSucc { - let source_info = terminator.source_info; - let span = source_info.span; + let source_info = mir::SourceInfo { span: fn_span, ..terminator.source_info }; // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar. let callee = self.codegen_operand(bx, func); @@ -968,10 +967,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) { - let location = self.get_caller_location( - bx, - mir::SourceInfo { span: fn_span, ..source_info }, - ); + let location = self.get_caller_location(bx, source_info); assert_eq!(llargs, []); if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { @@ -981,8 +977,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); } - match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) - { + match Self::codegen_intrinsic_call( + bx, instance, fn_abi, &args, dest, fn_span, + ) { Ok(()) => { if let ReturnDest::IndirectOperand(dst, _) = ret_dest { self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval); @@ -998,7 +995,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Err(instance) => { if intrinsic.must_be_overridden { span_bug!( - span, + fn_span, "intrinsic {} must be overridden by codegen backend, but isn't", intrinsic.name, ); @@ -1113,7 +1110,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Make sure that we've actually unwrapped the rcvr down // to a pointer or ref to `dyn* Trait`. if !op.layout.ty.builtin_deref(true).unwrap().is_dyn_star() { - span_bug!(span, "can't codegen a virtual call on {:#?}", op); + span_bug!(fn_span, "can't codegen a virtual call on {:#?}", op); } let place = op.deref(bx.cx()); let data_place = place.project_field(bx, 0); @@ -1129,7 +1126,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { continue; } _ => { - span_bug!(span, "can't codegen a virtual call on {:#?}", op); + span_bug!(fn_span, "can't codegen a virtual call on {:#?}", op); } } } @@ -1179,8 +1176,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir_args + 1, "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR: {instance:?} {fn_span:?} {fn_abi:?}", ); - let location = - self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); + let location = self.get_caller_location(bx, source_info); debug!( "codegen_call_terminator({:?}): location={:?} (fn_span {:?})", terminator, location, fn_span @@ -1199,9 +1195,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ptr = match (instance, llfn) { (Some(instance), None) => bx.get_fn_addr(instance), (_, Some(llfn)) => llfn, - _ => span_bug!(span, "no instance or llfn for call"), + _ => span_bug!(fn_span, "no instance or llfn for call"), }; - self.set_debug_loc(bx, mir::SourceInfo { span: fn_span, ..source_info }); + self.set_debug_loc(bx, source_info); helper.do_call( self, bx, -- cgit 1.4.1-3-g733a5 From c83358beb5f40a8b1c6e422f229ca4db1f927599 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 13:50:47 +0000 Subject: Move caller_location handling into codegen_intrinsic_call --- compiler/rustc_codegen_ssa/src/mir/block.rs | 25 +++++++++---------------- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 13 +++++++++++-- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index beb13ba28bc..1d11b907e90 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -11,8 +11,8 @@ use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, List, Ty}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; +use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_span::{Span, sym}; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use tracing::{debug, info}; @@ -965,20 +965,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let args: Vec<_> = args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect(); - if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) - { - let location = self.get_caller_location(bx, source_info); - - assert_eq!(llargs, []); - if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { - location.val.store(bx, tmp); - } - self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); - return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); - } - - match Self::codegen_intrinsic_call( - bx, instance, fn_abi, &args, dest, fn_span, + match self.codegen_intrinsic_call( + bx, + instance, + fn_abi, + &args, + dest, + source_info, ) { Ok(()) => { if let ReturnDest::IndirectOperand(dst, _) = ret_dest { @@ -1667,7 +1660,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { tuple.layout.fields.count() } - fn get_caller_location( + pub(super) fn get_caller_location( &mut self, bx: &mut Bx, source_info: mir::SourceInfo, diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index b0fcfee2adf..6cdd8480cbe 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,8 +1,9 @@ use rustc_abi::WrappingRange; +use rustc_middle::mir::SourceInfo; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; -use rustc_span::{Span, sym}; +use rustc_span::sym; use rustc_target::callconv::{FnAbi, PassMode}; use super::FunctionCx; @@ -52,13 +53,15 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// In the `Err` case, returns the instance that should be called instead. pub fn codegen_intrinsic_call( + &mut self, bx: &mut Bx, instance: ty::Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Bx::Value>], llresult: Bx::Value, - span: Span, + source_info: SourceInfo, ) -> Result<(), ty::Instance<'tcx>> { + let span = source_info.span; let callee_ty = instance.ty(bx.tcx(), bx.typing_env()); let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else { @@ -105,6 +108,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return Ok(()); } + sym::caller_location => { + let location = self.get_caller_location(bx, source_info); + location.val.store(bx, result); + return Ok(()); + } + sym::va_start => bx.va_start(args[0].immediate()), sym::va_end => bx.va_end(args[0].immediate()), sym::size_of_val => { -- cgit 1.4.1-3-g733a5 From 6016f84e716c443f64c491a26f5ec1dfd42f2491 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 14:15:41 +0000 Subject: Pass PlaceRef rather than Bx::Value to codegen_intrinsic_call --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 21 ++++----- compiler/rustc_codegen_llvm/src/intrinsic.rs | 50 ++++++++++------------ compiler/rustc_codegen_ssa/src/mir/block.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 5 +-- compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 3 +- 5 files changed, 38 insertions(+), 45 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index ba65c8205a5..18dabe9ea16 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -22,7 +22,7 @@ use rustc_codegen_ssa::traits::{ }; use rustc_middle::bug; #[cfg(feature = "master")] -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; @@ -202,7 +202,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], - llresult: RValue<'gcc>, + result: PlaceRef<'tcx, RValue<'gcc>>, span: Span, ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; @@ -221,7 +221,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let name_str = name.as_str(); let llret_ty = self.layout_of(ret_ty).gcc_type(self); - let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); @@ -271,7 +270,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc args[0].immediate(), args[1].immediate(), args[2].immediate(), - llresult, + result, ); return Ok(()); } @@ -1230,14 +1229,13 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, - dest: RValue<'gcc>, + dest: PlaceRef<'tcx, RValue<'gcc>>, ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { bx.call(bx.type_void(), None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. - let ret_align = bx.tcx.data_layout.i32_align.abi; - bx.store(bx.const_i32(0), dest, ret_align); + OperandValue::Immediate(bx.const_i32(0)).store(bx, dest); } else { if wants_msvc_seh(bx.sess()) { unimplemented!(); @@ -1261,12 +1259,12 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. #[cfg(feature = "master")] -fn codegen_gnu_try<'gcc>( - bx: &mut Builder<'_, 'gcc, '_>, +fn codegen_gnu_try<'gcc, 'tcx>( + bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue<'gcc>, data: RValue<'gcc>, catch_func: RValue<'gcc>, - dest: RValue<'gcc>, + dest: PlaceRef<'tcx, RValue<'gcc>>, ) { let cx: &CodegenCx<'gcc, '_> = bx.cx; let (llty, func) = get_rust_try_fn(cx, &mut |mut bx| { @@ -1322,8 +1320,7 @@ fn codegen_gnu_try<'gcc>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // Helper function used to get a handle to the `__rust_try` function used to diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 5ca57375292..067dd9b1681 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -167,7 +167,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { instance: ty::Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, &'ll Value>], - llresult: &'ll Value, + result: PlaceRef<'tcx, &'ll Value>, span: Span, ) -> Result<(), ty::Instance<'tcx>> { let tcx = self.tcx; @@ -184,7 +184,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let name = tcx.item_name(def_id); let llret_ty = self.layout_of(ret_ty).llvm_type(self); - let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); let llval = match name { @@ -255,7 +254,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { args[0].immediate(), args[1].immediate(), args[2].immediate(), - llresult, + result, ); return Ok(()); } @@ -688,20 +687,19 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } -fn catch_unwind_intrinsic<'ll>( - bx: &mut Builder<'_, 'll, '_>, +fn catch_unwind_intrinsic<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, try_func: &'ll Value, data: &'ll Value, catch_func: &'ll Value, - dest: &'ll Value, + dest: PlaceRef<'tcx, &'ll Value>, ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void()); bx.call(try_func_ty, None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. - let ret_align = bx.tcx().data_layout.i32_align.abi; - bx.store(bx.const_i32(0), dest, ret_align); + OperandValue::Immediate(bx.const_i32(0)).store(bx, dest); } else if wants_msvc_seh(bx.sess()) { codegen_msvc_try(bx, try_func, data, catch_func, dest); } else if wants_wasm_eh(bx.sess()) { @@ -720,12 +718,12 @@ fn catch_unwind_intrinsic<'ll>( // instructions are meant to work for all targets, as of the time of this // writing, however, LLVM does not recommend the usage of these new instructions // as the old ones are still more optimized. -fn codegen_msvc_try<'ll>( - bx: &mut Builder<'_, 'll, '_>, +fn codegen_msvc_try<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, try_func: &'ll Value, data: &'ll Value, catch_func: &'ll Value, - dest: &'ll Value, + dest: PlaceRef<'tcx, &'ll Value>, ) { let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { bx.set_personality_fn(bx.eh_personality()); @@ -865,17 +863,16 @@ fn codegen_msvc_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // WASM's definition of the `rust_try` function. -fn codegen_wasm_try<'ll>( - bx: &mut Builder<'_, 'll, '_>, +fn codegen_wasm_try<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, try_func: &'ll Value, data: &'ll Value, catch_func: &'ll Value, - dest: &'ll Value, + dest: PlaceRef<'tcx, &'ll Value>, ) { let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { bx.set_personality_fn(bx.eh_personality()); @@ -939,8 +936,7 @@ fn codegen_wasm_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // Definition of the standard `try` function for Rust using the GNU-like model @@ -954,12 +950,12 @@ fn codegen_wasm_try<'ll>( // function calling it, and that function may already have other personality // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. -fn codegen_gnu_try<'ll>( - bx: &mut Builder<'_, 'll, '_>, +fn codegen_gnu_try<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, try_func: &'ll Value, data: &'ll Value, catch_func: &'ll Value, - dest: &'ll Value, + dest: PlaceRef<'tcx, &'ll Value>, ) { let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { // Codegens the shims described above: @@ -1006,19 +1002,18 @@ fn codegen_gnu_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // Variant of codegen_gnu_try used for emscripten where Rust panics are // implemented using C++ exceptions. Here we use exceptions of a specific type // (`struct rust_panic`) to represent Rust panics. -fn codegen_emcc_try<'ll>( - bx: &mut Builder<'_, 'll, '_>, +fn codegen_emcc_try<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, try_func: &'ll Value, data: &'ll Value, catch_func: &'ll Value, - dest: &'ll Value, + dest: PlaceRef<'tcx, &'ll Value>, ) { let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { // Codegens the shims described above: @@ -1089,8 +1084,7 @@ fn codegen_emcc_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); - let i32_align = bx.tcx().data_layout.i32_align.abi; - bx.store(ret, dest, i32_align); + OperandValue::Immediate(ret).store(bx, dest); } // Helper function to give a Block to a closure to codegen a shim function. diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1d11b907e90..1a291b17886 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -965,12 +965,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let args: Vec<_> = args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect(); + let result = PlaceRef::new_sized(dest, fn_abi.ret.layout); + match self.codegen_intrinsic_call( bx, instance, fn_abi, &args, - dest, + result, source_info, ) { Ok(()) => { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 6cdd8480cbe..6a077883298 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { instance: ty::Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Bx::Value>], - llresult: Bx::Value, + result: PlaceRef<'tcx, Bx::Value>, source_info: SourceInfo, ) -> Result<(), ty::Instance<'tcx>> { let span = source_info.span; @@ -100,7 +100,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } let llret_ty = bx.backend_type(bx.layout_of(ret_ty)); - let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let llval = match name { sym::abort => { @@ -537,7 +536,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => { // Need to use backend-specific things in the implementation. - return bx.codegen_intrinsic_call(instance, fn_abi, args, llresult, span); + return bx.codegen_intrinsic_call(instance, fn_abi, args, result, span); } }; diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 88cf8dbf0c5..f9d6dab6faf 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -4,6 +4,7 @@ use rustc_target::callconv::FnAbi; use super::BackendTypes; use crate::mir::operand::OperandRef; +use crate::mir::place::PlaceRef; pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`, @@ -16,7 +17,7 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { instance: ty::Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Self::Value>], - llresult: Self::Value, + result: PlaceRef<'tcx, Self::Value>, span: Span, ) -> Result<(), ty::Instance<'tcx>>; -- cgit 1.4.1-3-g733a5 From 0a14e1b2e7483179fa74f44d3c198c33325f6d29 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 14:58:58 +0000 Subject: Remove usage of FnAbi in codegen_intrinsic_call --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 32 ++++++++-------------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 30 +++++++------------- compiler/rustc_codegen_ssa/src/mir/block.rs | 10 ++----- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 18 +++++------- compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 4 +-- 5 files changed, 31 insertions(+), 63 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 18dabe9ea16..1bcb891a250 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, PassMode}; use rustc_target::spec::PanicStrategy; #[cfg(feature = "master")] @@ -200,7 +200,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc fn codegen_intrinsic_call( &mut self, instance: Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], result: PlaceRef<'tcx, RValue<'gcc>>, span: Span, @@ -285,17 +284,10 @@ 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(layout.gcc_type(self), ptr) - }; + let load = self.volatile_load(result.layout.gcc_type(self), ptr); // TODO(antoyo): set alignment. - if let BackendRepr::Scalar(scalar) = layout.backend_repr { + if let BackendRepr::Scalar(scalar) = result.layout.backend_repr { self.to_immediate_scalar(load, scalar) } else { load @@ -510,16 +502,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc _ => return Err(Instance::new_raw(instance.def_id(), instance.args)), }; - if !fn_abi.ret.is_ignore() { - if let PassMode::Cast { cast: ref ty, .. } = fn_abi.ret.mode { - let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); - let ptr = self.pointercast(result.val.llval, ptr_llty); - self.store(value, ptr, result.val.align); - } else { - OperandRef::from_immediate_or_packed_pair(self, value, result.layout) - .val - .store(self, result); - } + if result.layout.ty.is_bool() { + OperandRef::from_immediate_or_packed_pair(self, value, result.layout) + .val + .store(self, result); + } else if !result.layout.ty.is_unit() { + let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self)); + let ptr = self.pointercast(result.val.llval, ptr_llty); + self.store(value, ptr, result.val.align); } Ok(()) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 067dd9b1681..e8629aeebb9 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -15,11 +15,10 @@ use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use tracing::debug; -use crate::abi::{FnAbiLlvmExt, LlvmType}; +use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::context::CodegenCx; use crate::llvm::{self, Metadata}; @@ -165,7 +164,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, &'ll Value>], result: PlaceRef<'tcx, &'ll Value>, span: Span, @@ -263,7 +261,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.call_intrinsic("llvm.va_copy", &[args[0].immediate(), args[1].immediate()]) } sym::va_arg => { - match fn_abi.ret.layout.backend_repr { + match result.layout.backend_repr { BackendRepr::Scalar(scalar) => { match scalar.primitive() { Primitive::Int(..) => { @@ -298,18 +296,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::volatile_load | sym::unaligned_volatile_load => { - let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); - let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode { - let llty = ty.llvm_type(self); - self.volatile_load(llty, ptr) - } else { - self.volatile_load(self.layout_of(tp_ty).llvm_type(self), ptr) - }; + let load = self.volatile_load(result.layout.llvm_type(self), ptr); let align = if name == sym::unaligned_volatile_load { 1 } else { - self.align_of(tp_ty).bytes() as u32 + result.layout.align.abi.bytes() as u32 }; unsafe { llvm::LLVMSetAlignment(load, align); @@ -628,14 +620,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } }; - if !fn_abi.ret.is_ignore() { - if let PassMode::Cast { .. } = &fn_abi.ret.mode { - self.store(llval, result.val.llval, result.val.align); - } else { - OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) - .val - .store(self, result); - } + if result.layout.ty.is_bool() { + OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) + .val + .store(self, result); + } else if !result.layout.ty.is_unit() { + self.store_to_place(llval, result.val); } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1a291b17886..a2565c4f69d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -967,14 +967,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let result = PlaceRef::new_sized(dest, fn_abi.ret.layout); - match self.codegen_intrinsic_call( - bx, - instance, - fn_abi, - &args, - result, - source_info, - ) { + match self.codegen_intrinsic_call(bx, instance, &args, result, source_info) + { Ok(()) => { if let ReturnDest::IndirectOperand(dst, _) = ret_dest { self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 6a077883298..a6d159c51e1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -4,7 +4,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::sym; -use rustc_target::callconv::{FnAbi, PassMode}; use super::FunctionCx; use super::operand::OperandRef; @@ -56,7 +55,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, bx: &mut Bx, instance: ty::Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Bx::Value>], result: PlaceRef<'tcx, Bx::Value>, source_info: SourceInfo, @@ -536,18 +534,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => { // Need to use backend-specific things in the implementation. - return bx.codegen_intrinsic_call(instance, fn_abi, args, result, span); + return bx.codegen_intrinsic_call(instance, args, result, span); } }; - if !fn_abi.ret.is_ignore() { - if let PassMode::Cast { .. } = &fn_abi.ret.mode { - bx.store_to_place(llval, result.val); - } else { - OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) - .val - .store(bx, result); - } + if result.layout.ty.is_bool() { + OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) + .val + .store(bx, result); + } else if !result.layout.ty.is_unit() { + bx.store_to_place(llval, result.val); } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index f9d6dab6faf..a07c569a032 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -1,6 +1,5 @@ -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty; use rustc_span::Span; -use rustc_target::callconv::FnAbi; use super::BackendTypes; use crate::mir::operand::OperandRef; @@ -15,7 +14,6 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Self::Value>], result: PlaceRef<'tcx, Self::Value>, span: Span, -- cgit 1.4.1-3-g733a5 From 7122648e3403bbbd471cd2667d5960a109bb9bd7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 May 2025 17:49:28 +0000 Subject: Don't depend on FnAbi for intrinsics Intrinsics are not real functions and as such don't have any calling convention. Trying to compute a calling convention for an intrinsic anyway is a nonsensical operation. --- compiler/rustc_codegen_ssa/src/mir/block.rs | 74 ++++++++++++++++------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a2565c4f69d..cb8088e9efb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -8,7 +8,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Instance, List, Ty}; +use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::Span; @@ -941,37 +941,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return merging_succ; } - let fn_abi = bx.fn_abi_of_instance(instance, List::empty()); + let result_layout = + self.cx.layout_of(self.monomorphized_place_ty(destination.as_ref())); - let mut llargs = Vec::with_capacity(1); - let ret_dest = self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - Some(intrinsic), - ); - let dest = match ret_dest { - _ if fn_abi.ret.is_indirect() => llargs[0], - ReturnDest::Nothing => bx.const_undef(bx.type_ptr()), - ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => { - dst.val.llval - } - ReturnDest::DirectOperand(_) => { - bug!("Cannot use direct operand with an intrinsic call") + let (result, store_in_local) = if result_layout.is_zst() { + ( + PlaceRef::new_sized(bx.const_undef(bx.type_ptr()), result_layout), + None, + ) + } else if let Some(local) = destination.as_local() { + match self.locals[local] { + LocalRef::Place(dest) => (dest, None), + LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), + LocalRef::PendingOperand => { + // Currently, intrinsics always need a location to store + // the result, so we create a temporary `alloca` for the + // result. + let tmp = PlaceRef::alloca(bx, result_layout); + tmp.storage_live(bx); + (tmp, Some(local)) + } + LocalRef::Operand(_) => { + bug!("place local already assigned to"); + } } + } else { + (self.codegen_place(bx, destination.as_ref()), None) }; + if result.val.align < result.layout.align.abi { + // Currently, MIR code generation does not create calls + // that store directly to fields of packed structs (in + // fact, the calls it creates write only to temps). + // + // If someone changes that, please update this code path + // to create a temporary. + span_bug!(self.mir.span, "can't directly store to unaligned value"); + } + let args: Vec<_> = args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect(); - let result = PlaceRef::new_sized(dest, fn_abi.ret.layout); - match self.codegen_intrinsic_call(bx, instance, &args, result, source_info) { Ok(()) => { - if let ReturnDest::IndirectOperand(dst, _) = ret_dest { - self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval); + if let Some(local) = store_in_local { + let op = bx.load_operand(result); + result.storage_dead(bx); + self.overwrite_local(local, LocalRef::Operand(op)); + self.debug_introduce_local(bx, local); } return if let Some(target) = target { @@ -1026,7 +1044,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // We still need to call `make_return_dest` even if there's no `target`, since // `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited, // and `make_return_dest` adds the return-place indirect pointer to `llargs`. - let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, None); + let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs); let destination = target.map(|target| (return_dest, target)); // Split the rust-call tupled arguments off. @@ -1857,7 +1875,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dest: mir::Place<'tcx>, fn_ret: &ArgAbi<'tcx, Ty<'tcx>>, llargs: &mut Vec, - intrinsic: Option, ) -> ReturnDest<'tcx, Bx::Value> { // If the return is ignored, we can just return a do-nothing `ReturnDest`. if fn_ret.is_ignore() { @@ -1877,13 +1894,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { tmp.storage_live(bx); llargs.push(tmp.val.llval); ReturnDest::IndirectOperand(tmp, index) - } else if intrinsic.is_some() { - // Currently, intrinsics always need a location to store - // the result, so we create a temporary `alloca` for the - // result. - let tmp = PlaceRef::alloca(bx, fn_ret.layout); - tmp.storage_live(bx); - ReturnDest::IndirectOperand(tmp, index) } else { ReturnDest::DirectOperand(index) }; @@ -1893,7 +1903,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - self.codegen_place(bx, mir::PlaceRef { local: dest.local, projection: dest.projection }) + self.codegen_place(bx, dest.as_ref()) }; if fn_ret.is_indirect() { if dest.val.align < dest.layout.align.abi { -- cgit 1.4.1-3-g733a5 From 165fb988499b771afb7c2ddb60f05e9e337afb6a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 23 May 2025 08:30:58 +0000 Subject: Reduce indentation in codegen_panic_intrinsic --- compiler/rustc_codegen_ssa/src/mir/block.rs | 96 ++++++++++++++--------------- 1 file changed, 47 insertions(+), 49 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index cb8088e9efb..1baab62ae43 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -836,58 +836,56 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Emit a panic or a no-op for `assert_*` intrinsics. // These are intrinsics that compile to panics so that we can get a message // which mentions the offending type, even from a const context. - if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) { - let ty = instance.args.type_at(0); - - let do_panic = !bx - .tcx() - .check_validity_requirement((requirement, bx.typing_env().as_query_input(ty))) - .expect("expect to have layout during codegen"); - - let layout = bx.layout_of(ty); - - Some(if do_panic { - let msg_str = with_no_visible_paths!({ - with_no_trimmed_paths!({ - if layout.is_uninhabited() { - // Use this error even for the other intrinsics as it is more precise. - format!("attempted to instantiate uninhabited type `{ty}`") - } else if requirement == ValidityRequirement::Zero { - format!("attempted to zero-initialize type `{ty}`, which is invalid") - } else { - format!( - "attempted to leave type `{ty}` uninitialized, which is invalid" - ) - } - }) - }); - let msg = bx.const_str(&msg_str); + let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) else { + return None; + }; - // Obtain the panic entry point. - let (fn_abi, llfn, instance) = - common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind); + let ty = instance.args.type_at(0); - // Codegen the actual panic invoke/call. - helper.do_call( - self, - bx, - fn_abi, - llfn, - &[msg.0, msg.1], - target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)), - unwind, - &[], - Some(instance), - mergeable_succ, - ) - } else { - // a NOP - let target = target.unwrap(); - helper.funclet_br(self, bx, target, mergeable_succ) - }) - } else { - None + let is_valid = bx + .tcx() + .check_validity_requirement((requirement, bx.typing_env().as_query_input(ty))) + .expect("expect to have layout during codegen"); + + if is_valid { + // a NOP + let target = target.unwrap(); + return Some(helper.funclet_br(self, bx, target, mergeable_succ)); } + + let layout = bx.layout_of(ty); + + let msg_str = with_no_visible_paths!({ + with_no_trimmed_paths!({ + if layout.is_uninhabited() { + // Use this error even for the other intrinsics as it is more precise. + format!("attempted to instantiate uninhabited type `{ty}`") + } else if requirement == ValidityRequirement::Zero { + format!("attempted to zero-initialize type `{ty}`, which is invalid") + } else { + format!("attempted to leave type `{ty}` uninitialized, which is invalid") + } + }) + }); + let msg = bx.const_str(&msg_str); + + // Obtain the panic entry point. + let (fn_abi, llfn, instance) = + common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind); + + // Codegen the actual panic invoke/call. + Some(helper.do_call( + self, + bx, + fn_abi, + llfn, + &[msg.0, msg.1], + target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)), + unwind, + &[], + Some(instance), + mergeable_succ, + )) } fn codegen_call_terminator( -- cgit 1.4.1-3-g733a5 From 29c3babd7c03a48b022663beb7ad39bb24bbef36 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 May 2025 12:07:32 +0000 Subject: Rename unpack to kind --- .../rustc_borrowck/src/diagnostics/region_name.rs | 4 +-- .../src/type_check/constraint_conversion.rs | 2 +- .../rustc_borrowck/src/type_check/opaque_types.rs | 2 +- compiler/rustc_codegen_ssa/src/meth.rs | 2 +- compiler/rustc_const_eval/src/check_consts/ops.rs | 2 +- compiler/rustc_const_eval/src/util/type_name.rs | 2 +- compiler/rustc_hir_analysis/src/check/check.rs | 4 +-- .../src/check/compare_impl_item.rs | 4 +-- .../src/check/compare_impl_item/refine.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 4 +-- .../rustc_hir_analysis/src/collect/item_bounds.rs | 2 +- .../src/hir_ty_lowering/dyn_compatibility.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- .../src/outlives/implicit_infer.rs | 4 +-- compiler/rustc_hir_analysis/src/outlives/mod.rs | 2 +- compiler/rustc_hir_analysis/src/outlives/utils.rs | 2 +- .../rustc_hir_analysis/src/variance/constraints.rs | 6 ++--- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 16 ++++++------ compiler/rustc_hir_typeck/src/method/suggest.rs | 4 +-- compiler/rustc_infer/src/infer/at.rs | 2 +- .../rustc_infer/src/infer/canonical/instantiate.rs | 6 ++--- .../src/infer/canonical/query_response.rs | 6 ++--- compiler/rustc_infer/src/infer/context.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 4 +-- .../rustc_infer/src/infer/outlives/obligations.rs | 4 +-- .../rustc_infer/src/infer/relate/generalize.rs | 2 +- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +-- compiler/rustc_middle/src/ty/generic_args.rs | 30 +++++++++++----------- compiler/rustc_middle/src/ty/impls_ty.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 26 +++++++++---------- compiler/rustc_middle/src/ty/opaque_types.rs | 6 ++--- compiler/rustc_middle/src/ty/print/pretty.rs | 6 ++--- compiler/rustc_middle/src/ty/relate.rs | 4 +-- compiler/rustc_middle/src/ty/structural_impls.rs | 4 +-- compiler/rustc_middle/src/ty/typeck_results.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 4 +-- .../src/thir/pattern/const_to_pat.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 4 +-- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 12 ++++----- compiler/rustc_symbol_mangling/src/export.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 8 +++--- .../src/error_reporting/infer/mod.rs | 8 +++--- .../src/error_reporting/infer/need_type_info.rs | 12 ++++----- .../src/error_reporting/infer/suggest.rs | 4 +-- .../error_reporting/traits/fulfillment_errors.rs | 2 +- compiler/rustc_trait_selection/src/opaque_types.rs | 2 +- .../rustc_trait_selection/src/solve/delegate.rs | 2 +- .../src/solve/inspect/analyse.rs | 2 +- .../rustc_trait_selection/src/traits/select/mod.rs | 2 +- .../src/traits/structural_normalize.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_ty_utils/src/representability.rs | 4 +-- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/utils.rs | 4 +-- .../clippy_lints/src/arc_with_non_send_sync.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 2 +- src/tools/clippy/clippy_lints/src/eta_reduction.rs | 4 +-- .../clippy_lints/src/functions/ref_option.rs | 2 +- .../clippy/clippy_lints/src/let_underscore.rs | 2 +- .../clippy_lints/src/matches/manual_unwrap_or.rs | 2 +- .../src/matches/redundant_pattern_match.rs | 2 +- .../src/matches/significant_drop_in_scrutinee.rs | 4 +-- .../clippy_lints/src/methods/needless_collect.rs | 2 +- .../src/methods/unnecessary_sort_by.rs | 2 +- .../src/methods/unnecessary_to_owned.rs | 4 +-- .../src/needless_borrows_for_generic_args.rs | 2 +- .../clippy_lints/src/non_send_fields_in_send_ty.rs | 6 ++--- .../clippy_lints/src/only_used_in_recursion.rs | 2 +- src/tools/clippy/clippy_lints/src/returns.rs | 2 +- .../src/significant_drop_tightening.rs | 2 +- src/tools/clippy/clippy_lints/src/use_self.rs | 4 +-- .../clippy_lints_internal/src/msrv_attr_impl.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/clippy/clippy_utils/src/ty/mod.rs | 10 ++++---- .../clippy_utils/src/ty/type_certainty/mod.rs | 2 +- src/tools/miri/src/machine.rs | 2 +- 80 files changed, 165 insertions(+), 165 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index b08c10983bb..4aa9e90ab88 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -607,7 +607,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, ) -> Option<&'hir hir::Lifetime> { for (kind, hir_arg) in iter::zip(args, hir_args.args) { - match (kind.unpack(), hir_arg) { + match (kind.kind(), hir_arg) { (GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => { if r.as_var() == needle_fr { return Some(lt); @@ -997,7 +997,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { ) -> bool { let tcx = self.infcx.tcx; ty.walk().any(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() + if let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Param(_) = ty.kind() { clauses.iter().any(|pred| { diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 57516565147..a1c74672157 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -148,7 +148,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { let mut next_outlives_predicates = vec![]; for (ty::OutlivesPredicate(k1, r2), constraint_category) in outlives_predicates { - match k1.unpack() { + match k1.kind() { GenericArgKind::Lifetime(r1) => { let r1_vid = self.to_region_vid(r1); let r2_vid = self.to_region_vid(r2); diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs index 341c50c37f6..5a422483eef 100644 --- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs +++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs @@ -221,7 +221,7 @@ fn register_member_constraints<'tcx>( .iter() .enumerate() .filter(|(i, _)| variances[*i] == ty::Invariant) - .filter_map(|(_, arg)| match arg.unpack() { + .filter_map(|(_, arg)| match arg.kind() { GenericArgKind::Lifetime(r) => Some(typeck.to_region_vid(r)), GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, }) diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 399c592432a..3a11ce6befb 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -77,7 +77,7 @@ fn dyn_trait_in_self<'tcx>( ty: Ty<'tcx>, ) -> Option> { for arg in ty.peel_refs().walk() { - if let GenericArgKind::Type(ty) = arg.unpack() + if let GenericArgKind::Type(ty) = arg.kind() && let ty::Dynamic(data, _, _) = ty.kind() { // FIXME(arbitrary_self_types): This is likely broken for receivers which diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 1e5b98675c4..177ba56b165 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -281,7 +281,7 @@ fn build_error_for_const_call<'tcx>( let mut sugg = None; if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) { - match (args[0].unpack(), args[1].unpack()) { + match (args[0].kind(), args[1].kind()) { (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) if self_ty == rhs_ty && self_ty.is_ref() diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 30e96ae4143..e8f2728a772 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -125,7 +125,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { ) -> Result<(), PrintError> { print_prefix(self)?; let args = - args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_))); + args.iter().cloned().filter(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_))); if args.clone().next().is_some() { self.generic_delimiters(|cx| cx.comma_sep(args)) } else { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 06814eaefe8..db7a5fe7897 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1575,7 +1575,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD let mut params_used = DenseBitSet::new_empty(generics.own_params.len()); for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() + if let GenericArgKind::Type(leaf_ty) = leaf.kind() && let ty::Param(param) = leaf_ty.kind() { debug!("found use of ty param {:?}", param); @@ -1700,7 +1700,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorG let mut label_match = |ty: Ty<'_>, span| { for arg in ty.walk() { - if let ty::GenericArgKind::Type(ty) = arg.unpack() + if let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Alias( ty::Opaque, ty::AliasTy { def_id: captured_def_id, .. }, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 2ee41e2efbd..47681a78ecc 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1231,7 +1231,7 @@ fn check_region_late_boundedness<'tcx>( for (id_arg, arg) in std::iter::zip(ty::GenericArgs::identity_for_item(tcx, impl_m.def_id), impl_m_args) { - if let ty::GenericArgKind::Lifetime(r) = arg.unpack() + if let ty::GenericArgKind::Lifetime(r) = arg.kind() && let ty::ReVar(vid) = r.kind() && let r = infcx .inner @@ -1256,7 +1256,7 @@ fn check_region_late_boundedness<'tcx>( for (id_arg, arg) in std::iter::zip(ty::GenericArgs::identity_for_item(tcx, trait_m.def_id), trait_m_args) { - if let ty::GenericArgKind::Lifetime(r) = arg.unpack() + if let ty::GenericArgKind::Lifetime(r) = arg.kind() && let ty::ReVar(vid) = r.kind() && let r = infcx .inner diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 4973d848959..3db1c40228f 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -427,7 +427,7 @@ fn report_mismatched_rpitit_captures<'tcx>( }; trait_captured_args - .sort_by_cached_key(|arg| !matches!(arg.unpack(), ty::GenericArgKind::Lifetime(_))); + .sort_by_cached_key(|arg| !matches!(arg.kind(), ty::GenericArgKind::Lifetime(_))); let suggestion = format!("use<{}>", trait_captured_args.iter().join(", ")); tcx.emit_node_span_lint( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 06c5e518fc6..476ce0e8691 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -819,7 +819,7 @@ impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> { match t.kind() { ty::Alias(ty::Projection, p) if p.def_id == self.gat => { for (idx, arg) in p.args.iter().enumerate() { - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(lt) if !lt.is_bound() => { self.regions.insert((lt, idx)); } @@ -1517,7 +1517,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } else { // If we've got a generic const parameter we still want to check its // type is correct in case both it and the param type are fully concrete. - let GenericArgKind::Const(ct) = default.unpack() else { + let GenericArgKind::Const(ct) = default.kind() else { continue; }; diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 279b1e82a71..5f1cdeddc19 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -151,7 +151,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( let mut mapping = FxIndexMap::default(); let generics = tcx.generics_of(assoc_item_def_id); for (param, var) in std::iter::zip(&generics.own_params, gat_vars) { - let existing = match var.unpack() { + let existing = match var.kind() { ty::GenericArgKind::Lifetime(re) => { if let ty::RegionKind::ReBound(ty::INNERMOST, bv) = re.kind() { mapping.insert(bv.var, tcx.mk_param_from_def(param)) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 9e44b645aca..e75c307984e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -216,7 +216,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let pred = bound_predicate.rebind(pred); // A `Self` within the original bound will be instantiated with a // `trait_object_dummy_self`, so check for that. - let references_self = match pred.skip_binder().term.unpack() { + let references_self = match pred.skip_binder().term.kind() { ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()), // FIXME(associated_const_equality): We should walk the const instead of not doing anything ty::TermKind::Const(_) => false, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 6b21bbbfcd8..9eaa8360fee 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -607,7 +607,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if !infer_args && has_default { // No type parameter provided, but a default exists. if let Some(prev) = - preceding_args.iter().find_map(|arg| match arg.unpack() { + preceding_args.iter().find_map(|arg| match arg.kind() { GenericArgKind::Type(ty) => ty.error_reported().err(), _ => None, }) diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index c99eb12efcc..4f35b87be30 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -119,7 +119,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( explicit_map: &mut ExplicitPredicatesMap<'tcx>, ) { for arg in ty.walk() { - let leaf_ty = match arg.unpack() { + let leaf_ty = match arg.kind() { GenericArgKind::Type(ty) => ty, // No predicates from lifetimes or constants, except potentially @@ -299,7 +299,7 @@ fn check_explicit_predicates<'tcx>( // binding) and thus infer an outlives requirement that `X: // 'b`. if let Some(self_ty) = ignored_self_ty - && let GenericArgKind::Type(ty) = outlives_predicate.0.unpack() + && let GenericArgKind::Type(ty) = outlives_predicate.0.kind() && ty.walk().any(|arg| arg == self_ty.into()) { debug!("skipping self ty = {ty:?}"); diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index daa908c8c78..fbf973a49dc 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -70,7 +70,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { let predicates = &*tcx.arena.alloc_from_iter(set.as_ref().skip_binder().iter().filter_map( |(ty::OutlivesPredicate(kind1, region2), &span)| { - match kind1.unpack() { + match kind1.kind() { GenericArgKind::Type(ty1) => Some(( ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)) .upcast(tcx), diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 044fb64ca82..3fd1dbb3a8a 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -25,7 +25,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>( return; } - match kind.unpack() { + match kind.kind() { GenericArgKind::Type(ty) => { // `T: 'outlived_region` for some type `T` // But T could be a lot of things: diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 92cfece77c4..68ceec384b9 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -201,7 +201,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let variance_i = self.invariant(variance); for k in args { - match k.unpack() { + match k.kind() { GenericArgKind::Lifetime(lt) => { self.add_constraints_from_region(current, lt, variance_i) } @@ -294,7 +294,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } for projection in data.projection_bounds() { - match projection.skip_binder().term.unpack() { + match projection.skip_binder().term.kind() { ty::TermKind::Ty(ty) => { self.add_constraints_from_ty(current, ty, self.invariant); } @@ -389,7 +389,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { "add_constraints_from_args: variance_decl={:?} variance_i={:?}", variance_decl, variance_i ); - match k.unpack() { + match k.kind() { GenericArgKind::Lifetime(lt) => { self.add_constraints_from_region(current, lt, variance_i) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index ee0436f73e1..db6482fe4fa 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -80,12 +80,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| { predicate_args.iter().find_map(|arg| { arg.walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() + if let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Param(param_ty) = *ty.kind() && matches(ty::ParamTerm::Ty(param_ty)) { Some(arg) - } else if let ty::GenericArgKind::Const(ct) = arg.unpack() + } else if let ty::GenericArgKind::Const(ct) = arg.kind() && let ty::ConstKind::Param(param_ct) = ct.kind() && matches(ty::ParamTerm::Const(param_ct)) { @@ -373,7 +373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Handle `Self` param specifically, since it's separated in // the path representation if let Some(self_ty) = self_ty - && let ty::GenericArgKind::Type(ty) = param.unpack() + && let ty::GenericArgKind::Type(ty) = param.kind() && ty == self.tcx.types.self_param { error.obligation.cause.span = self_ty @@ -389,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Handle `Self` param specifically, since it's separated in // the path representation - if let ty::GenericArgKind::Type(ty) = param.unpack() + if let ty::GenericArgKind::Type(ty) = param.kind() && ty == self.tcx.types.self_param { error.obligation.cause.span = self_ty @@ -424,10 +424,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the args list does not, then we should chop off all of the lifetimes, // since they're all elided. let segment_args = segment.args().args; - if matches!(own_args[0].unpack(), ty::GenericArgKind::Lifetime(_)) + if matches!(own_args[0].kind(), ty::GenericArgKind::Lifetime(_)) && segment_args.first().is_some_and(|arg| arg.is_ty_or_const()) && let Some(offset) = own_args.iter().position(|arg| { - matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_)) + matches!(arg.kind(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_)) }) && let Some(new_index) = index.checked_sub(offset) { @@ -750,7 +750,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ok(expr); } - let ty::GenericArgKind::Type(in_ty) = in_ty.unpack() else { + let ty::GenericArgKind::Type(in_ty) = in_ty.kind() else { return Err(expr); }; @@ -1045,7 +1045,7 @@ fn find_param_in_ty<'tcx>( if arg == param_to_point_at { return true; } - if let ty::GenericArgKind::Type(ty) = arg.unpack() + if let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind() { // This logic may seem a bit strange, but typically when diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7b71f5de756..3eae95d5b73 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2226,7 +2226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let infer_args = self.tcx.mk_args_from_iter(args.into_iter().map(|arg| { if !arg.is_suggestable(self.tcx, true) { has_unsuggestable_args = true; - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(_) => self .next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) .into(), @@ -2843,7 +2843,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let [first] = ***args else { return; }; - let ty::GenericArgKind::Type(ty) = first.unpack() else { + let ty::GenericArgKind::Type(ty) = first.kind() else { return; }; let Ok(pick) = self.lookup_probe_for_diagnostic( diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 2cd67cc4da2..5fe795bd23a 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -347,7 +347,7 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: match (a.unpack(), b.unpack()) { + values: match (a.kind(), b.kind()) { (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => { ValuePairs::Regions(ExpectedFound::new(a, b)) } diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index f5ee5702d09..67f13192b52 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -61,15 +61,15 @@ where value } else { let delegate = FnMutDelegate { - regions: &mut |br: ty::BoundRegion| match var_values[br.var].unpack() { + regions: &mut |br: ty::BoundRegion| match var_values[br.var].kind() { GenericArgKind::Lifetime(l) => l, r => bug!("{:?} is a region but value is {:?}", br, r), }, - types: &mut |bound_ty: ty::BoundTy| match var_values[bound_ty.var].unpack() { + types: &mut |bound_ty: ty::BoundTy| match var_values[bound_ty.var].kind() { GenericArgKind::Type(ty) => ty, r => bug!("{:?} is a type but value is {:?}", bound_ty, r), }, - consts: &mut |bound_ct: ty::BoundVar| match var_values[bound_ct].unpack() { + consts: &mut |bound_ct: ty::BoundVar| match var_values[bound_ct].kind() { GenericArgKind::Const(ct) => ct, c => bug!("{:?} is a const but value is {:?}", bound_ct, c), }, diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index bda33f3f455..008ef690008 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -245,7 +245,7 @@ impl<'tcx> InferCtxt<'tcx> { let result_value = query_response.instantiate_projected(self.tcx, &result_args, |v| { v.var_values[BoundVar::new(index)] }); - match (original_value.unpack(), result_value.unpack()) { + match (original_value.kind(), result_value.kind()) { (GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2)) if re1.is_erased() && re2.is_erased() => { @@ -402,7 +402,7 @@ impl<'tcx> InferCtxt<'tcx> { // [(?A, Vec), ('static, '?1), (?B, ?0)] for (original_value, result_value) in iter::zip(&original_values.var_values, result_values) { - match result_value.unpack() { + match result_value.kind() { GenericArgKind::Type(result_value) => { // e.g., here `result_value` might be `?0` in the example above... if let ty::Bound(debruijn, b) = *result_value.kind() { @@ -533,7 +533,7 @@ impl<'tcx> InferCtxt<'tcx> { for (index, value1) in variables1.var_values.iter().enumerate() { let value2 = variables2(BoundVar::new(index)); - match (value1.unpack(), value2.unpack()) { + match (value1.kind(), value2.kind()) { (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => { obligations.extend( self.at(cause, param_env) diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 6b75d676f4d..f7c702d321b 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -90,7 +90,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn is_changed_arg(&self, arg: ty::GenericArg<'tcx>) -> bool { - match arg.unpack() { + match arg.kind() { ty::GenericArgKind::Lifetime(_) => { // Lifetimes should not change affect trait selection. false diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 8fb25cb9b32..96e03e3bea5 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1372,7 +1372,7 @@ impl<'tcx> TyOrConstInferVar { /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option { - match arg.unpack() { + match arg.kind() { GenericArgKind::Type(ty) => Self::maybe_from_ty(ty), GenericArgKind::Const(ct) => Self::maybe_from_const(ct), GenericArgKind::Lifetime(_) => None, @@ -1383,7 +1383,7 @@ impl<'tcx> TyOrConstInferVar { /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). pub fn maybe_from_term(term: Term<'tcx>) -> Option { - match term.unpack() { + match term.kind() { TermKind::Ty(ty) => Self::maybe_from_ty(ty), TermKind::Const(ct) => Self::maybe_from_const(ct), } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 890902af02b..0d2732a3b6d 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -87,7 +87,7 @@ impl<'tcx> InferCtxt<'tcx> { ty::OutlivesPredicate(arg, r2): ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>, cause: &ObligationCause<'tcx>, ) { - match arg.unpack() { + match arg.kind() { ty::GenericArgKind::Lifetime(r1) => { self.register_region_outlives_constraint(ty::OutlivesPredicate(r1, r2), cause); } @@ -504,7 +504,7 @@ where ) { let constraint = origin.to_constraint_category(); for (index, k) in args.iter().enumerate() { - match k.unpack() { + match k.kind() { GenericArgKind::Lifetime(lt) => { let variance = if let Some(variances) = opt_variances { variances[index] diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 210b8f37d88..0e17b100276 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -329,7 +329,7 @@ struct Generalizer<'me, 'tcx> { impl<'tcx> Generalizer<'_, 'tcx> { /// Create an error that corresponds to the term kind in `root_term` fn cyclic_term_error(&self) -> TypeError<'tcx> { - match self.root_term.unpack() { + match self.root_term.kind() { ty::TermKind::Ty(ty) => TypeError::CyclicTy(ty), ty::TermKind::Const(ct) => TypeError::CyclicConst(ct), } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index a8f45d043be..8124d7f7c86 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -461,7 +461,7 @@ fn extract_def_id_from_arg<'tcx>( generics: &'tcx ty::Generics, arg: ty::GenericArg<'tcx>, ) -> DefId { - match arg.unpack() { + match arg.kind() { ty::GenericArgKind::Lifetime(re) => match re.kind() { ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id, ty::ReBound( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 70172e55e54..57b20a1bba6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2781,7 +2781,7 @@ impl<'tcx> TyCtxt<'tcx> { return false; } - if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) { + if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) { return false; } @@ -2803,7 +2803,7 @@ impl<'tcx> TyCtxt<'tcx> { }; for (param, arg) in std::iter::zip(&generics.own_params, own_args) { - match (¶m.kind, arg.unpack()) { + match (¶m.kind, arg.kind()) { (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_)) | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_)) | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {} diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 542c0b3e6eb..b7d3fd81b11 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -137,7 +137,7 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> { type Kind = GenericArgKind<'tcx>; fn kind(self) -> Self::Kind { - self.unpack() + self.kind() } } @@ -218,7 +218,7 @@ impl<'tcx> From> for GenericArg<'tcx> { impl<'tcx> From> for GenericArg<'tcx> { fn from(value: ty::Term<'tcx>) -> Self { - match value.unpack() { + match value.kind() { ty::TermKind::Ty(t) => t.into(), ty::TermKind::Const(c) => c.into(), } @@ -227,7 +227,7 @@ impl<'tcx> From> for GenericArg<'tcx> { impl<'tcx> GenericArg<'tcx> { #[inline] - pub fn unpack(self) -> GenericArgKind<'tcx> { + pub fn kind(self) -> GenericArgKind<'tcx> { let ptr = unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) }; // SAFETY: use of `Interned::new_unchecked` here is ok because these @@ -251,7 +251,7 @@ impl<'tcx> GenericArg<'tcx> { #[inline] pub fn as_region(self) -> Option> { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(re) => Some(re), _ => None, } @@ -259,7 +259,7 @@ impl<'tcx> GenericArg<'tcx> { #[inline] pub fn as_type(self) -> Option> { - match self.unpack() { + match self.kind() { GenericArgKind::Type(ty) => Some(ty), _ => None, } @@ -267,7 +267,7 @@ impl<'tcx> GenericArg<'tcx> { #[inline] pub fn as_const(self) -> Option> { - match self.unpack() { + match self.kind() { GenericArgKind::Const(ct) => Some(ct), _ => None, } @@ -275,7 +275,7 @@ impl<'tcx> GenericArg<'tcx> { #[inline] pub fn as_term(self) -> Option> { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(_) => None, GenericArgKind::Type(ty) => Some(ty.into()), GenericArgKind::Const(ct) => Some(ct.into()), @@ -300,7 +300,7 @@ impl<'tcx> GenericArg<'tcx> { } pub fn is_non_region_infer(self) -> bool { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(_) => false, // FIXME: This shouldn't return numerical/float. GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(), @@ -327,7 +327,7 @@ impl<'a, 'tcx> Lift> for GenericArg<'a> { type Lifted = GenericArg<'tcx>; fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => tcx.lift(lt).map(|lt| lt.into()), GenericArgKind::Type(ty) => tcx.lift(ty).map(|ty| ty.into()), GenericArgKind::Const(ct) => tcx.lift(ct).map(|ct| ct.into()), @@ -340,7 +340,7 @@ impl<'tcx> TypeFoldable> for GenericArg<'tcx> { self, folder: &mut F, ) -> Result { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), @@ -348,7 +348,7 @@ impl<'tcx> TypeFoldable> for GenericArg<'tcx> { } fn fold_with>>(self, folder: &mut F) -> Self { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(), GenericArgKind::Type(ty) => ty.fold_with(folder).into(), GenericArgKind::Const(ct) => ct.fold_with(folder).into(), @@ -358,7 +358,7 @@ impl<'tcx> TypeFoldable> for GenericArg<'tcx> { impl<'tcx> TypeVisitable> for GenericArg<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), GenericArgKind::Const(ct) => ct.visit_with(visitor), @@ -368,7 +368,7 @@ impl<'tcx> TypeVisitable> for GenericArg<'tcx> { impl<'tcx, E: TyEncoder<'tcx>> Encodable for GenericArg<'tcx> { fn encode(&self, e: &mut E) { - self.unpack().encode(e) + self.kind().encode(e) } } @@ -390,7 +390,7 @@ impl<'tcx> GenericArgs<'tcx> { /// /// If any of the generic arguments are not types. pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List> { - tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.unpack() { + tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.kind() { GenericArgKind::Type(ty) => ty, _ => bug!("`into_type_list` called on generic arg with non-types"), })) @@ -527,7 +527,7 @@ impl<'tcx> GenericArgs<'tcx> { /// Returns generic arguments that are not lifetimes. #[inline] pub fn non_erasable_generics(&self) -> impl DoubleEndedIterator> { - self.iter().filter_map(|k| match k.unpack() { + self.iter().filter_map(|k| match k.kind() { ty::GenericArgKind::Lifetime(_) => None, generic => Some(generic), }) diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 5f6305bb48a..ac45ce887c9 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -60,7 +60,7 @@ where impl<'a, 'tcx> HashStable> for ty::GenericArg<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.unpack().hash_stable(hcx, hasher); + self.kind().hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f57329608ef..78c0812b08f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -504,7 +504,7 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> { type Kind = TermKind<'tcx>; fn kind(self) -> Self::Kind { - self.unpack() + self.kind() } } @@ -521,7 +521,7 @@ unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync impl Debug for Term<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { + match self.kind() { TermKind::Ty(ty) => write!(f, "Term::Ty({ty:?})"), TermKind::Const(ct) => write!(f, "Term::Const({ct:?})"), } @@ -542,7 +542,7 @@ impl<'tcx> From> for Term<'tcx> { impl<'a, 'tcx> HashStable> for Term<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.unpack().hash_stable(hcx, hasher); + self.kind().hash_stable(hcx, hasher); } } @@ -551,14 +551,14 @@ impl<'tcx> TypeFoldable> for Term<'tcx> { self, folder: &mut F, ) -> Result { - match self.unpack() { + match self.kind() { ty::TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into), ty::TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), } } fn fold_with>>(self, folder: &mut F) -> Self { - match self.unpack() { + match self.kind() { ty::TermKind::Ty(ty) => ty.fold_with(folder).into(), ty::TermKind::Const(ct) => ct.fold_with(folder).into(), } @@ -567,7 +567,7 @@ impl<'tcx> TypeFoldable> for Term<'tcx> { impl<'tcx> TypeVisitable> for Term<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { - match self.unpack() { + match self.kind() { ty::TermKind::Ty(ty) => ty.visit_with(visitor), ty::TermKind::Const(ct) => ct.visit_with(visitor), } @@ -576,7 +576,7 @@ impl<'tcx> TypeVisitable> for Term<'tcx> { impl<'tcx, E: TyEncoder<'tcx>> Encodable for Term<'tcx> { fn encode(&self, e: &mut E) { - self.unpack().encode(e) + self.kind().encode(e) } } @@ -589,7 +589,7 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for Term<'tcx> { impl<'tcx> Term<'tcx> { #[inline] - pub fn unpack(self) -> TermKind<'tcx> { + pub fn kind(self) -> TermKind<'tcx> { let ptr = unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) }; // SAFETY: use of `Interned::new_unchecked` here is ok because these @@ -609,7 +609,7 @@ impl<'tcx> Term<'tcx> { } pub fn as_type(&self) -> Option> { - if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None } + if let TermKind::Ty(ty) = self.kind() { Some(ty) } else { None } } pub fn expect_type(&self) -> Ty<'tcx> { @@ -617,7 +617,7 @@ impl<'tcx> Term<'tcx> { } pub fn as_const(&self) -> Option> { - if let TermKind::Const(c) = self.unpack() { Some(c) } else { None } + if let TermKind::Const(c) = self.kind() { Some(c) } else { None } } pub fn expect_const(&self) -> Const<'tcx> { @@ -625,14 +625,14 @@ impl<'tcx> Term<'tcx> { } pub fn into_arg(self) -> GenericArg<'tcx> { - match self.unpack() { + match self.kind() { TermKind::Ty(ty) => ty.into(), TermKind::Const(c) => c.into(), } } pub fn to_alias_term(self) -> Option> { - match self.unpack() { + match self.kind() { TermKind::Ty(ty) => match *ty.kind() { ty::Alias(_kind, alias_ty) => Some(alias_ty.into()), _ => None, @@ -645,7 +645,7 @@ impl<'tcx> Term<'tcx> { } pub fn is_infer(&self) -> bool { - match self.unpack() { + match self.kind() { TermKind::Ty(ty) => ty.is_ty_var(), TermKind::Const(ct) => ct.is_ct_infer(), } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 9445a18ad76..5c05bdb08eb 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -120,7 +120,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { } } - match self.map.get(&r.into()).map(|k| k.unpack()) { + match self.map.get(&r.into()).map(|k| k.kind()) { Some(GenericArgKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {u:?}"), None if self.do_not_error => self.tcx.lifetimes.re_static, @@ -162,7 +162,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { ty::Param(param) => { // Look it up in the generic parameters list. - match self.map.get(&ty.into()).map(|k| k.unpack()) { + match self.map.get(&ty.into()).map(|k| k.kind()) { // Found it in the generic parameters list; replace with the parameter from the // opaque type. Some(GenericArgKind::Type(t1)) => t1, @@ -195,7 +195,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { match ct.kind() { ty::ConstKind::Param(..) => { // Look it up in the generic parameters list. - match self.map.get(&ct.into()).map(|k| k.unpack()) { + match self.map.get(&ct.into()).map(|k| k.kind()) { // Found it in the generic parameters list, replace with the parameter from the // opaque type. Some(GenericArgKind::Const(c1)) => c1, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6fd6aff0e2b..877bea095f9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1239,7 +1239,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name())); - match term.unpack() { + match term.kind() { TermKind::Ty(ty) => p!(print(ty)), TermKind::Const(c) => p!(print(c)), }; @@ -3386,7 +3386,7 @@ define_print_and_forward_display! { } ty::Term<'tcx> { - match self.unpack() { + match self.kind() { ty::TermKind::Ty(ty) => p!(print(ty)), ty::TermKind::Const(c) => p!(print(c)), } @@ -3401,7 +3401,7 @@ define_print_and_forward_display! { } GenericArg<'tcx> { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => p!(print(lt)), GenericArgKind::Type(ty) => p!(print(ty)), GenericArgKind::Const(ct) => p!(print(ct)), diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 6ad4e5276b2..dc1d60f3d43 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -169,7 +169,7 @@ impl<'tcx> Relate> for ty::GenericArg<'tcx> { a: ty::GenericArg<'tcx>, b: ty::GenericArg<'tcx>, ) -> RelateResult<'tcx, ty::GenericArg<'tcx>> { - match (a.unpack(), b.unpack()) { + match (a.kind(), b.kind()) { (ty::GenericArgKind::Lifetime(a_lt), ty::GenericArgKind::Lifetime(b_lt)) => { Ok(relation.relate(a_lt, b_lt)?.into()) } @@ -190,7 +190,7 @@ impl<'tcx> Relate> for ty::Term<'tcx> { a: Self, b: Self, ) -> RelateResult<'tcx, Self> { - Ok(match (a.unpack(), b.unpack()) { + Ok(match (a.kind(), b.kind()) { (ty::TermKind::Ty(a), ty::TermKind::Ty(b)) => relation.relate(a, b)?.into(), (ty::TermKind::Const(a), ty::TermKind::Const(b)) => relation.relate(a, b)?.into(), _ => return Err(TypeError::Mismatch), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 58f7bc75054..7a7c33fb34d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -202,7 +202,7 @@ impl fmt::Debug for ty::Placeholder { impl<'tcx> fmt::Debug for GenericArg<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { + match self.kind() { GenericArgKind::Lifetime(lt) => lt.fmt(f), GenericArgKind::Type(ty) => ty.fmt(f), GenericArgKind::Const(ct) => ct.fmt(f), @@ -326,7 +326,7 @@ impl<'tcx, T: Lift>> Lift> for Option { impl<'a, 'tcx> Lift> for Term<'a> { type Lifted = ty::Term<'tcx>; fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option { - match self.unpack() { + match self.kind() { TermKind::Ty(ty) => tcx.lift(ty).map(Into::into), TermKind::Const(c) => tcx.lift(c).map(Into::into), } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index c6a45f84686..9627188c334 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -778,7 +778,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { } iter::zip(user_args.args, BoundVar::ZERO..).all(|(kind, cvar)| { - match kind.unpack() { + match kind.kind() { GenericArgKind::Type(ty) => match ty.kind() { ty::Bound(debruijn, b) => { // We only allow a `ty::INNERMOST` index in generic parameters. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ecf83926df7..06fd8a294d0 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -517,7 +517,7 @@ impl<'tcx> TyCtxt<'tcx> { let result = iter::zip(item_args, impl_args) .filter(|&(_, k)| { - match k.unpack() { + match k.kind() { GenericArgKind::Lifetime(region) => match region.kind() { ty::ReEarlyParam(ebr) => { !impl_generics.region_param(ebr, self).pure_wrt_drop @@ -554,7 +554,7 @@ impl<'tcx> TyCtxt<'tcx> { let mut seen = GrowableBitSet::default(); let mut seen_late = FxHashSet::default(); for arg in args { - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { (CheckRegions::FromFunction, ty::ReBound(di, reg)) => { if !seen_late.insert((di, reg)) { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index e233358f386..84a0190a7fa 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -131,7 +131,7 @@ impl<'tcx> ConstToPat<'tcx> { .dcx() .create_err(ConstPatternDependsOnGenericParameter { span: self.span }); for arg in uv.args { - if let ty::GenericArgKind::Type(ty) = arg.unpack() + if let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Param(param_ty) = ty.kind() { let def_id = self.tcx.hir_enclosing_body_owner(self.id); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 47831f2f418..9d1d3412f8d 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -79,7 +79,7 @@ fn encode_args<'tcx>( s.push('I'); let def_generics = tcx.generics_of(for_def); for (n, arg) in args.iter().enumerate() { - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(region) => { s.push_str(&encode_region(region, dict)); } @@ -245,7 +245,7 @@ fn encode_predicate<'tcx>( let name = encode_ty_name(tcx, projection.def_id); let _ = write!(s, "u{}{}", name.len(), name); s.push_str(&encode_args(tcx, projection.args, projection.def_id, true, dict, options)); - match projection.term.unpack() { + match projection.term.kind() { TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)), TermKind::Const(c) => s.push_str(&encode_const( tcx, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 8bcac4c4678..b0c9dba78a6 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -100,7 +100,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { stable_mir::ty::ExistentialProjection { def_id: tables.trait_def(*def_id), generic_args: args.stable(tables), - term: term.unpack().stable(tables), + term: term.kind().stable(tables), } } } @@ -158,7 +158,7 @@ impl<'tcx> Stable<'tcx> for ty::FieldDef { impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { type T = stable_mir::ty::GenericArgs; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect()) + GenericArgs(self.iter().map(|arg| arg.kind().stable(tables)).collect()) } } @@ -604,8 +604,8 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { PredicateKind::NormalizesTo(_pred) => unimplemented!(), PredicateKind::AliasRelate(a, b, alias_relation_direction) => { stable_mir::ty::PredicateKind::AliasRelate( - a.unpack().stable(tables), - b.unpack().stable(tables), + a.kind().stable(tables), + b.kind().stable(tables), alias_relation_direction.stable(tables), ) } @@ -640,7 +640,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { ty.stable(tables), ), ClauseKind::WellFormed(term) => { - stable_mir::ty::ClauseKind::WellFormed(term.unpack().stable(tables)) + stable_mir::ty::ClauseKind::WellFormed(term.kind().stable(tables)) } ClauseKind::ConstEvaluatable(const_) => { stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) @@ -726,7 +726,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { let ty::ProjectionPredicate { projection_term, term } = self; stable_mir::ty::ProjectionPredicate { projection_term: projection_term.stable(tables), - term: term.unpack().stable(tables), + term: term.kind().stable(tables), } } } diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 770401fc8cf..956c996326b 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -147,7 +147,7 @@ impl<'tcx> AbiHashStable<'tcx> for ty::FnSig<'tcx> { impl<'tcx> AbiHashStable<'tcx> for ty::GenericArg<'tcx> { fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) { - self.unpack().abi_hash(tcx, hasher); + self.kind().abi_hash(tcx, hasher); } } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index db102abda7f..12d1de46313 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -386,7 +386,7 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> { print_prefix(self)?; let args = - args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_))); + args.iter().cloned().filter(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_))); if args.clone().next().is_some() { self.generic_delimiters(|cx| cx.comma_sep(args)) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 644031af859..49a5e20d7cf 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -646,7 +646,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { let name = cx.tcx.associated_item(projection.def_id).name(); cx.push("p"); cx.push_ident(name.as_str()); - match projection.term.unpack() { + match projection.term.kind() { ty::TermKind::Ty(ty) => ty.print(cx), ty::TermKind::Const(c) => c.print(cx), }?; @@ -912,11 +912,11 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { args: &[GenericArg<'tcx>], ) -> Result<(), PrintError> { // Don't print any regions if they're all erased. - let print_regions = args.iter().any(|arg| match arg.unpack() { + let print_regions = args.iter().any(|arg| match arg.kind() { GenericArgKind::Lifetime(r) => !r.is_erased(), _ => false, }); - let args = args.iter().cloned().filter(|arg| match arg.unpack() { + let args = args.iter().cloned().filter(|arg| match arg.kind() { GenericArgKind::Lifetime(_) => print_regions, _ => true, }); @@ -928,7 +928,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { self.push("I"); print_prefix(self)?; for arg in args { - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(lt) => { lt.print(self)?; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index fdd547448f0..aeadb32ac2b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -738,7 +738,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { value.push_normal(", "); } - match arg.unpack() { + match arg.kind() { ty::GenericArgKind::Lifetime(lt) => { let s = lt.to_string(); value.push_normal(if s.is_empty() { "'_" } else { &s }); @@ -1166,7 +1166,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for (i, (arg1, arg2)) in sub1.iter().zip(sub2).enumerate().take(len) { self.push_comma(&mut values.0, &mut values.1, i); - match arg1.unpack() { + match arg1.kind() { // At one point we'd like to elide all lifetimes here, they are // irrelevant for all diagnostics that use this output. // @@ -1509,7 +1509,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let (is_simple_error, exp_found) = match values { ValuePairs::Terms(ExpectedFound { expected, found }) => { - match (expected.unpack(), found.unpack()) { + match (expected.kind(), found.kind()) { (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => { let is_simple_err = expected.is_simple_text() && found.is_simple_text(); @@ -2156,7 +2156,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return None; } - Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) { + Some(match (exp_found.expected.kind(), exp_found.found.kind()) { (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => { let (mut exp, mut fnd) = self.cmp(expected, found); // Use the terminal width as the basis to determine when to compress the printed diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index cb1c9c75369..bfef3340b32 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -215,7 +215,7 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { // `_` because then we'd end up with `Vec<_, _>`, instead of // `Vec<_>`. arg - } else if let GenericArgKind::Type(_) = arg.unpack() { + } else if let GenericArgKind::Type(_) = arg.kind() { // We don't replace lifetime or const params, only type params. self.new_infer().into() } else { @@ -347,7 +347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { highlight: ty::print::RegionHighlightMode<'tcx>, ) -> InferenceDiagnosticsData { let tcx = self.tcx; - match term.unpack() { + match term.kind() { TermKind::Ty(ty) => { if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() { let var_origin = self.infcx.type_var_origin(ty_vid); @@ -568,7 +568,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return arg; } - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(), GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(), @@ -803,7 +803,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { } impl<'tcx> CostCtxt<'tcx> { fn arg_cost(self, arg: GenericArg<'tcx>) -> usize { - match arg.unpack() { + match arg.kind() { GenericArgKind::Lifetime(_) => 0, // erased GenericArgKind::Type(ty) => self.ty_cost(ty), GenericArgKind::Const(_) => 3, // some non-zero value @@ -898,7 +898,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { return true; } - match (arg.unpack(), self.target.unpack()) { + match (arg.kind(), self.target.kind()) { (GenericArgKind::Type(inner_ty), TermKind::Ty(target_ty)) => { use ty::{Infer, TyVar}; match (inner_ty.kind(), target_ty.kind()) { @@ -929,7 +929,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { if self.generic_arg_is_target(inner) { return true; } - match inner.unpack() { + match inner.kind() { GenericArgKind::Lifetime(_) => {} GenericArgKind::Type(ty) => { if matches!( diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index cdbb92f4c7b..3804c13acce 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -664,8 +664,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let Some(found) = exp_found.found.args.get(1) else { return; }; - let expected = expected.unpack(); - let found = found.unpack(); + let expected = expected.kind(); + let found = found.kind(); // 3. Extract the tuple type from Fn trait and suggest the change. if let GenericArgKind::Type(expected) = expected && let GenericArgKind::Type(found) = found diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index b88040a0f98..9b5e421e0e4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2446,7 +2446,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if let ty::Adt(def, args) = self_ty.kind() && let [arg] = &args[..] - && let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::GenericArgKind::Type(ty) = arg.kind() && let ty::Adt(inner_def, _) = ty.kind() && inner_def == def { diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 332204a0c5f..d5bde9192d5 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -81,7 +81,7 @@ pub fn check_opaque_type_parameter_valid<'tcx>( } for (i, arg) in opaque_type_key.iter_captured_args(tcx) { - let arg_is_param = match arg.unpack() { + let arg_is_param = match arg.kind() { GenericArgKind::Lifetime(lt) => match defining_scope_kind { DefiningScopeKind::HirTypeck => continue, DefiningScopeKind::MirBorrowck => { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index eea311fe66e..038cdc1a564 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -108,7 +108,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< arg: ty::GenericArg<'tcx>, span: Span, ) -> ty::GenericArg<'tcx> { - match arg.unpack() { + match arg.kind() { ty::GenericArgKind::Lifetime(_) => { self.next_region_var(RegionVariableOrigin::MiscVariable(span)).into() } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 49a8b363b0a..fda2c97ed56 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -207,7 +207,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { let infcx = self.goal.infcx; match goal.predicate.kind().no_bound_vars() { Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { - let unconstrained_term = match term.unpack() { + let unconstrained_term = match term.kind() { ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(), ty::TermKind::Const(_) => infcx.next_const_var(span).into(), }; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2be799735a8..3a2f9e8ca17 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1784,7 +1784,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if !generics.is_own_empty() && obligation.predicate.args[generics.parent_count..].iter().any(|&p| { p.has_non_region_infer() - && match p.unpack() { + && match p.kind() { ty::GenericArgKind::Const(ct) => { self.infcx.shallow_resolve_const(ct) != ct } diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index e6d5d336b8d..3f741345404 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -39,7 +39,7 @@ impl<'tcx> At<'_, 'tcx> { return Ok(term); } - let new_infer = match term.unpack() { + let new_infer = match term.kind() { ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(), ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(), }; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 08d3b92e9b5..3018dad8e09 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -37,7 +37,7 @@ pub fn obligations<'tcx>( span: Span, ) -> Option> { // Handle the "cycle" case (see comment above) by bailing out if necessary. - let term = match term.unpack() { + let term = match term.kind() { TermKind::Ty(ty) => { match ty.kind() { ty::Infer(ty::TyVar(_)) => { diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 98b1550e1a3..33d334092ba 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -74,7 +74,7 @@ fn representability_adt_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Representab // but the type parameters may cause a cycle with an upstream type let params_in_repr = tcx.params_in_repr(adt.did()); for (i, arg) in args.iter().enumerate() { - if let ty::GenericArgKind::Type(ty) = arg.unpack() { + if let ty::GenericArgKind::Type(ty) = arg.kind() { if params_in_repr.contains(i as u32) { rtry!(representability_ty(tcx, ty)); } @@ -104,7 +104,7 @@ fn params_in_repr_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, params_in_repr: &mut ty::Adt(adt, args) => { let inner_params_in_repr = tcx.params_in_repr(adt.did()); for (i, arg) in args.iter().enumerate() { - if let ty::GenericArgKind::Type(ty) = arg.unpack() { + if let ty::GenericArgKind::Type(ty) = arg.kind() { if inner_params_in_repr.contains(i as u32) { params_in_repr_ty(tcx, ty, params_in_repr); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 0c49ddff39b..330aaa25d13 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -274,7 +274,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe let def = tcx.adt_def(def_id); let num_params = tcx.generics_of(def_id).count(); - let maybe_unsizing_param_idx = |arg: ty::GenericArg<'tcx>| match arg.unpack() { + let maybe_unsizing_param_idx = |arg: ty::GenericArg<'tcx>| match arg.kind() { ty::GenericArgKind::Type(ty) => match ty.kind() { ty::Param(p) => Some(p.index), _ => None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 28dfa01534e..0fbffc7808d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -449,7 +449,7 @@ fn clean_middle_term<'tcx>( term: ty::Binder<'tcx, ty::Term<'tcx>>, cx: &mut DocContext<'tcx>, ) -> Term { - match term.skip_binder().unpack() { + match term.skip_binder().kind() { ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(term.rebind(ty), cx, None, None)), ty::TermKind::Const(c) => Term::Constant(clean_middle_const(term.rebind(c), cx)), } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 2e38b6cdc65..c58b07a5b67 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -124,7 +124,7 @@ pub(crate) fn clean_middle_generic_args<'tcx>( elision_has_failed_once_before = true; } - match arg.skip_binder().unpack() { + match arg.skip_binder().kind() { GenericArgKind::Lifetime(lt) => { Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided()))) } @@ -161,7 +161,7 @@ fn can_elide_generic_arg<'tcx>( default: ty::Binder<'tcx, ty::GenericArg<'tcx>>, ) -> bool { debug_assert_matches!( - (actual.skip_binder().unpack(), default.skip_binder().unpack()), + (actual.skip_binder().kind(), default.skip_binder().kind()), (ty::GenericArgKind::Lifetime(_), ty::GenericArgKind::Lifetime(_)) | (ty::GenericArgKind::Type(_), ty::GenericArgKind::Type(_)) | (ty::GenericArgKind::Const(_), ty::GenericArgKind::Const(_)) diff --git a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs index 2643f850879..9e09fb5bb43 100644 --- a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs +++ b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync { && let arg_ty = cx.typeck_results().expr_ty(arg) // make sure that the type is not and does not contain any type parameters && arg_ty.walk().all(|arg| { - !matches!(arg.unpack(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_))) + !matches!(arg.kind(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_))) }) && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send) && let Some(sync) = cx.tcx.lang_items().sync_trait() diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 3443b36eb4f..062f7cef3a7 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -345,7 +345,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h if ty_adt.repr().packed() && ty_subs .iter() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Type(_) | GenericArgKind::Const(_))) + .any(|arg| matches!(arg.kind(), GenericArgKind::Type(_) | GenericArgKind::Const(_))) { return; } diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 645f9306849..6ed7c87915b 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -306,7 +306,7 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<' return true; } for (from_arg, to_arg) in to_subs.iter().zip(from_subs) { - match (from_arg.unpack(), to_arg.unpack()) { + match (from_arg.kind(), to_arg.kind()) { (GenericArgKind::Lifetime(from_region), GenericArgKind::Lifetime(to_region)) => { if check_region(from_region, to_region) { return true; @@ -354,5 +354,5 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<' fn ty_has_static(ty: Ty<'_>) -> bool { ty.walk() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if re.is_static())) + .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if re.is_static())) } diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs index aba0fbcb9fe..106202d00d4 100644 --- a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs +++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs @@ -17,7 +17,7 @@ fn check_ty<'a>(cx: &LateContext<'a>, param: &rustc_hir::Ty<'a>, param_ty: Ty<'a && is_type_diagnostic_item(cx, *opt_ty, sym::Option) && let ty::Adt(_, opt_gen_args) = opt_ty.kind() && let [gen_arg] = opt_gen_args.as_slice() - && let GenericArgKind::Type(gen_ty) = gen_arg.unpack() + && let GenericArgKind::Type(gen_ty) = gen_arg.kind() && !gen_ty.is_ref() // Need to gen the original spans, so first parsing mid, and hir parsing afterward && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index 916191b2a7b..b72e14246db 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { && !local.span.in_external_macro(cx.tcx.sess.source_map()) { let init_ty = cx.typeck_results().expr_ty(init); - let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() { + let contains_sync_guard = init_ty.walk().any(|inner| match inner.kind() { GenericArgKind::Type(inner_ty) => inner_ty .ty_adt_def() .is_some_and(|adt| paths::PARKING_LOT_GUARDS.iter().any(|path| path.matches(cx, adt.did()))), diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs index 3ac2c9fc2b3..8c3f52542d9 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs @@ -109,7 +109,7 @@ fn handle( && implements_trait(cx, expr_type, default_trait_id, &[]) // We check if the initial condition implements Default. && let Some(condition_ty) = cx.typeck_results().expr_ty(condition).walk().nth(1) - && let GenericArgKind::Type(condition_ty) = condition_ty.unpack() + && let GenericArgKind::Type(condition_ty) = condition_ty.kind() && implements_trait(cx, condition_ty, default_trait_id, &[]) && is_default_equivalent(cx, peel_blocks(body_none)) { diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index aa9be61bf4d..c936c96f971 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -108,7 +108,7 @@ fn find_match_true<'tcx>( fn try_get_generic_ty(ty: Ty<'_>, index: usize) -> Option> { if let ty::Adt(_, subs) = ty.kind() && let Some(sub) = subs.get(index) - && let GenericArgKind::Type(sub_ty) = sub.unpack() + && let GenericArgKind::Type(sub_ty) = sub.kind() { Some(sub_ty) } else { diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 0f3ad40784d..88b4d9b7d54 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -208,12 +208,12 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { // (to avoid false positive on `Ref<'a, MutexGuard>`) || (args .iter() - .all(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_))) + .all(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_))) // some generic parameter has significant drop // (to avoid false negative on `Box>`) && args .iter() - .filter_map(|arg| match arg.unpack() { + .filter_map(|arg| match arg.kind() { GenericArgKind::Type(ty) => Some(ty), _ => None, }) diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 4c1ed6a1d83..2b75d6a8248 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -508,7 +508,7 @@ fn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet { match ty.kind() { ty::Adt(_, generics) => { for generic in *generics { - if let GenericArgKind::Type(ty) = generic.unpack() { + if let GenericArgKind::Type(ty) = generic.kind() { get_captured_ids_recursive(cx, ty, set); } } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index fb4984914eb..dbff08bc51c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -188,7 +188,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(expr); - matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_))) + matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(_))) } pub(super) fn check<'tcx>( diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 29a0d2950bc..768bbebccd4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -608,7 +608,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< } fn has_lifetime(ty: Ty<'_>) -> bool { - ty.walk().any(|t| matches!(t.unpack(), GenericArgKind::Lifetime(_))) + ty.walk().any(|t| matches!(t.kind(), GenericArgKind::Lifetime(_))) } /// Returns true if the named method is `Iterator::cloned` or `Iterator::copied`. @@ -643,7 +643,7 @@ fn is_to_string_on_string_like<'a>( if let Some(args) = cx.typeck_results().node_args_opt(call_expr.hir_id) && let [generic_arg] = args.as_slice() - && let GenericArgKind::Type(ty) = generic_arg.unpack() + && let GenericArgKind::Type(ty) = generic_arg.kind() && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) && (cx.get_associated_type(ty, deref_trait_id, sym::Target) == Some(cx.tcx.types.str_) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index e579dd5947d..2efb55b9880 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -269,7 +269,7 @@ fn needless_borrow_count<'tcx>( .tcx .is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) && let ty::Param(param_ty) = trait_predicate.self_ty().kind() - && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack() + && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].kind() && ty.is_array() && !msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) { diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 9542fed3875..8ff78ec7c58 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -172,7 +172,7 @@ impl NonSendField<'_> { /// Example: `MyStruct>` => `vec![P, Q, R]` fn collect_generic_params(ty: Ty<'_>) -> Vec> { ty.walk() - .filter_map(|inner| match inner.unpack() { + .filter_map(|inner| match inner.kind() { GenericArgKind::Type(inner_ty) => Some(inner_ty), _ => None, }) @@ -208,7 +208,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t ty::Adt(_, args) => { if contains_pointer_like(cx, ty) { // descends only if ADT contains any raw pointers - args.iter().all(|generic_arg| match generic_arg.unpack() { + args.iter().all(|generic_arg| match generic_arg.kind() { GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait), // Lifetimes and const generics are not solid part of ADT and ignored GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true, @@ -226,7 +226,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t /// Checks if the type contains any pointer-like types in args (including nested ones) fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool { for ty_node in target_ty.walk() { - if let GenericArgKind::Type(inner_ty) = ty_node.unpack() { + if let GenericArgKind::Type(inner_ty) = ty_node.kind() { match inner_ty.kind() { ty::RawPtr(_, _) => { return true; diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 6de203e068b..ba8f6354d97 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -385,7 +385,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { fn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool { match kind { FnKind::Fn => true, - FnKind::TraitFn => args.iter().enumerate().all(|(idx, subst)| match subst.unpack() { + FnKind::TraitFn => args.iter().enumerate().all(|(idx, subst)| match subst.kind() { GenericArgKind::Lifetime(_) => true, GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx), GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx), diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index ab9b0f88f93..6bc5af268ff 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -487,7 +487,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) .skip_binder() .output() .walk() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static())) + .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if !re.is_static())) { ControlFlow::Break(()) } else { diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index f3fea3add59..521754f7bab 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -184,7 +184,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { } } for generic_arg in *b { - if let GenericArgKind::Type(ty) = generic_arg.unpack() + if let GenericArgKind::Type(ty) = generic_arg.kind() && self.has_sig_drop_attr(ty, depth) { return true; diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 743f54ca993..aeda864b7eb 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -319,7 +319,7 @@ fn same_lifetimes<'tcx>(a: MiddleTy<'tcx>, b: MiddleTy<'tcx>) -> bool { args_a .iter() .zip(args_b.iter()) - .all(|(arg_a, arg_b)| match (arg_a.unpack(), arg_b.unpack()) { + .all(|(arg_a, arg_b)| match (arg_a.kind(), arg_b.kind()) { // TODO: Handle inferred lifetimes (GenericArgKind::Lifetime(inner_a), GenericArgKind::Lifetime(inner_b)) => inner_a == inner_b, (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => same_lifetimes(type_a, type_b), @@ -337,7 +337,7 @@ fn has_no_lifetime(ty: MiddleTy<'_>) -> bool { &Adt(_, args) => !args .iter() // TODO: Handle inferred lifetimes - .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(..))), + .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(..))), _ => true, } } diff --git a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs index 441c6884852..70b3c03d2bb 100644 --- a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs @@ -37,7 +37,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { .type_of(f.did) .instantiate_identity() .walk() - .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) + .filter(|t| matches!(t.kind(), GenericArgKind::Type(_))) .any(|t| internal_paths::MSRV_STACK.matches_ty(cx, t.expect_ty())) }) && !items.iter().any(|item| item.ident.name.as_str() == "check_attributes") diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 3a319176571..8716ee48c88 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3316,7 +3316,7 @@ pub fn leaks_droppable_temporary_with_limited_lifetime<'tcx>(cx: &LateContext<'t if temporary_ty.has_significant_drop(cx.tcx, cx.typing_env()) && temporary_ty .walk() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static())) + .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if !re.is_static())) { ControlFlow::Break(()) } else { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 45da266fd8a..bb04520c6b7 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -55,7 +55,7 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, msrv: Msrv) -> McfResult { for arg in ty.walk() { - let ty = match arg.unpack() { + let ty = match arg.kind() { GenericArgKind::Type(ty) => ty, // No constraints on lifetimes or constants, except potentially diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index c50ad17bfad..61e70b3fa0b 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -78,7 +78,7 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool /// Walks into `ty` and returns `true` if any inner type is an instance of the given adt /// constructor. pub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool { - ty.walk().any(|inner| match inner.unpack() { + ty.walk().any(|inner| match inner.kind() { GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt), GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, }) @@ -96,7 +96,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' needle: Ty<'tcx>, seen: &mut FxHashSet, ) -> bool { - ty.walk().any(|inner| match inner.unpack() { + ty.walk().any(|inner| match inner.kind() { GenericArgKind::Type(inner_ty) => { if inner_ty == needle { return true; @@ -129,7 +129,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' // For `impl Trait`, it will register a predicate of `::Assoc = U`, // so we check the term for `U`. ty::ClauseKind::Projection(projection_predicate) => { - if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack() + if let ty::TermKind::Ty(ty) = projection_predicate.term.kind() && contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) { return true; @@ -526,7 +526,7 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { args_a .iter() .zip(args_b.iter()) - .all(|(arg_a, arg_b)| match (arg_a.unpack(), arg_b.unpack()) { + .all(|(arg_a, arg_b)| match (arg_a.kind(), arg_b.kind()) { (GenericArgKind::Const(inner_a), GenericArgKind::Const(inner_b)) => inner_a == inner_b, (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => { same_type_and_consts(type_a, type_b) @@ -996,7 +996,7 @@ fn assert_generic_args_match<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, args: &[Generi if let Some((idx, (param, arg))) = params .clone() - .zip(args.iter().map(|&x| x.unpack())) + .zip(args.iter().map(|&x| x.kind())) .enumerate() .find(|(_, (param, arg))| match (param, arg) { (GenericParamDefKind::Lifetime, GenericArgKind::Lifetime(_)) diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index 6e358662327..84df36c75bf 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -326,5 +326,5 @@ fn adt_def_id(ty: Ty<'_>) -> Option { fn contains_param(ty: Ty<'_>, index: u32) -> bool { ty.walk() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Type(ty) if ty.is_param(index))) + .any(|arg| matches!(arg.kind(), GenericArgKind::Type(ty) if ty.is_param(index))) } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 5d5c19a24fa..e7a2cb25159 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1775,7 +1775,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { let is_generic = instance .args .into_iter() - .any(|kind| !matches!(kind.unpack(), ty::GenericArgKind::Lifetime(_))); + .any(|arg| !matches!(arg.kind(), ty::GenericArgKind::Lifetime(_))); let can_be_inlined = matches!( ecx.tcx.sess.opts.unstable_opts.cross_crate_inline_threshold, InliningThreshold::Always -- cgit 1.4.1-3-g733a5 From c593c0170347c016e54ab754d8dcdc283f4f4dfb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:39:26 +0000 Subject: Remove codegen_unit from MiscCodegenMethods --- compiler/rustc_codegen_gcc/src/base.rs | 11 ++++++--- compiler/rustc_codegen_gcc/src/context.rs | 4 ---- compiler/rustc_codegen_llvm/src/base.rs | 13 ++++++++--- compiler/rustc_codegen_llvm/src/context.rs | 4 ---- compiler/rustc_codegen_ssa/src/base.rs | 5 +++-- compiler/rustc_codegen_ssa/src/mono_item.rs | 32 +++++++-------------------- compiler/rustc_codegen_ssa/src/traits/misc.rs | 2 -- 7 files changed, 29 insertions(+), 42 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index a9d7808c833..c3ba975d964 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -219,17 +219,22 @@ pub fn compile_codegen_unit( let mono_items = cgu.items_in_deterministic_order(tcx); for &(mono_item, data) in &mono_items { - mono_item.predefine::>(&cx, data.linkage, data.visibility); + mono_item.predefine::>( + &cx, + cgu_name.as_str(), + data.linkage, + data.visibility, + ); } // ... and now that we have everything pre-defined, fill out those definitions. for &(mono_item, item_data) in &mono_items { - mono_item.define::>(&mut cx, item_data); + mono_item.define::>(&mut cx, cgu_name.as_str(), item_data); } // If this codegen unit contains the main function, also create the // wrapper here - maybe_create_entry_wrapper::>(&cx); + maybe_create_entry_wrapper::>(&cx, cx.codegen_unit); // Finalize debuginfo if cx.sess().opts.debuginfo != DebugInfo::None { diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 73718994e64..c6c43201f21 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -470,10 +470,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.tcx.sess } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { - self.codegen_unit - } - fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) { // TODO(antoyo) } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index e4fac35aa44..4d52696a5cc 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -86,17 +86,24 @@ pub(crate) fn compile_codegen_unit( let mut cx = CodegenCx::new(tcx, cgu, &llvm_module); let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); for &(mono_item, data) in &mono_items { - mono_item.predefine::>(&cx, data.linkage, data.visibility); + mono_item.predefine::>( + &cx, + cgu_name.as_str(), + data.linkage, + data.visibility, + ); } // ... and now that we have everything pre-defined, fill out those definitions. for &(mono_item, item_data) in &mono_items { - mono_item.define::>(&mut cx, item_data); + mono_item.define::>(&mut cx, cgu_name.as_str(), item_data); } // If this codegen unit contains the main function, also create the // wrapper here - if let Some(entry) = maybe_create_entry_wrapper::>(&cx) { + if let Some(entry) = + maybe_create_entry_wrapper::>(&cx, cx.codegen_unit) + { let attrs = attributes::sanitize_attrs(&cx, SanitizerSet::empty()); attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index b0d8e11d1fb..c8cbc859bfd 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -801,10 +801,6 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.tcx.sess } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { - self.codegen_unit - } - fn set_frame_pointer_type(&self, llfn: &'ll Value) { if let Some(attr) = attributes::frame_pointer_type_attr(self) { attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 1890119dca7..f7863fe4ae2 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -492,6 +492,7 @@ where /// users main function. pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, + cgu: &CodegenUnit<'tcx>, ) -> Option { let (main_def_id, entry_type) = cx.tcx().entry_fn(())?; let main_is_local = main_def_id.is_local(); @@ -500,10 +501,10 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if main_is_local { // We want to create the wrapper in the same codegen unit as Rust's main // function. - if !cx.codegen_unit().contains_item(&MonoItem::Fn(instance)) { + if !cgu.contains_item(&MonoItem::Fn(instance)) { return None; } - } else if !cx.codegen_unit().is_primary() { + } else if !cgu.is_primary() { // We want to create the wrapper only when the codegen unit is the primary one return None; } diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index c2067e52afe..e6bb3090843 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -11,11 +11,13 @@ pub trait MonoItemExt<'a, 'tcx> { fn define>( &self, cx: &'a mut Bx::CodegenCx, + cgu_name: &str, item_data: MonoItemData, ); fn predefine>( &self, cx: &'a Bx::CodegenCx, + cgu_name: &str, linkage: Linkage, visibility: Visibility, ); @@ -26,14 +28,10 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn define>( &self, cx: &'a mut Bx::CodegenCx, + cgu_name: &str, item_data: MonoItemData, ) { - debug!( - "BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self, - self.to_raw_string(), - cx.codegen_unit().name() - ); + debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", self, self.to_raw_string(), cgu_name); match *self { MonoItem::Static(def_id) => { @@ -56,26 +54,17 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } } - debug!( - "END IMPLEMENTING '{} ({})' in cgu {}", - self, - self.to_raw_string(), - cx.codegen_unit().name() - ); + debug!("END IMPLEMENTING '{} ({})' in cgu {}", self, self.to_raw_string(), cgu_name); } fn predefine>( &self, cx: &'a Bx::CodegenCx, + cgu_name: &str, linkage: Linkage, visibility: Visibility, ) { - debug!( - "BEGIN PREDEFINING '{} ({})' in cgu {}", - self, - self.to_raw_string(), - cx.codegen_unit().name() - ); + debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", self, self.to_raw_string(), cgu_name); let symbol_name = self.symbol_name(cx.tcx()).name; @@ -97,12 +86,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { MonoItem::GlobalAsm(..) => {} } - debug!( - "END PREDEFINING '{} ({})' in cgu {}", - self, - self.to_raw_string(), - cx.codegen_unit().name() - ); + debug!("END PREDEFINING '{} ({})' in cgu {}", self, self.to_raw_string(), cgu_name); } fn to_raw_string(&self) -> String { diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 4004947b464..d6dad4a1d19 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::{self, Instance, Ty}; use rustc_session::Session; @@ -22,7 +21,6 @@ pub trait MiscCodegenMethods<'tcx>: BackendTypes { fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn sess(&self) -> &Session; - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>; fn set_frame_pointer_type(&self, llfn: Self::Function); fn apply_target_cpu_attr(&self, llfn: Self::Function); /// Declares the extern "C" main function for the entry point. Returns None if the symbol -- cgit 1.4.1-3-g733a5 From 5b0ab2cbdd5c573a58986b5ec47ec1bc17abefd6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:40:45 +0000 Subject: The personality function is a Function, not a Value --- compiler/rustc_codegen_ssa/src/traits/builder.rs | 6 +++--- compiler/rustc_codegen_ssa/src/traits/misc.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f66309cf340..a7f05b2de26 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -514,11 +514,11 @@ pub trait BuilderMethods<'a, 'tcx>: fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value; fn insert_value(&mut self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value; - fn set_personality_fn(&mut self, personality: Self::Value); + fn set_personality_fn(&mut self, personality: Self::Function); // These are used by everyone except msvc - fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value); - fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value); + fn cleanup_landing_pad(&mut self, pers_fn: Self::Function) -> (Self::Value, Self::Value); + fn filter_landing_pad(&mut self, pers_fn: Self::Function) -> (Self::Value, Self::Value); fn resume(&mut self, exn0: Self::Value, exn1: Self::Value); // These are used only by msvc diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index d6dad4a1d19..710fab27901 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -19,7 +19,7 @@ pub trait MiscCodegenMethods<'tcx>: BackendTypes { } fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; - fn eh_personality(&self) -> Self::Value; + fn eh_personality(&self) -> Self::Function; fn sess(&self) -> &Session; fn set_frame_pointer_type(&self, llfn: Self::Function); fn apply_target_cpu_attr(&self, llfn: Self::Function); -- cgit 1.4.1-3-g733a5 From a4cb1c72c521a1300a3a88d46b721677e1380e3d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:44:43 +0000 Subject: Reduce amount of types that need to be PartialEq --- compiler/rustc_codegen_ssa/src/traits/backend.rs | 4 ++-- compiler/rustc_codegen_ssa/src/traits/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index e2f1458d062..c3ef95d09b5 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -21,12 +21,12 @@ use crate::back::write::TargetMachineFactoryFn; use crate::{CodegenResults, ModuleCodegen, TargetConfig}; pub trait BackendTypes { - type Value: CodegenObject; + type Value: CodegenObject + PartialEq; type Metadata: CodegenObject; type Function: CodegenObject; type BasicBlock: Copy; - type Type: CodegenObject; + type Type: CodegenObject + PartialEq; type Funclet; // FIXME(eddyb) find a common convention for all of the debuginfo-related diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index 239857a4298..6d1ac717c0b 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -50,7 +50,7 @@ pub use self::type_::{ }; pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods}; -pub trait CodegenObject = Copy + PartialEq + fmt::Debug; +pub trait CodegenObject = Copy + fmt::Debug; pub trait CodegenMethods<'tcx> = LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>> -- cgit 1.4.1-3-g733a5 From 0fd257d66ca761c5eba965fac52acffe3a8a7d96 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:52:38 +0000 Subject: Remove a couple of uses of interior mutability around statics --- compiler/rustc_codegen_gcc/src/consts.rs | 6 +++--- compiler/rustc_codegen_llvm/src/base.rs | 11 ++++------- compiler/rustc_codegen_llvm/src/consts.rs | 12 ++++++------ compiler/rustc_codegen_llvm/src/context.rs | 17 ++++++++++++----- compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 5 +++-- .../src/coverageinfo/mapgen/covfun.rs | 2 +- compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/statics.rs | 6 +++--- 8 files changed, 33 insertions(+), 28 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 8aed04c836a..fbf9e11c45e 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -67,7 +67,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { } #[cfg_attr(not(feature = "master"), allow(unused_mut))] - fn codegen_static(&self, def_id: DefId) { + fn codegen_static(&mut self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else { @@ -162,11 +162,11 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { } /// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*. - fn add_used_global(&self, _global: RValue<'gcc>) { + fn add_used_global(&mut self, _global: RValue<'gcc>) { // TODO(antoyo) } - fn add_compiler_used_global(&self, global: RValue<'gcc>) { + fn add_compiler_used_global(&mut self, global: RValue<'gcc>) { // NOTE: seems like GCC does not make the distinction between compiler.used and used. self.add_used_global(global); } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 4d52696a5cc..2eb11766869 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -115,14 +115,11 @@ pub(crate) fn compile_codegen_unit( } // Create the llvm.used and llvm.compiler.used variables. - if !cx.used_statics.borrow().is_empty() { - cx.create_used_variable_impl(c"llvm.used", &*cx.used_statics.borrow()); + if !cx.used_statics.is_empty() { + cx.create_used_variable_impl(c"llvm.used", &cx.used_statics); } - if !cx.compiler_used_statics.borrow().is_empty() { - cx.create_used_variable_impl( - c"llvm.compiler.used", - &*cx.compiler_used_statics.borrow(), - ); + if !cx.compiler_used_statics.is_empty() { + cx.create_used_variable_impl(c"llvm.compiler.used", &cx.compiler_used_statics); } // Run replace-all-uses-with for statics that need it. This must diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index fe2f2027327..a4dd0515c3a 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -411,7 +411,7 @@ impl<'ll> CodegenCx<'ll, '_> { g } - fn codegen_static_item(&self, def_id: DefId) { + fn codegen_static_item(&mut self, def_id: DefId) { unsafe { assert!( llvm::LLVMGetInitializer( @@ -571,18 +571,18 @@ impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { self.const_pointercast(gv, self.type_ptr()) } - fn codegen_static(&self, def_id: DefId) { + fn codegen_static(&mut self, def_id: DefId) { self.codegen_static_item(def_id) } /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr. - fn add_used_global(&self, global: &'ll Value) { - self.used_statics.borrow_mut().push(global); + fn add_used_global(&mut self, global: &'ll Value) { + self.used_statics.push(global); } /// Add a global value to a list to be stored in the `llvm.compiler.used` variable, /// an array of ptr. - fn add_compiler_used_global(&self, global: &'ll Value) { - self.compiler_used_statics.borrow_mut().push(global); + fn add_compiler_used_global(&mut self, global: &'ll Value) { + self.compiler_used_statics.push(global); } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c8cbc859bfd..8cc2cb9c333 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -2,7 +2,7 @@ use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, c_char, c_uint}; use std::marker::PhantomData; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use std::str; use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx}; @@ -77,6 +77,13 @@ impl<'ll, T: Borrow>> Deref for GenericCx<'ll, T> { } } +impl<'ll, T: Borrow>> DerefMut for GenericCx<'ll, T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + pub(crate) type SimpleCx<'ll> = GenericCx<'ll, SCx<'ll>>; /// There is one `CodegenCx` per codegen unit. Each one has its own LLVM @@ -110,11 +117,11 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Statics that will be placed in the llvm.used variable /// See for details - pub used_statics: RefCell>, + pub used_statics: Vec<&'ll Value>, /// Statics that will be placed in the llvm.compiler.used variable /// See for details - pub compiler_used_statics: RefCell>, + pub compiler_used_statics: Vec<&'ll Value>, /// Mapping of non-scalar types to llvm types. pub type_lowering: RefCell, Option), &'ll Type>>, @@ -606,8 +613,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { const_str_cache: Default::default(), const_globals: Default::default(), statics_to_rauw: RefCell::new(Vec::new()), - used_statics: RefCell::new(Vec::new()), - compiler_used_statics: RefCell::new(Vec::new()), + used_statics: Vec::new(), + compiler_used_statics: Vec::new(), type_lowering: Default::default(), scalar_lltypes: Default::default(), coverage_cx, diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 55b1e728b70..17b9c6464db 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -27,7 +27,7 @@ mod unused; /// /// Those sections are then read and understood by LLVM's `llvm-cov` tool, /// which is distributed in the `llvm-tools` rustup component. -pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { +pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) { let tcx = cx.tcx; // Ensure that LLVM is using a version of the coverage mapping format that @@ -62,6 +62,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { .sorted_by_cached_key(|&instance| tcx.symbol_name(instance).name) .filter_map(|instance| prepare_covfun_record(tcx, instance, true)) .collect::>(); + drop(instances_used); // In a single designated CGU, also prepare covfun records for functions // in this crate that were instrumented for coverage, but are unused. @@ -206,7 +207,7 @@ impl VirtualFileMapping { /// Generates the contents of the covmap record for this CGU, which mostly /// consists of a header and a list of filenames. The record is then stored /// as a global variable in the `__llvm_covmap` section. -fn generate_covmap_record<'ll>(cx: &CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) { +fn generate_covmap_record<'ll>(cx: &mut CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) { // A covmap record consists of four target-endian u32 values, followed by // the encoded filenames table. Two of the header fields are unused in // modern versions of the LLVM coverage mapping format, and are always 0. diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index 7bdbc685952..4c866e4a66b 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -181,7 +181,7 @@ fn fill_region_tables<'tcx>( /// contains the function's coverage mapping data. The record is then stored /// as a global variable in the `__llvm_covfun` section. pub(crate) fn generate_covfun_record<'tcx>( - cx: &CodegenCx<'_, 'tcx>, + cx: &mut CodegenCx<'_, 'tcx>, global_file_table: &GlobalFileTable, covfun: &CovfunRecord<'tcx>, ) { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index ea7f581a3cb..eefbd7cf6c4 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -56,7 +56,7 @@ impl<'ll, 'tcx> CguCoverageContext<'ll, 'tcx> { } impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { - pub(crate) fn coverageinfo_finalize(&self) { + pub(crate) fn coverageinfo_finalize(&mut self) { mapgen::finalize(self) } diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index ece0ea1b2ea..a11a1ca4d03 100644 --- a/compiler/rustc_codegen_ssa/src/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs @@ -5,11 +5,11 @@ use super::BackendTypes; pub trait StaticCodegenMethods: BackendTypes { fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; - fn codegen_static(&self, def_id: DefId); + fn codegen_static(&mut self, def_id: DefId); /// Mark the given global value as "used", to prevent the compiler and linker from potentially /// removing a static variable that may otherwise appear unused. - fn add_used_global(&self, global: Self::Value); + fn add_used_global(&mut self, global: Self::Value); /// Same as add_used_global(), but only prevent the compiler from potentially removing an /// otherwise unused symbol. The linker is still permitted to drop it. @@ -17,7 +17,7 @@ pub trait StaticCodegenMethods: BackendTypes { /// This corresponds to the documented semantics of the `#[used]` attribute, although /// on some targets (non-ELF), we may use `add_used_global` for `#[used]` statics /// instead. - fn add_compiler_used_global(&self, global: Self::Value); + fn add_compiler_used_global(&mut self, global: Self::Value); } pub trait StaticBuilderMethods: BackendTypes { -- cgit 1.4.1-3-g733a5 From 0809b41cd9c0d594c724ffbc9b21abf889ab174f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:17:07 +0000 Subject: Move supports_parallel from CodegenBackend to ExtraBackendMethods It is only relevant when using cg_ssa for driving compilation. --- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/backend.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 0fd4ed8475b..c073d950690 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -383,7 +383,7 @@ pub struct CodegenContext { pub coordinator_send: Sender>, /// `true` if the codegen should be run in parallel. /// - /// Depends on [`CodegenBackend::supports_parallel()`] and `-Zno_parallel_backend`. + /// Depends on [`ExtraBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`. pub parallel: bool, } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index c3ef95d09b5..95bf3b16685 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -97,13 +97,6 @@ pub trait CodegenBackend { fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) { link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, outputs); } - - /// Returns `true` if this backend can be safely called from multiple threads. - /// - /// Defaults to `true`. - fn supports_parallel(&self) -> bool { - true - } } pub trait ExtraBackendMethods: @@ -144,4 +137,11 @@ pub trait ExtraBackendMethods: { std::thread::Builder::new().name(name).spawn(f) } + + /// Returns `true` if this backend can be safely called from multiple threads. + /// + /// Defaults to `true`. + fn supports_parallel(&self) -> bool { + true + } } -- cgit 1.4.1-3-g733a5 From 669e2ea8487787c2641b50d958cd3e01c7e762ef Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:21:43 +0000 Subject: Make predefine methods take &mut self --- compiler/rustc_codegen_gcc/src/base.rs | 2 +- compiler/rustc_codegen_gcc/src/mono_item.rs | 4 ++-- compiler/rustc_codegen_llvm/src/base.rs | 2 +- compiler/rustc_codegen_llvm/src/mono_item.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mono_item.rs | 4 ++-- compiler/rustc_codegen_ssa/src/traits/declare.rs | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index c3ba975d964..c105916bbb2 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -220,7 +220,7 @@ pub fn compile_codegen_unit( let mono_items = cgu.items_in_deterministic_order(tcx); for &(mono_item, data) in &mono_items { mono_item.predefine::>( - &cx, + &mut cx, cgu_name.as_str(), data.linkage, data.visibility, diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs index a2df7b2596f..539e3ac8507 100644 --- a/compiler/rustc_codegen_gcc/src/mono_item.rs +++ b/compiler/rustc_codegen_gcc/src/mono_item.rs @@ -16,7 +16,7 @@ use crate::{attributes, base}; impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_static( - &self, + &mut self, def_id: DefId, _linkage: Linkage, visibility: Visibility, @@ -42,7 +42,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_fn( - &self, + &mut self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 2eb11766869..5dda836988c 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -87,7 +87,7 @@ pub(crate) fn compile_codegen_unit( let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); for &(mono_item, data) in &mono_items { mono_item.predefine::>( - &cx, + &mut cx, cgu_name.as_str(), data.linkage, data.visibility, diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index fdf62a08065..3f38e1e191b 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -16,7 +16,7 @@ use crate::{base, llvm}; impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { fn predefine_static( - &self, + &mut self, def_id: DefId, linkage: Linkage, visibility: Visibility, @@ -44,7 +44,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { } fn predefine_fn( - &self, + &mut self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index e6bb3090843..7b4268abe4b 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -16,7 +16,7 @@ pub trait MonoItemExt<'a, 'tcx> { ); fn predefine>( &self, - cx: &'a Bx::CodegenCx, + cx: &'a mut Bx::CodegenCx, cgu_name: &str, linkage: Linkage, visibility: Visibility, @@ -59,7 +59,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn predefine>( &self, - cx: &'a Bx::CodegenCx, + cx: &'a mut Bx::CodegenCx, cgu_name: &str, linkage: Linkage, visibility: Visibility, diff --git a/compiler/rustc_codegen_ssa/src/traits/declare.rs b/compiler/rustc_codegen_ssa/src/traits/declare.rs index c1edeac31b0..9f735546558 100644 --- a/compiler/rustc_codegen_ssa/src/traits/declare.rs +++ b/compiler/rustc_codegen_ssa/src/traits/declare.rs @@ -4,14 +4,14 @@ use rustc_middle::ty::Instance; pub trait PreDefineCodegenMethods<'tcx> { fn predefine_static( - &self, + &mut self, def_id: DefId, linkage: Linkage, visibility: Visibility, symbol_name: &str, ); fn predefine_fn( - &self, + &mut self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, -- cgit 1.4.1-3-g733a5 From d7c0bde0c11301b9a782eabc469f7a7548505d4f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:29:05 +0000 Subject: Remove methods from StaticCodegenMethods that are not called in cg_ssa itself --- compiler/rustc_codegen_gcc/src/consts.rs | 11 +++-------- compiler/rustc_codegen_llvm/src/consts.rs | 22 +++++++++++----------- .../rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 4 +--- .../src/coverageinfo/mapgen/covfun.rs | 4 +--- compiler/rustc_codegen_ssa/src/traits/statics.rs | 12 ------------ 5 files changed, 16 insertions(+), 37 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index fbf9e11c45e..deb13ddf755 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -160,19 +160,14 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { self.add_used_global(global.to_rvalue()); } } +} +impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*. - fn add_used_global(&mut self, _global: RValue<'gcc>) { + pub fn add_used_global(&mut self, _global: RValue<'gcc>) { // TODO(antoyo) } - fn add_compiler_used_global(&mut self, global: RValue<'gcc>) { - // NOTE: seems like GCC does not make the distinction between compiler.used and used. - self.add_used_global(global); - } -} - -impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { #[cfg_attr(not(feature = "master"), allow(unused_variables))] pub fn add_used_function(&self, function: Function<'gcc>) { #[cfg(feature = "master")] diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index a4dd0515c3a..4234352c93a 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -557,6 +557,17 @@ impl<'ll> CodegenCx<'ll, '_> { } } } + + /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr. + pub(crate) fn add_used_global(&mut self, global: &'ll Value) { + self.used_statics.push(global); + } + + /// Add a global value to a list to be stored in the `llvm.compiler.used` variable, + /// an array of ptr. + pub(crate) fn add_compiler_used_global(&mut self, global: &'ll Value) { + self.compiler_used_statics.push(global); + } } impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { @@ -574,15 +585,4 @@ impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { fn codegen_static(&mut self, def_id: DefId) { self.codegen_static_item(def_id) } - - /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr. - fn add_used_global(&mut self, global: &'ll Value) { - self.used_statics.push(global); - } - - /// Add a global value to a list to be stored in the `llvm.compiler.used` variable, - /// an array of ptr. - fn add_compiler_used_global(&mut self, global: &'ll Value) { - self.compiler_used_statics.push(global); - } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 17b9c6464db..a9be833a643 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -2,9 +2,7 @@ use std::sync::Arc; use itertools::Itertools; use rustc_abi::Align; -use rustc_codegen_ssa::traits::{ - BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods, -}; +use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index 4c866e4a66b..b704cf2b1cd 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -8,9 +8,7 @@ use std::ffi::CString; use std::sync::Arc; use rustc_abi::Align; -use rustc_codegen_ssa::traits::{ - BaseTypeCodegenMethods as _, ConstCodegenMethods, StaticCodegenMethods, -}; +use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods as _, ConstCodegenMethods}; use rustc_middle::mir::coverage::{ BasicCoverageBlock, CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping, MappingKind, Op, diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index a11a1ca4d03..0e1e445c72f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs @@ -6,18 +6,6 @@ use super::BackendTypes; pub trait StaticCodegenMethods: BackendTypes { fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; fn codegen_static(&mut self, def_id: DefId); - - /// Mark the given global value as "used", to prevent the compiler and linker from potentially - /// removing a static variable that may otherwise appear unused. - fn add_used_global(&mut self, global: Self::Value); - - /// Same as add_used_global(), but only prevent the compiler from potentially removing an - /// otherwise unused symbol. The linker is still permitted to drop it. - /// - /// This corresponds to the documented semantics of the `#[used]` attribute, although - /// on some targets (non-ELF), we may use `add_used_global` for `#[used]` statics - /// instead. - fn add_compiler_used_global(&mut self, global: Self::Value); } pub trait StaticBuilderMethods: BackendTypes { -- cgit 1.4.1-3-g733a5 From f0707fad319777ed5da4b6eb1eb908cb44ab8c18 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:41:19 +0000 Subject: Mark all optimize methods and the codegen method as safe There is no safety contract and I don't think any of them can actually cause UB in more ways than passing malicious source code to rustc can. While LtoModuleCodegen::optimize says that the returned ModuleCodegen points into the LTO module, the LTO module has already been dropped by the time this function returns, so if the returned ModuleCodegen indeed points into the LTO module, we would have seen crashes on every LTO compilation, which we don't. As such the comment is outdated. --- compiler/rustc_codegen_gcc/src/lib.rs | 6 +++--- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 4 ++-- compiler/rustc_codegen_llvm/src/lib.rs | 12 ++++++------ compiler/rustc_codegen_ssa/src/back/lto.rs | 11 +++-------- compiler/rustc_codegen_ssa/src/back/write.rs | 16 ++++++---------- compiler/rustc_codegen_ssa/src/traits/write.rs | 8 ++++---- 7 files changed, 25 insertions(+), 34 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 6994c385fc8..f79ba2dcfc7 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -391,7 +391,7 @@ impl WriteBackendMethods for GccCodegenBackend { unimplemented!() } - unsafe fn optimize( + fn optimize( _cgcx: &CodegenContext, _dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, @@ -409,14 +409,14 @@ impl WriteBackendMethods for GccCodegenBackend { Ok(()) } - unsafe fn optimize_thin( + fn optimize_thin( cgcx: &CodegenContext, thin: ThinModule, ) -> Result, FatalError> { back::lto::optimize_thin_module(thin, cgcx) } - unsafe fn codegen( + fn codegen( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index cb329323f5d..ee46b49a094 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -799,7 +799,7 @@ impl Drop for ThinBuffer { } } -pub(crate) unsafe fn optimize_thin_module( +pub(crate) fn optimize_thin_module( thin_module: ThinModule, cgcx: &CodegenContext, ) -> Result, FatalError> { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 20721c74608..bde6a9cf4bc 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -704,7 +704,7 @@ pub(crate) unsafe fn llvm_optimize( } // Unsafe due to LLVM calls. -pub(crate) unsafe fn optimize( +pub(crate) fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, @@ -815,7 +815,7 @@ pub(crate) fn link( Ok(modules.remove(0)) } -pub(crate) unsafe fn codegen( +pub(crate) fn codegen( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 5736314b96a..fd376ea8d80 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -189,13 +189,13 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) -> Result<(Vec>, Vec), FatalError> { back::lto::run_thin(cgcx, modules, cached_modules) } - unsafe fn optimize( + fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { - unsafe { back::write::optimize(cgcx, dcx, module, config) } + back::write::optimize(cgcx, dcx, module, config) } fn optimize_fat( cgcx: &CodegenContext, @@ -205,19 +205,19 @@ impl WriteBackendMethods for LlvmCodegenBackend { let dcx = dcx.handle(); back::lto::run_pass_manager(cgcx, dcx, module, false) } - unsafe fn optimize_thin( + fn optimize_thin( cgcx: &CodegenContext, thin: ThinModule, ) -> Result, FatalError> { - unsafe { back::lto::optimize_thin_module(thin, cgcx) } + back::lto::optimize_thin_module(thin, cgcx) } - unsafe fn codegen( + fn codegen( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, config: &ModuleConfig, ) -> Result { - unsafe { back::write::codegen(cgcx, dcx, module, config) } + back::write::codegen(cgcx, dcx, module, config) } fn prepare_thin( module: ModuleCodegen, diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index 9fd984b6419..ce6fe8a191b 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -56,12 +56,7 @@ impl LtoModuleCodegen { } /// Optimize this module within the given codegen context. - /// - /// This function is unsafe as it'll return a `ModuleCodegen` still - /// points to LLVM data structures owned by this `LtoModuleCodegen`. - /// It's intended that the module returned is immediately code generated and - /// dropped, and then this LTO module is dropped. - pub unsafe fn optimize( + pub fn optimize( self, cgcx: &CodegenContext, ) -> Result, FatalError> { @@ -70,7 +65,7 @@ impl LtoModuleCodegen { B::optimize_fat(cgcx, &mut module)?; Ok(module) } - LtoModuleCodegen::Thin(thin) => unsafe { B::optimize_thin(cgcx, thin) }, + LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin), } } @@ -85,7 +80,7 @@ impl LtoModuleCodegen { } /// Run autodiff on Fat LTO module - pub unsafe fn autodiff( + pub fn autodiff( self, cgcx: &CodegenContext, diff_fncs: Vec, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c073d950690..a41ca8ce28b 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -416,8 +416,7 @@ fn generate_lto_work( B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); if cgcx.lto == Lto::Fat && !autodiff.is_empty() { let config = cgcx.config(ModuleKind::Regular); - module = - unsafe { module.autodiff(cgcx, autodiff, config).unwrap_or_else(|e| e.raise()) }; + module = module.autodiff(cgcx, autodiff, config).unwrap_or_else(|e| e.raise()); } // We are adding a single work item, so the cost doesn't matter. vec![(WorkItem::LTO(module), 0)] @@ -887,9 +886,7 @@ fn execute_optimize_work_item( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); - unsafe { - B::optimize(cgcx, dcx, &mut module, module_config)?; - } + B::optimize(cgcx, dcx, &mut module, module_config)?; // After we've done the initial round of optimizations we need to // decide whether to synchronously codegen this module or ship it @@ -1020,7 +1017,7 @@ fn execute_lto_work_item( module: lto::LtoModuleCodegen, module_config: &ModuleConfig, ) -> Result, FatalError> { - let module = unsafe { module.optimize(cgcx)? }; + let module = module.optimize(cgcx)?; finish_intra_module_work(cgcx, module, module_config) } @@ -1036,7 +1033,7 @@ fn finish_intra_module_work( || module.kind == ModuleKind::Metadata || module.kind == ModuleKind::Allocator { - let module = unsafe { B::codegen(cgcx, dcx, module, module_config)? }; + let module = B::codegen(cgcx, dcx, module, module_config)?; Ok(WorkItemResult::Finished(module)) } else { Ok(WorkItemResult::NeedsLink(module)) @@ -1725,9 +1722,8 @@ fn start_executing_work( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); let module = B::run_link(&cgcx, dcx, needs_link).map_err(|_| ())?; - let module = unsafe { - B::codegen(&cgcx, dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())? - }; + let module = + B::codegen(&cgcx, dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?; compiled_modules.push(module); } diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index c77efdd1728..07a0609fda1 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -6,7 +6,7 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig}; use crate::{CompiledModule, ModuleCodegen}; -pub trait WriteBackendMethods: 'static + Sized + Clone { +pub trait WriteBackendMethods: Clone + 'static { type Module: Send + Sync; type TargetMachine; type TargetMachineError; @@ -37,7 +37,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { ) -> Result<(Vec>, Vec), FatalError>; fn print_pass_timings(&self); fn print_statistics(&self); - unsafe fn optimize( + fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, @@ -47,11 +47,11 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { cgcx: &CodegenContext, llmod: &mut ModuleCodegen, ) -> Result<(), FatalError>; - unsafe fn optimize_thin( + fn optimize_thin( cgcx: &CodegenContext, thin: ThinModule, ) -> Result, FatalError>; - unsafe fn codegen( + fn codegen( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, -- cgit 1.4.1-3-g733a5 From 865c7b9c7829b202f16657fc35895d1357ad6f2f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:50:01 +0000 Subject: Remove unused arg_memory_ty method --- compiler/rustc_codegen_gcc/src/abi.rs | 7 +++---- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 11 ----------- compiler/rustc_codegen_llvm/src/abi.rs | 10 ---------- compiler/rustc_codegen_ssa/src/traits/type_.rs | 1 - 4 files changed, 3 insertions(+), 26 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index d882d3eecf4..0c499ba6237 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -15,7 +15,6 @@ use rustc_target::callconv::{Conv, RiscvInterruptKind}; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; impl AbiBuilderMethods for Builder<'_, '_, '_> { @@ -125,7 +124,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), PassMode::Cast { ref cast, .. } => cast.gcc_type(cx), PassMode::Indirect { .. } => { - argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); + argument_tys.push(cx.type_ptr_to(self.ret.layout.gcc_type(cx))); cx.type_void() } }; @@ -176,13 +175,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => { // This is a "byval" argument, so we don't apply the `restrict` attribute on it. on_stack_param_indices.insert(argument_tys.len()); - arg.memory_ty(cx) + arg.layout.gcc_type(cx) } PassMode::Direct(attrs) => { apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()) } PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { - apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()) + apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len()) } PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { assert!(!on_stack); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 1bcb891a250..ff1ae2d9d79 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -574,14 +574,9 @@ impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { ) { arg_abi.store(self, val, dst) } - - fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> { - arg_abi.memory_ty(self) - } } pub trait ArgAbiExt<'gcc, 'tcx> { - fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn store( &self, bx: &mut Builder<'_, 'gcc, 'tcx>, @@ -597,12 +592,6 @@ pub trait ArgAbiExt<'gcc, 'tcx> { } impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { - /// Gets the LLVM type for a place of the original Rust type of - /// this argument/return, i.e., the result of `type_of::type_of`. - fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - self.layout.gcc_type(cx) - } - /// Stores a direct/indirect value described by this ArgAbi into a /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 8294e29d07d..c87e70864e5 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -172,7 +172,6 @@ impl LlvmType for CastTarget { } trait ArgAbiExt<'ll, 'tcx> { - fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn store( &self, bx: &mut Builder<'_, 'll, 'tcx>, @@ -188,12 +187,6 @@ trait ArgAbiExt<'ll, 'tcx> { } impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { - /// Gets the LLVM type for a place of the original Rust type of - /// this argument/return, i.e., the result of `type_of::type_of`. - fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { - self.layout.llvm_type(cx) - } - /// Stores a direct/indirect value described by this ArgAbi into a /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables @@ -302,9 +295,6 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { ) { arg_abi.store(self, val, dst) } - fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> &'ll Type { - arg_abi.memory_ty(self) - } } pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> { diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 32d9f27d32d..c3fc21a9285 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -158,7 +158,6 @@ pub trait ArgAbiBuilderMethods<'tcx>: BackendTypes { val: Self::Value, dst: PlaceRef<'tcx, Self::Value>, ); - fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type; } pub trait TypeCodegenMethods<'tcx> = DerivedTypeCodegenMethods<'tcx> -- cgit 1.4.1-3-g733a5 From 4794ea176be0d61f3ac08c367971c032e7abe7af Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 24 May 2025 16:35:20 +0200 Subject: atomic_load intrinsic: use const generic parameter for ordering --- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 3 +- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 93 ++++++++++++++-------- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 13 +-- compiler/rustc_middle/src/ty/consts/int.rs | 34 +++++++- compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics/mod.rs | 30 ++++++- library/core/src/sync/atomic.rs | 18 +++++ src/tools/miri/src/intrinsics/atomic.rs | 21 ++++- src/tools/miri/src/intrinsics/mod.rs | 2 +- .../fail/unaligned_pointers/atomic_unaligned.rs | 3 +- .../unaligned_pointers/atomic_unaligned.stderr | 4 +- tests/ui/intrinsics/intrinsic-atomics.rs | 6 +- tests/ui/intrinsics/non-integer-atomic.rs | 16 ++-- tests/ui/intrinsics/non-integer-atomic.stderr | 24 +++--- 15 files changed, 198 insertions(+), 74 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index b21ca32c9a2..0de23e55e81 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -870,11 +870,12 @@ fn codegen_regular_intrinsic_call<'tcx>( // FIXME use a compiler fence once Cranelift supports it fx.bcx.ins().fence(); } - _ if intrinsic.as_str().starts_with("atomic_load") => { + sym::atomic_load => { intrinsic_args!(fx, args => (ptr); intrinsic); let ptr = ptr.load_scalar(fx); let ty = generic_args.type_at(0); + let _ord = generic_args.const_at(1).to_value(); // FIXME: forward this to cranelift once they support that match ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { // FIXME implement 128bit atomics diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index a6d159c51e1..1047082df42 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -99,6 +99,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let llret_ty = bx.backend_type(bx.layout_of(ret_ty)); + let ret_llval = |bx: &mut Bx, llval| { + if result.layout.ty.is_bool() { + OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) + .val + .store(bx, result); + } else if !result.layout.ty.is_unit() { + bx.store_to_place(llval, result.val); + } + Ok(()) + }; + let llval = match name { sym::abort => { bx.abort(); @@ -337,6 +348,53 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { use crate::common::AtomicOrdering::*; use crate::common::{AtomicRmwBinOp, SynchronizationScope}; + let invalid_monomorphization = |ty| { + bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { + span, + name, + ty, + }); + }; + + let parse_const_generic_ordering = |ord: ty::Value<'tcx>| { + let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); + let ord = discr.to_atomic_ordering(); + // We have to translate from the intrinsic ordering to the backend ordering. + use rustc_middle::ty::AtomicOrdering; + match ord { + AtomicOrdering::Relaxed => Relaxed, + AtomicOrdering::Release => Release, + AtomicOrdering::Acquire => Acquire, + AtomicOrdering::AcqRel => AcquireRelease, + AtomicOrdering::SeqCst => SequentiallyConsistent, + } + }; + + // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first. + match name { + sym::atomic_load => { + let ty = fn_args.type_at(0); + let ordering = fn_args.const_at(1).to_value(); + if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { + invalid_monomorphization(ty); + return Ok(()); + } + let layout = bx.layout_of(ty); + let source = args[0].immediate(); + let llval = bx.atomic_load( + bx.backend_type(layout), + source, + parse_const_generic_ordering(ordering), + layout.size, + ); + + return ret_llval(bx, llval); + } + + // The rest falls back to below. + _ => {} + } + let Some((instruction, ordering)) = atomic.split_once('_') else { bx.sess().dcx().emit_fatal(errors::MissingMemoryOrdering); }; @@ -350,14 +408,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOrdering), }; - let invalid_monomorphization = |ty| { - bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { - span, - name, - ty, - }); - }; - match instruction { "cxchg" | "cxchgweak" => { let Some((success, failure)) = ordering.split_once('_') else { @@ -390,24 +440,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return Ok(()); } - "load" => { - let ty = fn_args.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { - let layout = bx.layout_of(ty); - let size = layout.size; - let source = args[0].immediate(); - bx.atomic_load( - bx.backend_type(layout), - source, - parse_ordering(bx, ordering), - size, - ) - } else { - invalid_monomorphization(ty); - return Ok(()); - } - } - "store" => { let ty = fn_args.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { @@ -538,14 +570,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; - if result.layout.ty.is_bool() { - OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) - .val - .store(bx, result); - } else if !result.layout.ty.is_unit() { - bx.store_to_place(llval, result.val); - } - Ok(()) + ret_llval(bx, llval) } } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 9fd158ad154..54bb3ac4113 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -204,24 +204,25 @@ pub(crate) fn check_intrinsic_type( // Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use // string ops to strip the suffixes, because the variants all get the same treatment here. - let (n_tps, inputs, output) = match split[1] { + let (n_tps, n_cts, inputs, output) = match split[1] { "cxchg" | "cxchgweak" => ( 1, + 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]), ), - "load" => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), - "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit), + "load" => (1, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), + "store" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit), "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" - | "umin" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)), - "fence" | "singlethreadfence" => (0, Vec::new(), tcx.types.unit), + | "umin" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)), + "fence" | "singlethreadfence" => (0, 0, Vec::new(), tcx.types.unit), op => { tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op }); return; } }; - (n_tps, 0, 0, inputs, output, hir::Safety::Unsafe) + (n_tps, 0, n_cts, inputs, output, hir::Safety::Unsafe) } else if intrinsic_name == sym::contract_check_ensures { // contract_check_ensures::(Ret, C) -> Ret // where C: for<'a> Fn(&'a Ret) -> bool, diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 9c9cd695339..0383814cc96 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -26,6 +26,19 @@ impl ConstInt { } } +/// An enum to represent the compiler-side view of `intrinsics::AtomicOrdering`. +/// This lives here because there's a method in this file that needs it and it is entirely unclear +/// where else to put this... +#[derive(Debug)] +pub enum AtomicOrdering { + // These values must match `intrinsics::AtomicOrdering`! + Relaxed = 0, + Release = 1, + Acquire = 2, + AcqRel = 3, + SeqCst = 4, +} + impl std::fmt::Debug for ConstInt { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { int, signed, is_ptr_sized_integral } = *self; @@ -318,6 +331,25 @@ impl ScalarInt { self.to_uint(tcx.data_layout.pointer_size).try_into().unwrap() } + #[inline] + pub fn to_atomic_ordering(self) -> AtomicOrdering { + use AtomicOrdering::*; + let val = self.to_u32(); + if val == Relaxed as u32 { + Relaxed + } else if val == Release as u32 { + Release + } else if val == Acquire as u32 { + Acquire + } else if val == AcqRel as u32 { + AcqRel + } else if val == SeqCst as u32 { + SeqCst + } else { + panic!("not a valid atomic ordering") + } + } + /// Converts the `ScalarInt` to `bool`. /// Panics if the `size` of the `ScalarInt` is not equal to 1 byte. /// Errors if it is not a valid `bool`. @@ -488,7 +520,7 @@ from_scalar_int_for_x_signed!(i8, i16, i32, i64, i128); impl From for ScalarInt { #[inline] fn from(c: std::cmp::Ordering) -> Self { - // Here we rely on `Ordering` having the same values in host and target! + // Here we rely on `cmp::Ordering` having the same values in host and target! ScalarInt::from(c as i8) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 78c0812b08f..af31f7ed33b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -74,8 +74,8 @@ pub use self::closure::{ place_to_string_for_capture, }; pub use self::consts::{ - AnonConstKind, Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, - ValTree, ValTreeKind, Value, + AnonConstKind, AtomicOrdering, Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, + UnevaluatedConst, ValTree, ValTreeKind, Value, }; pub use self::context::{ CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8f7e72f0ae1..cabd43ebbdc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -515,6 +515,7 @@ symbols! { async_iterator_poll_next, async_trait_bounds, atomic, + atomic_load, atomic_mod, atomics, att_syntax, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 32642a13b42..8a0f80f8ce7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -30,7 +30,7 @@ //! //! The atomic intrinsics provide common atomic operations on machine //! words, with multiple possible memory orderings. See the -//! [atomic types][crate::sync::atomic] docs for details. +//! [atomic types][atomic] docs for details. //! //! # Unwinding //! @@ -50,7 +50,7 @@ )] #![allow(missing_docs)] -use crate::marker::{DiscriminantKind, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, Tuple}; use crate::ptr; pub mod fallback; @@ -62,6 +62,20 @@ pub mod simd; #[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))] use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering}; +/// A type for atomic ordering parameters for intrinsics. This is a separate type from +/// `atomic::Ordering` so that we can make it `ConstParamTy` and fix the values used here without a +/// risk of leaking that to stable code. +#[derive(Debug, ConstParamTy, PartialEq, Eq)] +pub enum AtomicOrdering { + // These values must match the compiler's `AtomicOrdering` defined in + // `rustc_middle/src/ty/consts/int.rs`! + Relaxed = 0, + Release = 1, + Acquire = 2, + AcqRel = 3, + SeqCst = 4, +} + // N.B., these intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. @@ -391,6 +405,15 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); +/// Loads the current value of the pointer. +/// `T` must be an integer or pointer type. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `load` method. For example, [`AtomicBool::load`]. +#[rustc_intrinsic] +#[rustc_nounwind] +#[cfg(not(bootstrap))] +pub unsafe fn atomic_load(src: *const T) -> T; /// Loads the current value of the pointer. /// `T` must be an integer or pointer type. /// @@ -399,6 +422,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_seqcst(src: *const T) -> T; /// Loads the current value of the pointer. /// `T` must be an integer or pointer type. @@ -408,6 +432,7 @@ pub unsafe fn atomic_load_seqcst(src: *const T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_acquire(src: *const T) -> T; /// Loads the current value of the pointer. /// `T` must be an integer or pointer type. @@ -417,6 +442,7 @@ pub unsafe fn atomic_load_acquire(src: *const T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_relaxed(src: *const T) -> T; /// Stores the value at the specified memory location. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index bd5a58d74ba..a3fbc71162b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3822,6 +3822,7 @@ unsafe fn atomic_store(dst: *mut T, val: T, order: Ordering) { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[cfg(bootstrap)] unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_load`. unsafe { @@ -3835,6 +3836,23 @@ unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { } } +#[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[cfg(not(bootstrap))] +unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { + use intrinsics::AtomicOrdering; + // SAFETY: the caller must uphold the safety contract for `atomic_load`. + unsafe { + match order { + Relaxed => intrinsics::atomic_load::(dst), + Acquire => intrinsics::atomic_load::(dst), + SeqCst => intrinsics::atomic_load::(dst), + Release => panic!("there is no such thing as a release load"), + AcqRel => panic!("there is no such thing as an acquire-release load"), + } + } +} + #[inline] #[cfg(target_has_atomic)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index 2eb8086f578..a61226eeed9 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -1,4 +1,5 @@ use rustc_middle::mir::BinOp; +use rustc_middle::ty::AtomicOrdering; use rustc_middle::{mir, ty}; use self::helpers::check_intrinsic_arg_count; @@ -19,6 +20,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_atomic_intrinsic( &mut self, intrinsic_name: &str, + generic_args: ty::GenericArgsRef<'tcx>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -35,6 +37,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } + fn read_ord_const_generic(o: AtomicOrdering) -> AtomicReadOrd { + match o { + AtomicOrdering::SeqCst => AtomicReadOrd::SeqCst, + AtomicOrdering::Acquire => AtomicReadOrd::Acquire, + AtomicOrdering::Relaxed => AtomicReadOrd::Relaxed, + _ => panic!("invalid read ordering `{o:?}`"), + } + } + fn write_ord(ord: &str) -> AtomicWriteOrd { match ord { "seqcst" => AtomicWriteOrd::SeqCst, @@ -66,7 +77,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } match &*intrinsic_structure { - ["load", ord] => this.atomic_load(args, dest, read_ord(ord))?, + // New-style intrinsics that use const generics + ["load"] => { + let ordering = generic_args.const_at(1).to_value(); + let ordering = + ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering(); + this.atomic_load(args, dest, read_ord_const_generic(ordering))?; + } + + // Old-style intrinsics that have the ordering in the intrinsic name ["store", ord] => this.atomic_store(args, write_ord(ord))?, ["fence", ord] => this.atomic_fence_intrinsic(args, fence_ord(ord))?, diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 69baa472cd6..581005bc9a1 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -97,7 +97,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); if let Some(name) = intrinsic_name.strip_prefix("atomic_") { - return this.emulate_atomic_intrinsic(name, args, dest); + return this.emulate_atomic_intrinsic(name, generic_args, args, dest); } if let Some(name) = intrinsic_name.strip_prefix("simd_") { return this.emulate_simd_intrinsic(name, generic_args, args, dest); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs index 29976836b0b..37c64c81944 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs @@ -1,5 +1,6 @@ //@compile-flags: -Zmiri-symbolic-alignment-check -Cdebug-assertions=no #![feature(core_intrinsics)] +use std::intrinsics; fn main() { // Do a 4-aligned u64 atomic access. That should be UB on all platforms, @@ -7,7 +8,7 @@ fn main() { let z = [0u32; 2]; let zptr = &z as *const _ as *const u64; unsafe { - ::std::intrinsics::atomic_load_seqcst(zptr); + intrinsics::atomic_load::<_, { intrinsics::AtomicOrdering::SeqCst }>(zptr); //~^ERROR: accessing memory with alignment 4, but alignment 8 is required } } diff --git a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr index a9da740be1d..e0f9d011ce4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required --> tests/fail/unaligned_pointers/atomic_unaligned.rs:LL:CC | -LL | ::std::intrinsics::atomic_load_seqcst(zptr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +LL | intrinsics::atomic_load::<_, { intrinsics::AtomicOrdering::SeqCst }>(zptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs index 9127cc649e6..f96c6dc832e 100644 --- a/tests/ui/intrinsics/intrinsic-atomics.rs +++ b/tests/ui/intrinsics/intrinsic-atomics.rs @@ -1,14 +1,14 @@ //@ run-pass #![feature(core_intrinsics)] -use std::intrinsics as rusti; +use std::intrinsics::{self as rusti, AtomicOrdering}; pub fn main() { unsafe { let mut x: Box<_> = Box::new(1); - assert_eq!(rusti::atomic_load_seqcst(&*x), 1); + assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::SeqCst }>(&*x), 1); *x = 5; - assert_eq!(rusti::atomic_load_acquire(&*x), 5); + assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::Acquire }>(&*x), 5); rusti::atomic_store_seqcst(&mut *x, 3); assert_eq!(*x, 3); diff --git a/tests/ui/intrinsics/non-integer-atomic.rs b/tests/ui/intrinsics/non-integer-atomic.rs index 2d1d0882084..dd129e55945 100644 --- a/tests/ui/intrinsics/non-integer-atomic.rs +++ b/tests/ui/intrinsics/non-integer-atomic.rs @@ -4,7 +4,7 @@ #![allow(warnings)] #![crate_type = "rlib"] -use std::intrinsics; +use std::intrinsics::{self, AtomicOrdering}; #[derive(Copy, Clone)] pub struct Foo(i64); @@ -12,8 +12,8 @@ pub type Bar = &'static Fn(); pub type Quux = [u8; 100]; pub unsafe fn test_bool_load(p: &mut bool, v: bool) { - intrinsics::atomic_load_seqcst(p); - //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool` + intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `bool` } pub unsafe fn test_bool_store(p: &mut bool, v: bool) { @@ -32,8 +32,8 @@ pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) { } pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) { - intrinsics::atomic_load_seqcst(p); - //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo` + intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `Foo` } pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) { @@ -52,7 +52,7 @@ pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) { } pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) { - intrinsics::atomic_load_seqcst(p); + intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); //~^ ERROR expected basic integer type, found `&dyn Fn()` } @@ -72,8 +72,8 @@ pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) { } pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) { - intrinsics::atomic_load_seqcst(p); - //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]` } pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) { diff --git a/tests/ui/intrinsics/non-integer-atomic.stderr b/tests/ui/intrinsics/non-integer-atomic.stderr index 32791a8e8b7..58c2dc00c66 100644 --- a/tests/ui/intrinsics/non-integer-atomic.stderr +++ b/tests/ui/intrinsics/non-integer-atomic.stderr @@ -1,8 +1,8 @@ -error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool` +error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:15:5 | -LL | intrinsics::atomic_load_seqcst(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:20:5 @@ -22,11 +22,11 @@ error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo` +error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:35:5 | -LL | intrinsics::atomic_load_seqcst(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:40:5 @@ -46,11 +46,11 @@ error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` +error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:55:5 | -LL | intrinsics::atomic_load_seqcst(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:60:5 @@ -70,11 +70,11 @@ error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:75:5 | -LL | intrinsics::atomic_load_seqcst(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:80:5 -- cgit 1.4.1-3-g733a5 From a387c86a929c27c102833c55bebad11cfc1c155d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 May 2025 12:15:04 +0200 Subject: get rid of rustc_codegen_ssa::common::AtomicOrdering --- compiler/rustc_codegen_gcc/src/builder.rs | 10 +++++----- compiler/rustc_codegen_llvm/src/builder.rs | 12 ++++++------ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 8 ++++---- compiler/rustc_codegen_ssa/src/common.rs | 9 --------- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 18 +++++------------- compiler/rustc_codegen_ssa/src/traits/builder.rs | 6 ++---- compiler/rustc_middle/src/ty/consts/int.rs | 2 +- 7 files changed, 23 insertions(+), 42 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 4e2163201fd..d1fb8d8f9d6 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -12,7 +12,7 @@ use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout, WrappingRange}; use rustc_apfloat::{Float, Round, Status, ieee}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::{ - AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, + AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, }; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -26,7 +26,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{self, AtomicOrdering, Instance, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::def_id::DefId; use rustc_target::callconv::FnAbi; @@ -75,7 +75,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let load_ordering = match order { // TODO(antoyo): does this make sense? - AtomicOrdering::AcquireRelease | AtomicOrdering::Release => AtomicOrdering::Acquire, + AtomicOrdering::AcqRel | AtomicOrdering::Release => AtomicOrdering::Acquire, _ => order, }; let previous_value = @@ -2474,8 +2474,8 @@ impl ToGccOrdering for AtomicOrdering { AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, AtomicOrdering::Release => __ATOMIC_RELEASE, - AtomicOrdering::AcquireRelease => __ATOMIC_ACQ_REL, - AtomicOrdering::SequentiallyConsistent => __ATOMIC_SEQ_CST, + AtomicOrdering::AcqRel => __ATOMIC_ACQ_REL, + AtomicOrdering::SeqCst => __ATOMIC_SEQ_CST, }; ordering as i32 } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 5238755c8eb..fcb55a04635 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -612,7 +612,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { &mut self, ty: &'ll Type, ptr: &'ll Value, - order: rustc_codegen_ssa::common::AtomicOrdering, + order: rustc_middle::ty::AtomicOrdering, size: Size, ) -> &'ll Value { unsafe { @@ -851,7 +851,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { &mut self, val: &'ll Value, ptr: &'ll Value, - order: rustc_codegen_ssa::common::AtomicOrdering, + order: rustc_middle::ty::AtomicOrdering, size: Size, ) { debug!("Store {:?} -> {:?}", val, ptr); @@ -1307,8 +1307,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { dst: &'ll Value, cmp: &'ll Value, src: &'ll Value, - order: rustc_codegen_ssa::common::AtomicOrdering, - failure_order: rustc_codegen_ssa::common::AtomicOrdering, + order: rustc_middle::ty::AtomicOrdering, + failure_order: rustc_middle::ty::AtomicOrdering, weak: bool, ) -> (&'ll Value, &'ll Value) { let weak = if weak { llvm::True } else { llvm::False }; @@ -1334,7 +1334,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { op: rustc_codegen_ssa::common::AtomicRmwBinOp, dst: &'ll Value, mut src: &'ll Value, - order: rustc_codegen_ssa::common::AtomicOrdering, + order: rustc_middle::ty::AtomicOrdering, ) -> &'ll Value { // The only RMW operation that LLVM supports on pointers is compare-exchange. let requires_cast_to_int = self.val_ty(src) == self.type_ptr() @@ -1360,7 +1360,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn atomic_fence( &mut self, - order: rustc_codegen_ssa::common::AtomicOrdering, + order: rustc_middle::ty::AtomicOrdering, scope: SynchronizationScope, ) { let single_threaded = match scope { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 67a66e6ec79..e27fbf94f34 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -426,14 +426,14 @@ pub(crate) enum AtomicOrdering { } impl AtomicOrdering { - pub(crate) fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self { - use rustc_codegen_ssa::common::AtomicOrdering as Common; + pub(crate) fn from_generic(ao: rustc_middle::ty::AtomicOrdering) -> Self { + use rustc_middle::ty::AtomicOrdering as Common; match ao { Common::Relaxed => Self::Monotonic, Common::Acquire => Self::Acquire, Common::Release => Self::Release, - Common::AcquireRelease => Self::AcquireRelease, - Common::SequentiallyConsistent => Self::SequentiallyConsistent, + Common::AcqRel => Self::AcquireRelease, + Common::SeqCst => Self::SequentiallyConsistent, } } } diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 6d0c9d8d066..ef0d565333e 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -59,15 +59,6 @@ pub enum AtomicRmwBinOp { AtomicUMin, } -#[derive(Copy, Clone, Debug)] -pub enum AtomicOrdering { - Relaxed, - Acquire, - Release, - AcquireRelease, - SequentiallyConsistent, -} - #[derive(Copy, Clone, Debug)] pub enum SynchronizationScope { SingleThread, diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 1047082df42..a79d67bb6cd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -345,7 +345,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // This requires that atomic intrinsics follow a specific naming pattern: // "atomic_[_]" name if let Some(atomic) = name_str.strip_prefix("atomic_") => { - use crate::common::AtomicOrdering::*; + use rustc_middle::ty::AtomicOrdering::*; + use crate::common::{AtomicRmwBinOp, SynchronizationScope}; let invalid_monomorphization = |ty| { @@ -358,16 +359,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let parse_const_generic_ordering = |ord: ty::Value<'tcx>| { let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); - let ord = discr.to_atomic_ordering(); - // We have to translate from the intrinsic ordering to the backend ordering. - use rustc_middle::ty::AtomicOrdering; - match ord { - AtomicOrdering::Relaxed => Relaxed, - AtomicOrdering::Release => Release, - AtomicOrdering::Acquire => Acquire, - AtomicOrdering::AcqRel => AcquireRelease, - AtomicOrdering::SeqCst => SequentiallyConsistent, - } + discr.to_atomic_ordering() }; // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first. @@ -403,8 +395,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "relaxed" => Relaxed, "acquire" => Acquire, "release" => Release, - "acqrel" => AcquireRelease, - "seqcst" => SequentiallyConsistent, + "acqrel" => AcqRel, + "seqcst" => SeqCst, _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOrdering), }; diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f66309cf340..e35716d3afb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -4,7 +4,7 @@ use std::ops::Deref; use rustc_abi::{Align, Scalar, Size, WrappingRange}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; -use rustc_middle::ty::{Instance, Ty}; +use rustc_middle::ty::{AtomicOrdering, Instance, Ty}; use rustc_session::config::OptLevel; use rustc_span::Span; use rustc_target::callconv::FnAbi; @@ -19,9 +19,7 @@ use super::misc::MiscCodegenMethods; use super::type_::{ArgAbiBuilderMethods, BaseTypeCodegenMethods, LayoutTypeCodegenMethods}; use super::{CodegenMethods, StaticBuilderMethods}; use crate::MemFlags; -use crate::common::{ - AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, -}; +use crate::common::{AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind}; use crate::mir::operand::{OperandRef, OperandValue}; use crate::mir::place::{PlaceRef, PlaceValue}; diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 0383814cc96..b087ae25486 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -29,7 +29,7 @@ impl ConstInt { /// An enum to represent the compiler-side view of `intrinsics::AtomicOrdering`. /// This lives here because there's a method in this file that needs it and it is entirely unclear /// where else to put this... -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum AtomicOrdering { // These values must match `intrinsics::AtomicOrdering`! Relaxed = 0, -- cgit 1.4.1-3-g733a5 From f1778074fb8089f5c1bdf611b702248df8d400e1 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Thu, 29 May 2025 23:15:44 +0200 Subject: Remove RUSTC_RETRY_LINKER_ON_SEGFAULT hack It looks like this was added 6 years ago because of issues with the MacOS linker. MacOS got a new linker in the meantime, so that should probably be resolved now. Hopefully. --- compiler/rustc_codegen_ssa/src/back/link.rs | 54 ++--------------------------- src/ci/github-actions/jobs.yml | 5 --- 2 files changed, 2 insertions(+), 57 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b802284eb32..58fa3c392ca 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -6,7 +6,7 @@ use std::fs::{File, OpenOptions, read}; use std::io::{BufWriter, Write}; use std::ops::{ControlFlow, Deref}; use std::path::{Path, PathBuf}; -use std::process::{ExitStatus, Output, Stdio}; +use std::process::{Output, Stdio}; use std::{env, fmt, fs, io, mem, str}; use cc::windows_registry; @@ -736,13 +736,10 @@ fn link_natively( // Invoke the system linker info!("{cmd:?}"); - let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok(); let unknown_arg_regex = Regex::new(r"(unknown|unrecognized) (command line )?(option|argument)").unwrap(); let mut prog; - let mut i = 0; loop { - i += 1; prog = sess.time("run_linker", || exec_linker(sess, &cmd, out_filename, flavor, tmpdir)); let Ok(ref output) = prog else { break; @@ -858,54 +855,7 @@ fn link_natively( continue; } - // Here's a terribly awful hack that really shouldn't be present in any - // compiler. Here an environment variable is supported to automatically - // retry the linker invocation if the linker looks like it segfaulted. - // - // Gee that seems odd, normally segfaults are things we want to know - // about! Unfortunately though in rust-lang/rust#38878 we're - // experiencing the linker segfaulting on Travis quite a bit which is - // causing quite a bit of pain to land PRs when they spuriously fail - // due to a segfault. - // - // The issue #38878 has some more debugging information on it as well, - // but this unfortunately looks like it's just a race condition in - // macOS's linker with some thread pool working in the background. It - // seems that no one currently knows a fix for this so in the meantime - // we're left with this... - if !retry_on_segfault || i > 3 { - break; - } - let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11"; - let msg_bus = "clang: error: unable to execute command: Bus error: 10"; - if out.contains(msg_segv) || out.contains(msg_bus) { - warn!( - ?cmd, %out, - "looks like the linker segfaulted when we tried to call it, \ - automatically retrying again", - ); - continue; - } - - if is_illegal_instruction(&output.status) { - warn!( - ?cmd, %out, status = %output.status, - "looks like the linker hit an illegal instruction when we \ - tried to call it, automatically retrying again.", - ); - continue; - } - - #[cfg(unix)] - fn is_illegal_instruction(status: &ExitStatus) -> bool { - use std::os::unix::prelude::*; - status.signal() == Some(libc::SIGILL) - } - - #[cfg(not(unix))] - fn is_illegal_instruction(_status: &ExitStatus) -> bool { - false - } + break; } match prog { diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index f32f9cd45a8..56f46b191ad 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -72,7 +72,6 @@ envs: env-x86_64-apple-tests: &env-x86_64-apple-tests SCRIPT: ./x.py check compiletest --set build.compiletest-use-stage0-libtest=true && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # Ensure that host tooling is tested on our minimum supported macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 @@ -402,7 +401,6 @@ auto: env: SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1 - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # Ensure that host tooling is built to support our minimum support macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 @@ -420,7 +418,6 @@ auto: # Mac Catalyst cannot currently compile the sanitizer: # https://github.com/rust-lang/rust/issues/129069 RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # Ensure that host tooling is built to support our minimum support macOS version. # FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?) MACOSX_DEPLOYMENT_TARGET: 10.12 @@ -453,7 +450,6 @@ auto: --set llvm.ninja=false --set rust.lto=thin --set rust.codegen-units=1 - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else @@ -474,7 +470,6 @@ auto: --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else -- cgit 1.4.1-3-g733a5 From 1f717ae7789546be2291a11b9c79e7fa9d7d609f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 09:25:27 +0000 Subject: Use layout field of OperandRef and PlaceRef in codegen_intrinsic_call This avoids having to get the function signature. --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 21 ++++++------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 40 +++++++++++-------------- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 31 ++++++++----------- 3 files changed, 41 insertions(+), 51 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index ff1ae2d9d79..1c06bd73095 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -212,15 +212,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc _ => bug!("expected fn item type, found {}", callee_ty), }; - let sig = callee_ty.fn_sig(tcx); - let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig); - let arg_tys = sig.inputs(); - let ret_ty = sig.output(); let name = tcx.item_name(def_id); let name_str = name.as_str(); - let llret_ty = self.layout_of(ret_ty).gcc_type(self); - let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); @@ -320,8 +314,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::rotate_right | sym::saturating_add | sym::saturating_sub => { - let ty = arg_tys[0]; - match int_type_width_signed(ty, self) { + match int_type_width_signed(args[0].layout.ty, self) { Some((width, signed)) => match name { sym::ctlz | sym::cttz => { let func = self.current_func.borrow().expect("func"); @@ -400,7 +393,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, - ty, + ty: args[0].layout.ty, }); return Ok(()); } @@ -492,7 +485,15 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } _ if name_str.starts_with("simd_") => { - match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { + match generic_simd_intrinsic( + self, + name, + callee_ty, + args, + result.layout.ty, + result.layout.gcc_type(self), + span, + ) { Ok(value) => value, Err(()) => return Ok(()), } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e8629aeebb9..c4bbe86f122 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -175,14 +175,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { bug!("expected fn item type, found {}", callee_ty); }; - let sig = callee_ty.fn_sig(tcx); - let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig); - let arg_tys = sig.inputs(); - let ret_ty = sig.output(); let name = tcx.item_name(def_id); - let llret_ty = self.layout_of(ret_ty).llvm_type(self); - let simple = get_simple_intrinsic(self, name); let llval = match name { _ if simple.is_some() => { @@ -265,22 +259,22 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { BackendRepr::Scalar(scalar) => { match scalar.primitive() { Primitive::Int(..) => { - if self.cx().size_of(ret_ty).bytes() < 4 { + if self.cx().size_of(result.layout.ty).bytes() < 4 { // `va_arg` should not be called on an integer type // less than 4 bytes in length. If it is, promote // the integer to an `i32` and truncate the result // back to the smaller type. let promoted_result = emit_va_arg(self, args[0], tcx.types.i32); - self.trunc(promoted_result, llret_ty) + self.trunc(promoted_result, result.layout.llvm_type(self)) } else { - emit_va_arg(self, args[0], ret_ty) + emit_va_arg(self, args[0], result.layout.ty) } } Primitive::Float(Float::F16) => { bug!("the va_arg intrinsic does not work with `f16`") } Primitive::Float(Float::F64) | Primitive::Pointer(_) => { - emit_va_arg(self, args[0], ret_ty) + emit_va_arg(self, args[0], result.layout.ty) } // `va_arg` should never be used with the return type f32. Primitive::Float(Float::F32) => { @@ -384,7 +378,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { | sym::rotate_right | sym::saturating_add | sym::saturating_sub => { - let ty = arg_tys[0]; + let ty = args[0].layout.ty; if !ty.is_integral() { tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, @@ -403,26 +397,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { &[args[0].immediate(), y], ); - self.intcast(ret, llret_ty, false) + self.intcast(ret, result.layout.llvm_type(self), false) } sym::ctlz_nonzero => { let y = self.const_bool(true); let llvm_name = &format!("llvm.ctlz.i{width}"); let ret = self.call_intrinsic(llvm_name, &[args[0].immediate(), y]); - self.intcast(ret, llret_ty, false) + self.intcast(ret, result.layout.llvm_type(self), false) } sym::cttz_nonzero => { let y = self.const_bool(true); let llvm_name = &format!("llvm.cttz.i{width}"); let ret = self.call_intrinsic(llvm_name, &[args[0].immediate(), y]); - self.intcast(ret, llret_ty, false) + self.intcast(ret, result.layout.llvm_type(self), false) } sym::ctpop => { let ret = self.call_intrinsic( &format!("llvm.ctpop.i{width}"), &[args[0].immediate()], ); - self.intcast(ret, llret_ty, false) + self.intcast(ret, result.layout.llvm_type(self), false) } sym::bswap => { if width == 8 { @@ -554,16 +548,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { // Unpack non-power-of-2 #[repr(packed, simd)] arguments. // This gives them the expected layout of a regular #[repr(simd)] vector. let mut loaded_args = Vec::new(); - for (ty, arg) in arg_tys.iter().zip(args) { + for arg in args { loaded_args.push( // #[repr(packed, simd)] vectors are passed like arrays (as references, // with reduced alignment and no padding) rather than as immediates. // We can use a vector load to fix the layout and turn the argument // into an immediate. - if ty.is_simd() + if arg.layout.ty.is_simd() && let OperandValue::Ref(place) = arg.val { - let (size, elem_ty) = ty.simd_size_and_type(self.tcx()); + let (size, elem_ty) = arg.layout.ty.simd_size_and_type(self.tcx()); let elem_ll_ty = match elem_ty.kind() { ty::Float(f) => self.type_float_from_ty(*f), ty::Int(i) => self.type_int_from_ty(*i), @@ -580,10 +574,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { ); } - let llret_ty = if ret_ty.is_simd() - && let BackendRepr::Memory { .. } = self.layout_of(ret_ty).layout.backend_repr + let llret_ty = if result.layout.ty.is_simd() + && let BackendRepr::Memory { .. } = result.layout.backend_repr { - let (size, elem_ty) = ret_ty.simd_size_and_type(self.tcx()); + let (size, elem_ty) = result.layout.ty.simd_size_and_type(self.tcx()); let elem_ll_ty = match elem_ty.kind() { ty::Float(f) => self.type_float_from_ty(*f), ty::Int(i) => self.type_int_from_ty(*i), @@ -593,7 +587,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { }; self.type_vector(elem_ll_ty, size) } else { - llret_ty + result.layout.llvm_type(self) }; match generic_simd_intrinsic( @@ -602,7 +596,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { callee_ty, fn_args, &loaded_args, - ret_ty, + result.layout.ty, llret_ty, span, ) { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index a79d67bb6cd..b6cebdfee24 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -66,10 +66,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { span_bug!(span, "expected fn item type, found {}", callee_ty); }; - let sig = callee_ty.fn_sig(bx.tcx()); - let sig = bx.tcx().normalize_erasing_late_bound_regions(bx.typing_env(), sig); - let arg_tys = sig.inputs(); - let ret_ty = sig.output(); let name = bx.tcx().item_name(def_id); let name_str = name.as_str(); @@ -97,8 +93,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - let llret_ty = bx.backend_type(bx.layout_of(ret_ty)); - let ret_llval = |bx: &mut Bx, llval| { if result.layout.ty.is_bool() { OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) @@ -164,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | sym::type_name | sym::variant_count => { let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap(); - OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx) + OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx) } sym::arith_offset => { let ty = fn_args.type_at(0); @@ -248,7 +242,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.or_disjoint(a, b) } sym::exact_div => { - let ty = arg_tys[0]; + let ty = args[0].layout.ty; match int_type_width_signed(ty, bx.tcx()) { Some((_width, signed)) => { if signed { @@ -268,7 +262,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => { - match float_type_width(arg_tys[0]) { + match float_type_width(args[0].layout.ty) { Some(_width) => match name { sym::fadd_fast => bx.fadd_fast(args[0].immediate(), args[1].immediate()), sym::fsub_fast => bx.fsub_fast(args[0].immediate(), args[1].immediate()), @@ -281,7 +275,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, - ty: arg_tys[0], + ty: args[0].layout.ty, }); return Ok(()); } @@ -291,7 +285,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | sym::fsub_algebraic | sym::fmul_algebraic | sym::fdiv_algebraic - | sym::frem_algebraic => match float_type_width(arg_tys[0]) { + | sym::frem_algebraic => match float_type_width(args[0].layout.ty) { Some(_width) => match name { sym::fadd_algebraic => { bx.fadd_algebraic(args[0].immediate(), args[1].immediate()) @@ -314,31 +308,32 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, - ty: arg_tys[0], + ty: args[0].layout.ty, }); return Ok(()); } }, sym::float_to_int_unchecked => { - if float_type_width(arg_tys[0]).is_none() { + if float_type_width(args[0].layout.ty).is_none() { bx.tcx().dcx().emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, - ty: arg_tys[0], + ty: args[0].layout.ty, }); return Ok(()); } - let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else { + let Some((_width, signed)) = int_type_width_signed(result.layout.ty, bx.tcx()) + else { bx.tcx().dcx().emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, - ty: ret_ty, + ty: result.layout.ty, }); return Ok(()); }; if signed { - bx.fptosi(args[0].immediate(), llret_ty) + bx.fptosi(args[0].immediate(), bx.backend_type(result.layout)) } else { - bx.fptoui(args[0].immediate(), llret_ty) + bx.fptoui(args[0].immediate(), bx.backend_type(result.layout)) } } -- cgit 1.4.1-3-g733a5 From 0fcea3db28ad738ae2fe8c0cf871450d8492e5b0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 09:39:43 +0000 Subject: Avoid computing function type for intrinsic instances --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 11 +++-------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 8 ++------ compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 16 ++++++++-------- 3 files changed, 13 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f6afb15aafe..2b1dca72d06 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -23,7 +23,7 @@ use rustc_codegen_ssa::traits::{ use rustc_middle::bug; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; use rustc_target::callconv::{ArgAbi, PassMode}; @@ -205,15 +205,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc span: Span, ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; - let callee_ty = instance.ty(tcx, self.typing_env()); - let (def_id, fn_args) = match *callee_ty.kind() { - ty::FnDef(def_id, fn_args) => (def_id, fn_args), - _ => bug!("expected fn item type, found {}", callee_ty), - }; - - let name = tcx.item_name(def_id); + let name = tcx.item_name(instance.def_id()); let name_str = name.as_str(); + let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); let simple_func = get_simple_function(self, name); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 2e31f6b3649..30a924ef158 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -169,13 +169,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { span: Span, ) -> Result<(), ty::Instance<'tcx>> { let tcx = self.tcx; - let callee_ty = instance.ty(tcx, self.typing_env()); - let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else { - bug!("expected fn item type, found {}", callee_ty); - }; - - let name = tcx.item_name(def_id); + let name = tcx.item_name(instance.def_id()); + let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); let llval = match name { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index b6cebdfee24..1102bfc193e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,7 +1,7 @@ use rustc_abi::WrappingRange; +use rustc_middle::bug; use rustc_middle::mir::SourceInfo; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::sym; @@ -60,14 +60,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { source_info: SourceInfo, ) -> Result<(), ty::Instance<'tcx>> { let span = source_info.span; - let callee_ty = instance.ty(bx.tcx(), bx.typing_env()); - let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else { - span_bug!(span, "expected fn item type, found {}", callee_ty); - }; - - let name = bx.tcx().item_name(def_id); + let name = bx.tcx().item_name(instance.def_id()); let name_str = name.as_str(); + let fn_args = instance.args; // If we're swapping something that's *not* an `OperandValue::Ref`, // then we can do it directly and avoid the alloca. @@ -137,7 +133,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN, _ => bug!(), }; - let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable, callee_ty); + let value = meth::VirtualIndex::from_index(idx).get_usize( + bx, + vtable, + instance.ty(bx.tcx(), bx.typing_env()), + ); match name { // Size is always <= isize::MAX. sym::vtable_size => { -- cgit 1.4.1-3-g733a5 From 284bec542816487b93126118f6f0d6616499ea4f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 30 May 2025 10:04:35 +0000 Subject: Directly use from_immediate for handling bool --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 9 +++------ compiler/rustc_codegen_llvm/src/intrinsic.rs | 5 ++--- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 5 ++--- 3 files changed, 7 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 2b1dca72d06..73be25ba92b 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -498,13 +498,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc }; if result.layout.ty.is_bool() { - OperandRef::from_immediate_or_packed_pair(self, value, result.layout) - .val - .store(self, result); + let val = self.from_immediate(value); + self.store_to_place(val, result.val); } else if !result.layout.ty.is_unit() { - let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self)); - let ptr = self.pointercast(result.val.llval, ptr_llty); - self.store(value, ptr, result.val.align); + self.store_to_place(value, result.val); } Ok(()) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 30a924ef158..989752eb78e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -610,9 +610,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { }; if result.layout.ty.is_bool() { - OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) - .val - .store(self, result); + let val = self.from_immediate(llval); + self.store_to_place(val, result.val); } else if !result.layout.ty.is_unit() { self.store_to_place(llval, result.val); } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 1102bfc193e..8c6f52084c2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -91,9 +91,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ret_llval = |bx: &mut Bx, llval| { if result.layout.ty.is_bool() { - OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) - .val - .store(bx, result); + let val = bx.from_immediate(llval); + bx.store_to_place(val, result.val); } else if !result.layout.ty.is_unit() { bx.store_to_place(llval, result.val); } -- cgit 1.4.1-3-g733a5 From ba5a7444c3569b3fbb66e327ea0b6019995c87fb Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Thu, 29 May 2025 23:55:12 +0200 Subject: Warn when gold was used as the linker gold has been deprecated recently and is known to behave incorrectly around Rust programs, including miscompiling `#[used(linker)]`. Tell people to switch to a different linker instead. Co-Authored-By: bjorn3 <17426603+bjorn3@users.noreply.github.com> --- compiler/rustc_codegen_ssa/src/back/link.rs | 59 ++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b802284eb32..d0c4af0d45e 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3,7 +3,7 @@ mod raw_dylib; use std::collections::BTreeSet; use std::ffi::OsString; use std::fs::{File, OpenOptions, read}; -use std::io::{BufWriter, Write}; +use std::io::{BufReader, BufWriter, Write}; use std::ops::{ControlFlow, Deref}; use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; @@ -184,6 +184,12 @@ pub fn link_binary( ); } + if sess.target.binary_format == BinaryFormat::Elf { + if let Err(err) = warn_if_linked_with_gold(sess, &out_filename) { + info!(?err, "Error while checking if gold was the linker"); + } + } + if output.is_stdout() { if output.is_tty() { sess.dcx().emit_err(errors::BinaryOutputToTty { @@ -3425,3 +3431,54 @@ fn add_lld_args( } } } + +// gold has been deprecated with binutils 2.44 +// and is known to behave incorrectly around Rust programs. +// There have been reports of being unable to bootstrap with gold: +// https://github.com/rust-lang/rust/issues/139425 +// Additionally, gold miscompiles SHF_GNU_RETAIN sections, which are +// emitted with `#[used(linker)]`. +fn warn_if_linked_with_gold(sess: &Session, path: &Path) -> Result<(), Box> { + use object::read::elf::{FileHeader, SectionHeader}; + use object::read::{ReadCache, ReadRef, Result}; + use object::{Endianness, elf}; + + fn elf_has_gold_version_note<'a>( + elf: &impl FileHeader, + data: impl ReadRef<'a>, + ) -> Result { + let endian = elf.endian()?; + + let section = + elf.sections(endian, data)?.section_by_name(endian, b".note.gnu.gold-version"); + if let Some((_, section)) = section { + if let Some(mut notes) = section.notes(endian, data)? { + return Ok(notes.any(|note| { + note.is_ok_and(|note| note.n_type(endian) == elf::NT_GNU_GOLD_VERSION) + })); + } + } + + Ok(false) + } + + let data = ReadCache::new(BufReader::new(File::open(path)?)); + + let was_linked_with_gold = if sess.target.pointer_width == 64 { + let elf = elf::FileHeader64::::parse(&data)?; + elf_has_gold_version_note(elf, &data)? + } else if sess.target.pointer_width == 32 { + let elf = elf::FileHeader32::::parse(&data)?; + elf_has_gold_version_note(elf, &data)? + } else { + return Ok(()); + }; + + if was_linked_with_gold { + let mut warn = + sess.dcx().struct_warn("the gold linker is deprecated and has known bugs with Rust"); + warn.help("consider using LLD or ld from GNU binutils instead"); + warn.emit(); + } + Ok(()) +} -- cgit 1.4.1-3-g733a5 From 00a88b903d3728517dff8f0044160d18a0322ab4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:00:11 +0000 Subject: Remove get_dbg_loc from DebugInfoBuilderMethods It is only used within cg_llvm. --- compiler/rustc_codegen_gcc/src/debuginfo.rs | 4 ---- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 10 ++++++---- compiler/rustc_codegen_ssa/src/traits/debuginfo.rs | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index e0597d0030d..3a265fbc64f 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -52,10 +52,6 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { fn clear_dbg_loc(&mut self) { self.location = None; } - - fn get_dbg_loc(&self) -> Option { - self.location - } } /// Generate the `debug_context` in an MIR Body. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index c5085927923..5ca2505cec4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -147,6 +147,12 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { } } +impl<'ll> Builder<'_, 'll, '_> { + pub(crate) fn get_dbg_loc(&self) -> Option<&'ll DILocation> { + unsafe { llvm::LLVMGetCurrentDebugLocation2(self.llbuilder) } + } +} + impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). @@ -209,10 +215,6 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { } } - fn get_dbg_loc(&self) -> Option<&'ll DILocation> { - unsafe { llvm::LLVMGetCurrentDebugLocation2(self.llbuilder) } - } - fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { gdb::insert_reference_to_gdb_debug_scripts_section_global(self) } diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index 30d77c206a5..b9d4950e0ad 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -81,7 +81,6 @@ pub trait DebugInfoBuilderMethods: BackendTypes { ); fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation); fn clear_dbg_loc(&mut self); - fn get_dbg_loc(&self) -> Option; fn insert_reference_to_gdb_debug_scripts_section_global(&mut self); fn set_var_name(&mut self, value: Self::Value, name: &str); } -- cgit 1.4.1-3-g733a5 From 2e8401ae5f293070f57b964252db7b38d3f2fc2a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:00:56 +0000 Subject: Remove type_test from IntrinsicCallBuilderMethods It is only used within cg_llvm. --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 5 ----- compiler/rustc_codegen_llvm/src/builder.rs | 7 +++++-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 7 ------- compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 2 -- 4 files changed, 5 insertions(+), 16 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 73be25ba92b..9e05b8f23aa 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -524,11 +524,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc cond } - fn type_test(&mut self, _pointer: Self::Value, _typeid: Self::Value) -> Self::Value { - // Unsupported. - self.context.new_rvalue_from_int(self.int_type, 0) - } - fn type_checked_load( &mut self, _llvtable: Self::Value, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 167678c2ff1..ec006b59192 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1815,8 +1815,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap(); let dbg_loc = self.get_dbg_loc(); - // Test whether the function pointer is associated with the type identifier. - let cond = self.type_test(llfn, typeid_metadata); + // Test whether the function pointer is associated with the type identifier using the + // llvm.type.test intrinsic. The LowerTypeTests link-time optimization pass replaces + // calls to this intrinsic with code to test type membership. + let typeid = self.get_metadata_value(typeid_metadata); + let cond = self.call_intrinsic("llvm.type.test", &[llfn, typeid]); let bb_pass = self.append_sibling_block("type_test.pass"); let bb_fail = self.append_sibling_block("type_test.fail"); self.cond_br(cond, bb_pass, bb_fail); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 989752eb78e..10697b9a71f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -636,13 +636,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } - fn type_test(&mut self, pointer: Self::Value, typeid: Self::Metadata) -> Self::Value { - // Test the called operand using llvm.type.test intrinsic. The LowerTypeTests link-time - // optimization pass replaces calls to this intrinsic with code to test type membership. - let typeid = self.get_metadata_value(typeid); - self.call_intrinsic("llvm.type.test", &[pointer, typeid]) - } - fn type_checked_load( &mut self, llvtable: &'ll Value, diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index a07c569a032..7d0c6be4c65 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -22,8 +22,6 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { fn abort(&mut self); fn assume(&mut self, val: Self::Value); fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; - /// Trait method used to test whether a given pointer is associated with a type identifier. - fn type_test(&mut self, pointer: Self::Value, typeid: Self::Metadata) -> Self::Value; /// Trait method used to load a function while testing if it is associated with a type /// identifier. fn type_checked_load( -- cgit 1.4.1-3-g733a5 From 72ecde27ff3f0c02a738acd45d94d5588cb446cc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 21 May 2025 22:50:21 +0200 Subject: compiler: change Conv to CanonAbi --- .../rustc_codegen_ssa/src/back/symbol_export.rs | 20 +++++----- compiler/rustc_const_eval/messages.ftl | 2 +- .../src/mono_checks/abi_check.rs | 8 ++-- .../src/cfi/typeid/itanium_cxx_abi/mod.rs | 5 ++- compiler/rustc_smir/src/rustc_smir/convert/abi.rs | 38 ++++++++++++++++++- compiler/rustc_target/src/callconv/arm.rs | 6 +-- compiler/rustc_target/src/callconv/mod.rs | 6 +-- compiler/rustc_ty_utils/src/abi.rs | 44 ++-------------------- 8 files changed, 64 insertions(+), 65 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index e26f999773d..92b9b6e132e 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,5 +1,6 @@ use std::collections::hash_map::Entry::*; +use rustc_abi::{CanonAbi, X86Call}; use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; @@ -14,7 +15,6 @@ use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolNam use rustc_middle::util::Providers; use rustc_session::config::{CrateType, OomStrategy}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::callconv::Conv; use rustc_target::spec::{SanitizerSet, TlsModel}; use tracing::debug; @@ -652,7 +652,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( fn calling_convention_for_symbol<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, -) -> (Conv, &'tcx [rustc_target::callconv::ArgAbi<'tcx, Ty<'tcx>>]) { +) -> (CanonAbi, &'tcx [rustc_target::callconv::ArgAbi<'tcx, Ty<'tcx>>]) { let instance = match symbol { ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _) if tcx.is_static(def_id) => @@ -683,7 +683,7 @@ fn calling_convention_for_symbol<'tcx>( }) .map(|fnabi| (fnabi.conv, &fnabi.args[..])) // FIXME(workingjubilee): why don't we know the convention here? - .unwrap_or((Conv::Rust, &[])) + .unwrap_or((CanonAbi::Rust, &[])) } /// This is the symbol name of the given instance as seen by the linker. @@ -717,14 +717,14 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( _ => return undecorated, }; - let (conv, args) = calling_convention_for_symbol(tcx, symbol); + let (callconv, args) = calling_convention_for_symbol(tcx, symbol); // Decorate symbols with prefixes, suffixes and total number of bytes of arguments. // Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170 - let (prefix, suffix) = match conv { - Conv::X86Fastcall => ("@", "@"), - Conv::X86Stdcall => ("_", "@"), - Conv::X86VectorCall => ("", "@@"), + let (prefix, suffix) = match callconv { + CanonAbi::X86(X86Call::Fastcall) => ("@", "@"), + CanonAbi::X86(X86Call::Stdcall) => ("_", "@"), + CanonAbi::X86(X86Call::Vectorcall) => ("", "@@"), _ => { if let Some(prefix) = prefix { undecorated.insert(0, prefix); @@ -758,9 +758,9 @@ pub(crate) fn extend_exported_symbols<'tcx>( symbol: ExportedSymbol<'tcx>, instantiating_crate: CrateNum, ) { - let (conv, _) = calling_convention_for_symbol(tcx, symbol); + let (callconv, _) = calling_convention_for_symbol(tcx, symbol); - if conv != Conv::GpuKernel || tcx.sess.target.os != "amdhsa" { + if callconv != CanonAbi::GpuKernel || tcx.sess.target.os != "amdhsa" { return; } diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index f4defd2aa13..abecea13520 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -118,7 +118,7 @@ const_eval_frame_note_inner = inside {$where_ -> const_eval_frame_note_last = the failure occurred here const_eval_incompatible_calling_conventions = - calling a function with calling convention {$callee_conv} using calling convention {$caller_conv} + calling a function with calling convention "{$callee_conv}" using calling convention "{$caller_conv}" const_eval_incompatible_return_types = calling a function with return type {$callee_ty} passing return place of type {$caller_ty} diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index cfeaee07776..5478e54a606 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -1,6 +1,6 @@ //! This module ensures that if a function's ABI requires a particular target feature, //! that target feature is enabled both on the callee and all callers. -use rustc_abi::{BackendRepr, RegKind}; +use rustc_abi::{BackendRepr, CanonAbi, RegKind, X86Call}; use rustc_hir::{CRATE_HIR_ID, HirId}; use rustc_middle::mir::{self, Location, traversal}; use rustc_middle::ty::layout::LayoutCx; @@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypingEnv}; use rustc_session::lint::builtin::WASM_C_ABI; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; -use rustc_target::callconv::{ArgAbi, Conv, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use rustc_target::spec::{HasWasmCAbiOpt, WasmCAbi}; use crate::errors; @@ -72,7 +72,7 @@ fn do_check_simd_vector_abi<'tcx>( } } // The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed. - if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) { + if abi.conv == CanonAbi::X86(X86Call::Vectorcall) && !have_feature(sym::sse2) { let (span, _hir_id) = loc(); tcx.dcx().emit_err(errors::AbiRequiredTargetFeature { span, @@ -128,7 +128,7 @@ fn do_check_wasm_abi<'tcx>( if !(tcx.sess.target.arch == "wasm32" && tcx.sess.target.os == "unknown" && tcx.wasm_c_abi_opt() == WasmCAbi::Legacy { with_lint: true } - && abi.conv == Conv::C) + && abi.conv == CanonAbi::C) { return; } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs index 562e288afaa..82e18ad497b 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs @@ -4,10 +4,11 @@ //! For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, //! see design document in the tracking issue #89653. +use rustc_abi::CanonAbi; use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; -use rustc_target::callconv::{Conv, FnAbi, PassMode}; +use rustc_target::callconv::{FnAbi, PassMode}; use tracing::instrument; mod encode; @@ -45,7 +46,7 @@ pub fn typeid_for_fnabi<'tcx>( let mut encode_ty_options = EncodeTyOptions::from_bits(options.bits()) .unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits())); match fn_abi.conv { - Conv::C => { + CanonAbi::C => { encode_ty_options.insert(EncodeTyOptions::GENERALIZE_REPR_C); } _ => { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index 7ccc785a400..a0c70e81fa4 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -2,6 +2,7 @@ #![allow(rustc::usage_of_qualified_ty)] +use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call}; use rustc_middle::ty; use rustc_target::callconv::{self, Conv}; use stable_mir::abi::{ @@ -69,7 +70,7 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { assert!(self.args.len() >= self.fixed_count as usize); - assert!(!self.c_variadic || matches!(self.conv, Conv::C)); + assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C)); FnAbi { args: self.args.as_ref().stable(tables), ret: self.ret.stable(tables), @@ -121,6 +122,41 @@ impl<'tcx> Stable<'tcx> for callconv::Conv { } } +impl<'tcx> Stable<'tcx> for CanonAbi { + type T = CallConvention; + + fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + match self { + CanonAbi::C => CallConvention::C, + CanonAbi::Rust => CallConvention::Rust, + CanonAbi::RustCold => CallConvention::Cold, + CanonAbi::Arm(arm_call) => match arm_call { + ArmCall::Aapcs => CallConvention::ArmAapcs, + ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall, + ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry, + }, + CanonAbi::GpuKernel => CallConvention::GpuKernel, + CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { + InterruptKind::Avr => CallConvention::AvrInterrupt, + InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt, + InterruptKind::Msp430 => CallConvention::Msp430Intr, + InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => { + CallConvention::RiscvInterrupt + } + InterruptKind::X86 => CallConvention::X86Intr, + }, + CanonAbi::X86(x86_call) => match x86_call { + X86Call::Fastcall => CallConvention::X86Fastcall, + X86Call::Stdcall => CallConvention::X86Stdcall, + X86Call::SysV64 => CallConvention::X86_64SysV, + X86Call::Thiscall => CallConvention::X86ThisCall, + X86Call::Vectorcall => CallConvention::X86VectorCall, + X86Call::Win64 => CallConvention::X86_64Win64, + }, + } + } +} + impl<'tcx> Stable<'tcx> for callconv::PassMode { type T = PassMode; diff --git a/compiler/rustc_target/src/callconv/arm.rs b/compiler/rustc_target/src/callconv/arm.rs index 0a5dcc66347..70830fa07b6 100644 --- a/compiler/rustc_target/src/callconv/arm.rs +++ b/compiler/rustc_target/src/callconv/arm.rs @@ -1,6 +1,6 @@ -use rustc_abi::{HasDataLayout, TyAbiInterface}; +use rustc_abi::{ArmCall, CanonAbi, HasDataLayout, TyAbiInterface}; -use crate::callconv::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform}; +use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; use crate::spec::HasTargetSpec; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option @@ -90,7 +90,7 @@ where // If this is a target with a hard-float ABI, and the function is not explicitly // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates. let vfp = cx.target_spec().llvm_target.ends_with("hf") - && fn_abi.conv != Conv::ArmAapcs + && fn_abi.conv != CanonAbi::Arm(ArmCall::Aapcs) && !fn_abi.c_variadic; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 5e510ef38be..c3ca11c2d88 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -3,8 +3,8 @@ use std::str::FromStr; use std::{fmt, iter}; use rustc_abi::{ - AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Primitive, Reg, RegKind, Scalar, - Size, TyAbiInterface, TyAndLayout, + AddressSpace, Align, BackendRepr, CanonAbi, ExternAbi, HasDataLayout, Primitive, Reg, RegKind, + Scalar, Size, TyAbiInterface, TyAndLayout, }; use rustc_macros::HashStable_Generic; @@ -606,7 +606,7 @@ pub struct FnAbi<'a, Ty> { /// This can be used to know whether an argument is variadic or not. pub fixed_count: u32, /// The calling convention of this function. - pub conv: Conv, + pub conv: CanonAbi, /// Indicates if an unwind may happen across a call to this function. pub can_unwind: bool, } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 2b49d7ac8b5..83d7416b03e 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_target::callconv::{ - ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, RiscvInterruptKind, + AbiMap, ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, FnAbi, PassMode, }; use tracing::debug; @@ -240,45 +240,6 @@ fn fn_sig_for_fn_abi<'tcx>( } } -#[inline] -fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv { - use rustc_abi::ExternAbi::*; - match tcx.sess.target.adjust_abi(abi, c_variadic) { - Rust | RustCall => Conv::Rust, - - // This is intentionally not using `Conv::Cold`, as that has to preserve - // even SIMD registers, which is generally not a good trade-off. - RustCold => Conv::PreserveMost, - - // It's the ABI's job to select this, not ours. - System { .. } => bug!("system abi should be selected elsewhere"), - EfiApi => bug!("eficall abi should be selected elsewhere"), - - Stdcall { .. } => Conv::X86Stdcall, - Fastcall { .. } => Conv::X86Fastcall, - Vectorcall { .. } => Conv::X86VectorCall, - Thiscall { .. } => Conv::X86ThisCall, - C { .. } => Conv::C, - Unadjusted => Conv::C, - Win64 { .. } => Conv::X86_64Win64, - SysV64 { .. } => Conv::X86_64SysV, - Aapcs { .. } => Conv::ArmAapcs, - CCmseNonSecureCall => Conv::CCmseNonSecureCall, - CCmseNonSecureEntry => Conv::CCmseNonSecureEntry, - PtxKernel => Conv::GpuKernel, - Msp430Interrupt => Conv::Msp430Intr, - X86Interrupt => Conv::X86Intr, - GpuKernel => Conv::GpuKernel, - AvrInterrupt => Conv::AvrInterrupt, - AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, - RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }, - RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }, - - // These API constants ought to be more specific... - Cdecl { .. } => Conv::C, - } -} - fn fn_abi_of_fn_ptr<'tcx>( tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, @@ -529,7 +490,8 @@ fn fn_abi_new_uncached<'tcx>( }; let sig = tcx.normalize_erasing_regions(cx.typing_env, sig); - let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic); + let abi_map = AbiMap::from_target(&tcx.sess.target); + let conv = abi_map.canonize_abi(sig.abi, sig.c_variadic).unwrap(); let mut inputs = sig.inputs(); let extra_args = if sig.abi == ExternAbi::RustCall { -- cgit 1.4.1-3-g733a5 From ee9901e65c78f70b93dab5bd1e04bd77273b7c40 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 3 Jun 2025 23:42:21 -0700 Subject: Change `tag_field` to `FieldIdx` in `Variants::Multiple` It was already available as a generic parameter anyway, and it's not like we'll ever put a tag in the 5-billionth field. --- compiler/rustc_abi/src/layout.rs | 4 ++-- compiler/rustc_abi/src/layout/coroutine.rs | 4 ++-- compiler/rustc_abi/src/lib.rs | 2 +- compiler/rustc_codegen_cranelift/src/discriminant.rs | 6 +++--- .../src/debuginfo/metadata/enums/cpp_like.rs | 14 +++++++------- .../src/debuginfo/metadata/enums/native.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/place.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/discriminant.rs | 8 ++++---- compiler/rustc_const_eval/src/interpret/validity.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 8 +++++--- compiler/rustc_smir/src/rustc_smir/convert/abi.rs | 2 +- compiler/rustc_transmute/src/layout/tree.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 2 +- 14 files changed, 33 insertions(+), 31 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 42250aa173b..21fd6be39fa 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -758,7 +758,7 @@ impl LayoutCalculator { niche_variants, niche_start, }, - tag_field: 0, + tag_field: FieldIdx::new(0), variants: IndexVec::new(), }, fields: FieldsShape::Arbitrary { @@ -1072,7 +1072,7 @@ impl LayoutCalculator { variants: Variants::Multiple { tag, tag_encoding: TagEncoding::Direct, - tag_field: 0, + tag_field: FieldIdx::new(0), variants: IndexVec::new(), }, fields: FieldsShape::Arbitrary { diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 27e704d538c..2b22276d4ae 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -158,7 +158,7 @@ pub(super) fn layout< // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let tag_index = prefix_layouts.len(); + let tag_index = prefix_layouts.next_index(); // `variant_fields` already accounts for the reserved variants, so no need to add them. let max_discr = (variant_fields.len() - 1) as u128; @@ -187,7 +187,7 @@ pub(super) fn layout< // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. - let b_start = FieldIdx::new(tag_index + 1); + let b_start = tag_index.plus(1); let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); let offsets_a = offsets; diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index b806d0aba31..46b7a0c1e77 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1573,7 +1573,7 @@ pub enum Variants { Multiple { tag: Scalar, tag_encoding: TagEncoding, - tag_field: usize, + tag_field: FieldIdx, variants: IndexVec>, }, } diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index 4d0d5dc60eb..a08b0e0cbfc 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -28,7 +28,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( tag_encoding: TagEncoding::Direct, variants: _, } => { - let ptr = place.place_field(fx, FieldIdx::new(tag_field)); + let ptr = place.place_field(fx, tag_field); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; let to = match ptr.layout().ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { @@ -53,7 +53,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( variants: _, } => { if variant_index != untagged_variant { - let niche = place.place_field(fx, FieldIdx::new(tag_field)); + let niche = place.place_field(fx, tag_field); let niche_type = fx.clif_type(niche.layout().ty).unwrap(); let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128).wrapping_add(niche_start); @@ -118,7 +118,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let cast_to = fx.clif_type(dest_layout.ty).unwrap(); // Read the tag/niche-encoded discriminant from memory. - let tag = value.value_field(fx, FieldIdx::new(tag_field)); + let tag = value.value_field(fx, tag_field); let tag = tag.load_scalar(fx); // Decode the discriminant (specifically if it's niche-encoded). diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index e9574108696..a5c80895741 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use libc::c_uint; -use rustc_abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants}; +use rustc_abi::{Align, Endian, FieldIdx, Size, TagEncoding, VariantIdx, Variants}; use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name; use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods}; @@ -401,7 +401,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( enum_type_and_layout: TyAndLayout<'tcx>, enum_type_di_node: &'ll DIType, variant_indices: impl Iterator + Clone, - tag_field: usize, + tag_field: FieldIdx, untagged_variant_index: Option, ) -> SmallVec<&'ll DIType> { let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout); @@ -805,7 +805,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( variant_field_infos: &[VariantFieldInfo<'ll>], discr_type_di_node: &'ll DIType, tag_base_type: Ty<'tcx>, - tag_field: usize, + tag_field: FieldIdx, untagged_variant_index: Option, di_flags: DIFlags, ) -> SmallVec<&'ll DIType> { @@ -858,7 +858,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( })); assert_eq!( - cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty), + cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field.as_usize()).ty), cx.size_and_align_of(self::tag_base_type(cx.tcx, enum_type_and_layout)) ); @@ -875,7 +875,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( Endian::Big => (8, 0), }; - let tag_field_offset = enum_type_and_layout.fields.offset(tag_field).bytes(); + let tag_field_offset = enum_type_and_layout.fields.offset(tag_field.as_usize()).bytes(); let lo_offset = Size::from_bytes(tag_field_offset + lo_offset); let hi_offset = Size::from_bytes(tag_field_offset + hi_offset); @@ -905,8 +905,8 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( cx, enum_type_di_node, TAG_FIELD_NAME, - enum_type_and_layout.field(cx, tag_field), - enum_type_and_layout.fields.offset(tag_field), + enum_type_and_layout.field(cx, tag_field.as_usize()), + enum_type_and_layout.fields.offset(tag_field.as_usize()), di_flags, tag_base_type_di_node, None, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 20a841f2287..62d38d463ab 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -373,7 +373,7 @@ fn build_discr_member_di_node<'ll, 'tcx>( file, UNKNOWN_LINE_NUMBER, layout, - enum_or_coroutine_type_and_layout.fields.offset(tag_field), + enum_or_coroutine_type_and_layout.fields.offset(tag_field.as_usize()), DIFlags::FlagArtificial, ty, )) diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index eade9e52de9..b7f2277bfda 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -462,10 +462,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let tag_op = match self.val { OperandValue::ZeroSized => bug!(), OperandValue::Immediate(_) | OperandValue::Pair(_, _) => { - self.extract_field(fx, bx, tag_field) + self.extract_field(fx, bx, tag_field.as_usize()) } OperandValue::Ref(place) => { - let tag = place.with_type(self.layout).project_field(bx, tag_field); + let tag = place.with_type(self.layout).project_field(bx, tag_field.as_usize()); bx.load_operand(tag) } }; diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 31db7fa9a18..937063c24a6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { Variants::Single { index } => assert_eq!(index, variant_index), Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => { - let ptr = self.project_field(bx, tag_field); + let ptr = self.project_field(bx, tag_field.as_usize()); let to = self.layout.ty.discriminant_for_variant(bx.tcx(), variant_index).unwrap().val; bx.store_to_place( @@ -265,7 +265,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { .. } => { if variant_index != untagged_variant { - let niche = self.project_field(bx, tag_field); + let niche = self.project_field(bx, tag_field.as_usize()); let niche_llty = bx.cx().immediate_backend_type(niche.layout); let BackendRepr::Scalar(scalar) = niche.layout.backend_repr else { bug!("expected a scalar placeref for the niche"); diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 2f0b1cb6d1e..020cd65d75d 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -1,6 +1,6 @@ //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines). -use rustc_abi::{self as abi, TagEncoding, VariantIdx, Variants}; +use rustc_abi::{self as abi, FieldIdx, TagEncoding, VariantIdx, Variants}; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, CoroutineArgsExt, ScalarInt, Ty}; use rustc_middle::{mir, span_bug}; @@ -26,7 +26,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // No need to validate that the discriminant here because the // `TyAndLayout::for_variant()` call earlier already checks the // variant is valid. - let tag_dest = self.project_field(dest, tag_field)?; + let tag_dest = self.project_field(dest, tag_field.as_usize())?; self.write_scalar(tag, &tag_dest) } None => { @@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. - let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?; + let tag_val = self.read_immediate(&self.project_field(op, tag_field.as_usize())?)?; assert_eq!(tag_layout.size, tag_val.layout.size); assert_eq!(tag_layout.backend_repr.is_signed(), tag_val.layout.backend_repr.is_signed()); trace!("tag value: {}", tag_val); @@ -231,7 +231,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { &self, layout: TyAndLayout<'tcx>, variant_index: VariantIdx, - ) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> { + ) -> InterpResult<'tcx, Option<(ScalarInt, FieldIdx)>> { // Layout computation excludes uninhabited variants from consideration. // Therefore, there's no way to represent those variants in the given layout. // Essentially, uninhabited variants do not have a tag that corresponds to their diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 8f39afa642a..7d76d925ef2 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -294,7 +294,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { // First, check if we are projecting to a variant. match layout.variants { Variants::Multiple { tag_field, .. } => { - if tag_field == field { + if tag_field.as_usize() == field { return match layout.ty.kind() { ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag, ty::Coroutine(..) => PathElem::CoroutineTag, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 7ebfebea44e..c2ae6b06192 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -934,7 +934,7 @@ where .unwrap(), ), Variants::Multiple { tag, tag_field, .. } => { - if i == tag_field { + if FieldIdx::from_usize(i) == tag_field { return TyMaybeWithLayout::TyAndLayout(tag_layout(tag)); } TyMaybeWithLayout::Ty(args.as_coroutine().prefix_tys()[i]) @@ -1060,8 +1060,10 @@ where tag_field, variants, .. - } if variants.len() == 2 && this.fields.offset(*tag_field) == offset => { - let tagged_variant = if untagged_variant.as_u32() == 0 { + } if variants.len() == 2 + && this.fields.offset(tag_field.as_usize()) == offset => + { + let tagged_variant = if *untagged_variant == VariantIdx::ZERO { VariantIdx::from_u32(1) } else { VariantIdx::from_u32(0) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index 06dfaf079a3..64901ee0502 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -180,7 +180,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants( // However, if the discriminant is placed past the end of the variant, then we need // to factor in the size of the discriminant manually. This really should be refactored // better, but this "works" for now. - if layout.fields.offset(tag_field) >= variant_size { + if layout.fields.offset(tag_field.as_usize()) >= variant_size { variant_size += match tag_encoding { TagEncoding::Direct => tag.size(cx), _ => Size::ZERO, -- cgit 1.4.1-3-g733a5 From 64df9e3c8a38e6975a6376ba0384d0a7bd4949ea Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 4 Jun 2025 14:25:38 -0700 Subject: compiler: Document the offset invariant of `OperandValue::Pair` --- compiler/rustc_codegen_ssa/src/mir/operand.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index eade9e52de9..29d030b7461 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -45,9 +45,15 @@ pub enum OperandValue { Immediate(V), /// A pair of immediate LLVM values. Used by wide pointers too. /// - /// An `OperandValue` *must* be this variant for any type for which + /// # Invariants + /// - For `Pair(a, b)`, `a` is always at offset 0, but may have `FieldIdx(1..)` + /// - `b` is not at offset 0, because `V` is not a 1ZST type. + /// - `a` and `b` will have a different FieldIdx, but otherwise `b`'s may be lower + /// or they may not be adjacent, due to arbitrary numbers of 1ZST fields that + /// will not affect the shape of the data which determines if `Pair` will be used. + /// - An `OperandValue` *must* be this variant for any type for which /// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`. - /// The backend values in this variant must be the *immediate* backend types, + /// - The backend values in this variant must be the *immediate* backend types, /// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`] /// with `immediate: true`. Pair(V, V), -- cgit 1.4.1-3-g733a5 From f8e9778eb12573eabac183f5d617e1a7404505c7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 May 2025 20:37:06 +0000 Subject: Make #[used(linker)] the default on ELF too #[used] currently is an alias for #[used(linker)] on all platforms except ELF based ones where it is an alias for #[used(compiler)]. The latter has surprising behavior and the LLVM LangRef explicitly states that it "should only be used in rare circumstances, and should not be exposed to source languages." The reason #[used] still was an alias to #[used(compiler)] on ELF is because the gold linker has issues with it. Luckily gold has been deprecated with GCC 15 and seems to be unable to bootstrap rustc anyway. As such we shouldn't really care about supporting gold. --- compiler/rustc_codegen_llvm/src/consts.rs | 12 ++++----- compiler/rustc_codegen_ssa/src/back/link.rs | 5 ++-- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 33 +++---------------------- 3 files changed, 13 insertions(+), 37 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index fe2f2027327..866696276e1 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -541,12 +541,12 @@ impl<'ll> CodegenCx<'ll, '_> { // in the handling of `.init_array` (the static constructor list) in versions of // the gold linker (prior to the one released with binutils 2.36). // - // That said, we only ever emit these when compiling for ELF targets, unless - // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage - // on other targets, in particular MachO targets have *their* static constructor - // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However, - // that check happens when assigning the `CodegenFnAttrFlags` in - // `rustc_hir_analysis`, so we don't need to take care of it here. + // That said, we only ever emit these when `#[used(compiler)]` is explicitly + // requested. This is to avoid similar breakage on other targets, in particular + // MachO targets have *their* static constructor lists broken if `llvm.compiler.used` + // is emitted rather than `llvm.used`. However, that check happens when assigning + // the `CodegenFnAttrFlags` in the `codegen_fn_attrs` query, so we don't need to + // take care of it here. self.add_compiler_used_global(g); } if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c5792da2678..30128c4bea2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1986,7 +1986,7 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor /// This method creates a synthetic object file, which contains undefined references to all symbols /// that are necessary for the linking. They are only present in symbol table but not actually /// used in any sections, so the linker will therefore pick relevant rlibs for linking, but -/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections. +/// unused `#[no_mangle]` or `#[used(compiler)]` can still be discard by GC sections. /// /// There's a few internal crates in the standard library (aka libcore and /// libstd) which actually have a circular dependence upon one another. This @@ -2020,7 +2020,8 @@ fn add_linked_symbol_object( if file.format() == object::BinaryFormat::MachO { // Divide up the sections into sub-sections via symbols for dead code stripping. - // Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets. + // Without this flag, unused `#[no_mangle]` or `#[used(compiler)]` cannot be + // discard on MachO targets. file.set_subsections_via_symbols(); } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 4bcafa3be36..0b31fa8fa88 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -195,35 +195,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() }); } None => { - // Unfortunately, unconditionally using `llvm.used` causes - // issues in handling `.init_array` with the gold linker, - // but using `llvm.compiler.used` caused a nontrivial amount - // of unintentional ecosystem breakage -- particularly on - // Mach-O targets. - // - // As a result, we emit `llvm.compiler.used` only on ELF - // targets. This is somewhat ad-hoc, but actually follows - // our pre-LLVM 13 behavior (prior to the ecosystem - // breakage), and seems to match `clang`'s behavior as well - // (both before and after LLVM 13), possibly because they - // have similar compatibility concerns to us. See - // https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146 - // and following comments for some discussion of this, as - // well as the comments in `rustc_codegen_llvm` where these - // flags are handled. - // - // Anyway, to be clear: this is still up in the air - // somewhat, and is subject to change in the future (which - // is a good thing, because this would ideally be a bit - // more firmed up). - let is_like_elf = !(tcx.sess.target.is_like_darwin - || tcx.sess.target.is_like_windows - || tcx.sess.target.is_like_wasm); - codegen_fn_attrs.flags |= if is_like_elf { - CodegenFnAttrFlags::USED_COMPILER - } else { - CodegenFnAttrFlags::USED_LINKER - }; + // Unconditionally using `llvm.used` causes issues in handling + // `.init_array` with the gold linker. Luckily gold has been + // deprecated with GCC 15 and rustc now warns about using gold. + codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER } } } -- cgit 1.4.1-3-g733a5 From fd3da4bebdff63b7529483ff7025986ef16bf463 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 4 Jun 2025 06:26:56 +0000 Subject: Replace some `Option` with `Span` and use DUMMY_SP instead of None --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 4 +-- compiler/rustc_borrowck/src/type_check/mod.rs | 22 +++++------- compiler/rustc_borrowck/src/universal_regions.rs | 8 ++--- compiler/rustc_codegen_cranelift/src/base.rs | 16 ++++----- .../rustc_codegen_cranelift/src/intrinsics/llvm.rs | 2 +- .../src/intrinsics/llvm_aarch64.rs | 2 +- .../src/intrinsics/llvm_x86.rs | 2 +- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 6 ++-- compiler/rustc_codegen_cranelift/src/main_shim.rs | 4 +-- compiler/rustc_codegen_cranelift/src/num.rs | 2 +- compiler/rustc_codegen_cranelift/src/unsize.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/common.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 9 ++--- compiler/rustc_codegen_ssa/src/size_of_val.rs | 3 +- compiler/rustc_const_eval/src/check_consts/ops.rs | 6 +--- .../rustc_const_eval/src/check_consts/qualifs.rs | 4 +-- .../rustc_const_eval/src/const_eval/machine.rs | 2 +- compiler/rustc_const_eval/src/interpret/operand.rs | 3 +- .../rustc_const_eval/src/util/caller_location.rs | 2 +- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 8 ++--- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 20 +++++------ .../rustc_hir_analysis/src/coherence/builtin.rs | 10 +++--- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 2 +- compiler/rustc_hir_typeck/src/check.rs | 4 +-- compiler/rustc_hir_typeck/src/closure.rs | 6 ++-- compiler/rustc_hir_typeck/src/coercion.rs | 5 ++- compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 ++-- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 5 ++- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 8 ++--- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 5 +-- compiler/rustc_middle/src/error.rs | 2 +- compiler/rustc_middle/src/middle/lang_items.rs | 2 +- compiler/rustc_middle/src/mir/statement.rs | 2 +- compiler/rustc_middle/src/ty/adjustment.rs | 4 +-- compiler/rustc_middle/src/ty/context.rs | 8 ++--- compiler/rustc_middle/src/ty/instance.rs | 6 ++-- compiler/rustc_middle/src/ty/sty.rs | 14 ++++---- .../rustc_mir_build/src/builder/expr/as_rvalue.rs | 2 +- compiler/rustc_mir_build/src/builder/expr/into.rs | 2 +- .../rustc_mir_build/src/builder/matches/test.rs | 4 +-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 7 ++-- compiler/rustc_mir_transform/src/coroutine.rs | 31 +++++++++-------- compiler/rustc_mir_transform/src/coroutine/drop.rs | 39 +++++++++++----------- compiler/rustc_mir_transform/src/elaborate_drop.rs | 13 +++----- compiler/rustc_mir_transform/src/shim.rs | 2 +- .../src/shim/async_destructor_ctor.rs | 12 +++---- compiler/rustc_mir_transform/src/validate.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 4 +-- compiler/rustc_monomorphize/src/lib.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/transform.rs | 8 ++--- .../src/error_reporting/infer/mod.rs | 4 +-- .../src/error_reporting/traits/call_kind.rs | 6 ++-- .../src/error_reporting/traits/suggestions.rs | 6 ++-- compiler/rustc_trait_selection/src/infer.rs | 8 ++--- .../rustc_trait_selection/src/traits/effects.rs | 4 +-- compiler/rustc_trait_selection/src/traits/misc.rs | 4 +-- .../rustc_trait_selection/src/traits/project.rs | 34 ++++++++++--------- .../src/traits/select/confirmation.rs | 28 ++++++++-------- compiler/rustc_trait_selection/src/traits/wf.rs | 4 +-- compiler/rustc_ty_utils/src/abi.rs | 13 ++++---- compiler/rustc_ty_utils/src/common_traits.rs | 3 +- compiler/rustc_ty_utils/src/structural_match.rs | 3 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/types.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/miri/src/shims/panic.rs | 2 +- .../lang-items/lang-item-generic-requirements.rs | 3 +- .../lang-item-generic-requirements.stderr | 8 +++-- 77 files changed, 250 insertions(+), 250 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f41627e479f..ca110719a72 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -732,7 +732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, args: Option<&'hir hir::GenericArgs<'hir>>, ) -> &'hir hir::Path<'hir> { - let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_id = self.tcx.require_lang_item(lang_item, span); let def_kind = self.tcx.def_kind(def_id); let res = Res::Def(def_kind, def_id); self.arena.alloc(hir::Path { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b7b6a2da549..1b4bb11d87b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -263,7 +263,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // something that already has `Fn`-like bounds (or is a closure), so we can't // restrict anyways. } else { - let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span)); + let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, span); self.suggest_adding_bounds(&mut err, ty, copy_did, span); } @@ -1915,7 +1915,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let local_ty = self.body.local_decls[place.local].ty; let typeck_results = tcx.typeck(self.mir_def_id()); - let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span)); + let clone = tcx.require_lang_item(LangItem::Clone, body.span); for expr in expr_finder.clones { if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind && let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4f5baeff7c3..4f75dd7e992 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -688,7 +688,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), + tcx.require_lang_item(LangItem::Sized, self.last_span), [place_ty], ); self.prove_trait_ref( @@ -1010,7 +1010,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let ty = place.ty(self.body, tcx).ty; let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(span)), + tcx.require_lang_item(LangItem::Copy, span), [ty], ); @@ -1025,11 +1025,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]); self.prove_trait_ref( trait_ref, @@ -1041,11 +1038,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} Rvalue::ShallowInitBox(_operand, ty) => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [*ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]); self.prove_trait_ref( trait_ref, @@ -1222,7 +1216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let &ty = ty; let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + tcx.require_lang_item(LangItem::CoerceUnsized, span), [op.ty(self.body, tcx), ty], ); @@ -1811,7 +1805,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), + tcx.require_lang_item(LangItem::Copy, self.last_span), [place_ty.ty], ); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index c11e14d214c..846299711be 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -544,10 +544,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // (as it's created inside the body itself, not passed in from outside). if let DefiningTy::FnDef(def_id, _) = defining_ty { if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { - let va_list_did = self.infcx.tcx.require_lang_item( - LangItem::VaList, - Some(self.infcx.tcx.def_span(self.mir_def)), - ); + let va_list_did = self + .infcx + .tcx + .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); let reg_vid = self .infcx diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 4617304105a..0b641ba64b7 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -380,7 +380,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicBoundsCheck, &[index, len, location], *unwind, - Some(source_info.span), + source_info.span, ); } AssertKind::MisalignedPointerDereference { ref required, ref found } => { @@ -393,7 +393,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicMisalignedPointerDereference, &[required, found, location], *unwind, - Some(source_info.span), + source_info.span, ); } AssertKind::NullPointerDereference => { @@ -404,7 +404,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicNullPointerDereference, &[location], *unwind, - Some(source_info.span), + source_info.span, ) } _ => { @@ -415,7 +415,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { msg.panic_function(), &[location], *unwind, - Some(source_info.span), + source_info.span, ); } } @@ -531,7 +531,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { ); } TerminatorKind::UnwindTerminate(reason) => { - codegen_unwind_terminate(fx, Some(source_info.span), *reason); + codegen_unwind_terminate(fx, source_info.span, *reason); } TerminatorKind::UnwindResume => { // FIXME implement unwinding @@ -1074,7 +1074,7 @@ pub(crate) fn codegen_operand<'tcx>( pub(crate) fn codegen_panic_nounwind<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, - span: Option, + span: Span, ) { let msg_ptr = fx.anonymous_str(msg_str); let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); @@ -1091,7 +1091,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>( pub(crate) fn codegen_unwind_terminate<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - span: Option, + span: Span, reason: UnwindTerminateReason, ) { codegen_panic_inner(fx, reason.lang_item(), &[], UnwindAction::Unreachable, span); @@ -1102,7 +1102,7 @@ fn codegen_panic_inner<'tcx>( lang_item: rustc_hir::LangItem, args: &[Value], _unwind: UnwindAction, - span: Option, + span: Span, ) { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index 2e02e85a997..99a5518d0b6 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -71,7 +71,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs index d22483cf177..c22f2a7b873 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs @@ -512,7 +512,7 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, fx.mir.span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 3d67913a8ff..615f6c47d90 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -1321,7 +1321,7 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 0de23e55e81..27a5df8b152 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -785,7 +785,7 @@ fn codegen_regular_intrinsic_call<'tcx>( } }) }); - crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span)); + crate::base::codegen_panic_nounwind(fx, &msg_str, source_info.span); return Ok(()); } } @@ -884,7 +884,7 @@ fn codegen_regular_intrinsic_call<'tcx>( crate::base::codegen_panic_nounwind( fx, "128bit atomics not yet supported", - None, + source_info.span, ); return Ok(()); } else { @@ -919,7 +919,7 @@ fn codegen_regular_intrinsic_call<'tcx>( crate::base::codegen_panic_nounwind( fx, "128bit atomics not yet supported", - None, + source_info.span, ); return Ok(()); } else { diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 6eef97c14dd..bf756860b64 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -101,7 +101,7 @@ pub(crate) fn maybe_create_entry_wrapper( let call_inst = bcx.ins().call(main_func_ref, &[]); let call_results = bcx.func.dfg.inst_results(call_inst).to_owned(); - let termination_trait = tcx.require_lang_item(LangItem::Termination, None); + let termination_trait = tcx.require_lang_item(LangItem::Termination, DUMMY_SP); let report = tcx .associated_items(termination_trait) .find_by_ident_and_kind( @@ -136,7 +136,7 @@ pub(crate) fn maybe_create_entry_wrapper( } } else { // Regular main fn invoked via start lang item. - let start_def_id = tcx.require_lang_item(LangItem::Start, None); + let start_def_id = tcx.require_lang_item(LangItem::Start, DUMMY_SP); let start_instance = Instance::expect_resolve( tcx, ty::TypingEnv::fully_monomorphized(), diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index f53045df6e7..95d44dfb6d9 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -54,7 +54,7 @@ fn codegen_three_way_compare<'tcx>( let gt = fx.bcx.ins().icmp(gt_cc, lhs, rhs); let lt = fx.bcx.ins().icmp(lt_cc, lhs, rhs); let val = fx.bcx.ins().isub(gt, lt); - CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(Some(fx.mir.span)))) + CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(fx.mir.span))) } fn codegen_compare_bin_op<'tcx>( diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index f8bbb214920..662546e4999 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -240,7 +240,7 @@ pub(crate) fn size_and_align_of<'tcx>( }) }); - codegen_panic_nounwind(fx, &msg_str, None); + codegen_panic_nounwind(fx, &msg_str, fx.mir.span); fx.bcx.switch_to_block(next_block); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f7863fe4ae2..c2d6a26de0f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -561,7 +561,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let EntryFnType::Main { sigpipe } = entry_type; let (start_fn, start_ty, args, instance) = { - let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None); + let start_def_id = cx.tcx().require_lang_item(LangItem::Start, DUMMY_SP); let start_instance = ty::Instance::expect_resolve( cx.tcx(), cx.typing_env(), diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index ef0d565333e..48565e0b4de 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -110,7 +110,7 @@ mod temp_stable_hash_impls { pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &Bx, - span: Option, + span: Span, li: LangItem, ) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) { let tcx = bx.tcx(); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1baab62ae43..bfc367f7a4d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; - let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), lang_item); + let (fn_abi, llfn, instance) = common::build_langcall(bx, span, lang_item); // Codegen the actual panic invoke/call. let merging_succ = @@ -803,7 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(bx, terminator.source_info); // Obtain the panic entry point. - let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), reason.lang_item()); + let (fn_abi, llfn, instance) = common::build_langcall(bx, span, reason.lang_item()); // Codegen the actual panic invoke/call. let merging_succ = helper.do_call( @@ -871,7 +871,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Obtain the panic entry point. let (fn_abi, llfn, instance) = - common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind); + common::build_langcall(bx, source_info.span, LangItem::PanicNounwind); // Codegen the actual panic invoke/call. Some(helper.do_call( @@ -1830,7 +1830,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span)); - let (fn_abi, fn_ptr, instance) = common::build_langcall(&bx, None, reason.lang_item()); + let (fn_abi, fn_ptr, instance) = + common::build_langcall(&bx, self.mir.span, reason.lang_item()); if is_call_from_compiler_builtins_to_upstream_monomorphization(bx.tcx(), instance) { bx.abort(); } else { diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index ac2366340fb..577012151e4 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -5,6 +5,7 @@ use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Ty}; +use rustc_span::DUMMY_SP; use tracing::{debug, trace}; use crate::common::IntPredicate; @@ -62,7 +63,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Obtain the panic entry point. let (fn_abi, llfn, _instance) = - common::build_langcall(bx, None, LangItem::PanicNounwind); + common::build_langcall(bx, DUMMY_SP, LangItem::PanicNounwind); // Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we // can't create a `TerminationCodegenHelper`. (But we are in good company, this code is diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index d701646719a..9c30dbff99e 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -345,11 +345,7 @@ fn build_error_for_const_call<'tcx>( non_or_conditionally, }); - note_trait_if_possible( - &mut err, - self_ty, - tcx.require_lang_item(LangItem::Deref, Some(span)), - ); + note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, span)); err } _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => { diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index dfcd1969a73..c1a37ab6a83 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -99,7 +99,7 @@ impl Qualif for HasMutInterior { // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error. // Instead we invoke an obligation context manually, and provide the opaque type inference settings // that allow the trait solver to just error out instead of cycling. - let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span)); + let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span); // FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR // typeck results without causing query cycles, we should use this here instead of defining // opaque types. @@ -180,7 +180,7 @@ impl Qualif for NeedsNonConstDrop { // that the components of this type are also `~const Destruct`. This // amounts to verifying that there are no values in this ADT that may have // a non-const drop. - let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); + let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, cx.body.span); let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 3922b33ea84..a68dcf29988 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -249,7 +249,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { return Err(ConstEvalErrKind::Panic { msg, file, line, col }).into(); } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) { // For panic_fmt, call const_panic_fmt instead. - let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None); + let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, self.tcx.span); let new_instance = ty::Instance::expect_resolve( *self.tcx, self.typing_env(), diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 39755169e6c..77667ba823a 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -12,6 +12,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug, ty}; +use rustc_span::DUMMY_SP; use tracing::trace; use super::{ @@ -307,7 +308,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self { // Can use any typing env, since `Ordering` is always monomorphic. - let ty = tcx.ty_ordering_enum(None); + let ty = tcx.ty_ordering_enum(DUMMY_SP); let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap(); Self::from_scalar(Scalar::Int(c.into()), layout) diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index e926040e9ba..9575bd43661 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -30,7 +30,7 @@ fn alloc_caller_location<'tcx>( // Allocate memory for `CallerLocation` struct. let loc_ty = ecx .tcx - .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, None)) + .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span)) .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()])); let loc_layout = ecx.layout_of(loc_ty).unwrap(); let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 846eacce9e1..77f6204d595 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -97,7 +97,7 @@ fn allowed_union_or_unsafe_field<'tcx>( let def_id = tcx .lang_items() .get(LangItem::BikeshedGuaranteedNoDrop) - .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, Some(span))); + .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span)); let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else { tcx.dcx().span_delayed_bug(span, "could not normalize field type"); return true; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 09610a2f3ec..234520c1583 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -180,7 +180,7 @@ pub(crate) fn check_intrinsic_type( ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv), ]); let mk_va_list_ty = |mutbl| { - let did = tcx.require_lang_item(LangItem::VaList, Some(span)); + let did = tcx.require_lang_item(LangItem::VaList, span); let region = ty::Region::new_bound( tcx, ty::INNERMOST, @@ -442,9 +442,7 @@ pub(crate) fn check_intrinsic_type( sym::bswap | sym::bitreverse => (1, 0, vec![param(0)], param(0)), - sym::three_way_compare => { - (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(Some(span))) - } + sym::three_way_compare => (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(span)), sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool])) @@ -520,7 +518,7 @@ pub(crate) fn check_intrinsic_type( sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( - tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + tcx.require_lang_item(hir::LangItem::DiscriminantKind, span), ); let discriminant_def_id = assoc_items[0]; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3e872607e31..237b8ae8b89 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -969,7 +969,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::UnsizedConstParamTy, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::UnsizedConstParamTy, hir_ty.span), ); Ok(()) }) @@ -983,7 +983,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::ConstParamTy, hir_ty.span), ); Ok(()) }) @@ -1232,7 +1232,7 @@ fn check_type_defn<'tcx>( ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::Sized, hir_ty.span), ); } @@ -1356,7 +1356,7 @@ fn check_static_item( ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sized, Some(ty_span)), + tcx.require_lang_item(LangItem::Sized, ty_span), ); } @@ -1375,7 +1375,7 @@ fn check_static_item( ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sync, Some(ty_span)), + tcx.require_lang_item(LangItem::Sync, ty_span), ); } Ok(()) @@ -1401,7 +1401,7 @@ fn check_const_item( ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, ty_span), ); check_where_clauses(wfcx, item_span, def_id); @@ -1725,13 +1725,13 @@ fn check_fn_or_method<'tcx>( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), wfcx.param_env, *ty, - tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), + tcx.require_lang_item(hir::LangItem::Tuple, span), ); wfcx.register_bound( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), wfcx.param_env, *ty, - tcx.require_lang_item(hir::LangItem::Sized, Some(span)), + tcx.require_lang_item(hir::LangItem::Sized, span), ); } else { tcx.dcx().span_err( @@ -1776,7 +1776,7 @@ fn check_sized_if_body<'tcx>( ObligationCause::new(span, def_id, code), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, Some(span)), + tcx.require_lang_item(LangItem::Sized, span), ); } } @@ -2013,7 +2013,7 @@ fn receiver_is_valid<'tcx>( // deref chain implement `LegacyReceiver`. if arbitrary_self_types_enabled.is_none() { let legacy_receiver_trait_def_id = - tcx.require_lang_item(LangItem::LegacyReceiver, Some(span)); + tcx.require_lang_item(LangItem::LegacyReceiver, span); if !legacy_receiver_is_implemented( wfcx, legacy_receiver_trait_def_id, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b92d1d7104f..4779f4fb702 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -225,7 +225,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() // redundant errors for `DispatchFromDyn`. This is best effort, though. let mut res = Ok(()); tcx.for_each_relevant_impl( - tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + tcx.require_lang_item(LangItem::CoerceUnsized, span), source, |impl_def_id| { res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id)); @@ -379,8 +379,8 @@ pub(crate) fn coerce_unsized_info<'tcx>( let span = tcx.def_span(impl_did); let trait_name = "CoerceUnsized"; - let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); - let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); + let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span); + let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span); let source = tcx.type_of(impl_did).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity(); @@ -591,7 +591,7 @@ fn infringing_fields_error<'tcx>( impl_did: LocalDefId, impl_span: Span, ) -> ErrorGuaranteed { - let trait_did = tcx.require_lang_item(lang_item, Some(impl_span)); + let trait_did = tcx.require_lang_item(lang_item, impl_span); let trait_name = tcx.def_path_str(trait_did); @@ -748,7 +748,7 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err ObligationCause::misc(impl_span, checker.impl_def_id), param_env, nontrivial_field_ty, - tcx.require_lang_item(LangItem::PointerLike, Some(impl_span)), + tcx.require_lang_item(LangItem::PointerLike, impl_span), ); // FIXME(dyn-star): We should regionck this implementation. if ocx.select_all_or_error().is_empty() { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2a37a8bdbd4..4c65d0d0510 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2590,7 +2590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => { - let def_id = tcx.require_lang_item(lang_item, Some(span)); + let def_id = tcx.require_lang_item(lang_item, span); let (args, _) = self.lower_generic_args_of_path( span, def_id, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index f555d116c52..d173fe7c2c2 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -508,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(ty) = fn_sig.inputs().last().copied() { self.register_bound( ty, - self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)), + self.tcx.require_lang_item(hir::LangItem::Tuple, sp), self.cause(sp, ObligationCauseCode::RustCall), ); self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 99103f14d68..ac42eebf08c 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -57,7 +57,7 @@ pub(super) fn check_fn<'a, 'tcx>( // (as it's created inside the body itself, not passed in from outside). let maybe_va_list = fn_sig.c_variadic.then(|| { let span = body.params.last().unwrap().span; - let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); + let va_list_did = tcx.require_lang_item(LangItem::VaList, span); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]) @@ -178,7 +178,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_> tcx.dcx().span_err(span, "should have no const parameters"); } - let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span)); + let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span); // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` let panic_info_ty = tcx.type_of(panic_info_did).instantiate( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index cd3746be1d1..459c0498d50 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -142,13 +142,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_adt( tcx, - tcx.adt_def( - tcx.require_lang_item(hir::LangItem::Poll, Some(expr_span)), - ), + tcx.adt_def(tcx.require_lang_item(hir::LangItem::Poll, expr_span)), tcx.mk_args(&[Ty::new_adt( tcx, tcx.adt_def( - tcx.require_lang_item(hir::LangItem::Option, Some(expr_span)), + tcx.require_lang_item(hir::LangItem::Option, expr_span), ), tcx.mk_args(&[yield_ty.into()]), ) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ddc80fab2ce..d9fa56fefeb 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -760,8 +760,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.param_env, ty::TraitRef::new( self.tcx, - self.tcx - .require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), + self.tcx.require_lang_item(hir::LangItem::PointerLike, self.cause.span), [a], ), ), @@ -1969,7 +1968,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.param_env, ty::TraitRef::new( fcx.tcx, - fcx.tcx.require_lang_item(hir::LangItem::Sized, None), + fcx.tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP), [sig.output()], ), )) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 082ddac7e5a..b17d5977e06 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1407,7 +1407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_deref_ty_is_sized = self .infcx .type_implements_trait( - self.tcx.require_lang_item(LangItem::Sized, None), + self.tcx.require_lang_item(LangItem::Sized, span), [lhs_deref_ty], self.param_env, ) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 362c7d8efac..8a90e768d70 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { code: traits::ObligationCauseCode<'tcx>, ) { if !ty.references_error() { - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, span); self.require_type_meets(ty, span, code, lang_item); } } @@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Nothing else is required here. } else { // We can't be sure, let's required full `Sized`. - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, span); self.require_type_meets(ty, span, ObligationCauseCode::Misc, lang_item); } } @@ -732,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, hir_id: HirId, ) -> (Res, Ty<'tcx>) { - let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_id = self.tcx.require_lang_item(lang_item, span); let def_kind = self.tcx.def_kind(def_id); let item_ty = if let DefKind::Variant = def_kind { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 59aba6fae5e..95c7f251c88 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => traits::IsConstable::No, }; - let lang_item = self.tcx.require_lang_item(LangItem::Copy, None); + let lang_item = self.tcx.require_lang_item(LangItem::Copy, element.span); let code = traits::ObligationCauseCode::RepeatElementCopy { is_constable, elt_span: element.span, @@ -1680,8 +1680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast::LitKind::CStr(_, _) => Ty::new_imm_ref( tcx, tcx.lifetimes.re_static, - tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span))) - .skip_binder(), + tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, lit.span)).skip_binder(), ), ast::LitKind::Err(guar) => Ty::new_error(tcx, guar), } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1c3bc338d85..66af085cfd4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2679,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut sugg_sp = sp; if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind { let clone_trait = - self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span)); + self.tcx.require_lang_item(LangItem::Clone, segment.ident.span); if args.is_empty() && self .typeck_results diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 17d48184dd9..432eeae8016 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if *negated { self.register_bound( ty, - self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)), + self.tcx.require_lang_item(LangItem::Neg, lt.span), ObligationCause::dummy_with_span(lt.span), ); } @@ -2553,13 +2553,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; self.register_bound( source_ty, - tcx.require_lang_item(hir::LangItem::DerefPure, Some(span)), + tcx.require_lang_item(hir::LangItem::DerefPure, span), self.misc(span), ); // The expected type for the deref pat's inner pattern is `::Target`. let target_ty = Ty::new_projection( tcx, - tcx.require_lang_item(hir::LangItem::DerefTarget, Some(span)), + tcx.require_lang_item(hir::LangItem::DerefTarget, span), [source_ty], ); let target_ty = self.normalize(span, target_ty); @@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for mutably_derefed_ty in derefed_tys { self.register_bound( mutably_derefed_ty, - self.tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)), + self.tcx.require_lang_item(hir::LangItem::DerefMut, span), self.misc(span), ); } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4b2e87f5674..5b5253c7e7e 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let is_drop_defined_for_ty = |ty: Ty<'tcx>| { - let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); + let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, closure_span); self.infcx .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id)) .must_apply_modulo_regions() diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 47b80135bae..69e9f8e1b2c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -39,7 +39,7 @@ pub use rustc_session::lint::builtin::*; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; -use rustc_span::{BytePos, Ident, InnerSpan, Span, Symbol, kw, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym}; use rustc_target::asm::InlineAsmArch; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; @@ -635,7 +635,8 @@ fn type_implements_negative_copy_modulo_regions<'tcx>( typing_env: ty::TypingEnv<'tcx>, ) -> bool { let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); - let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, DUMMY_SP), [ty]); let pred = ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative }; let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index bd315577efb..6c6b12fed67 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -95,7 +95,7 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { #[diag(middle_requires_lang_item)] pub(crate) struct RequiresLangItem { #[primary_span] - pub span: Option, + pub span: Span, pub name: Symbol, } diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 0f92c1910f1..93264f02cc2 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -17,7 +17,7 @@ use crate::ty::{self, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { /// Returns the `DefId` for a given `LangItem`. /// If not found, fatally aborts compilation. - pub fn require_lang_item(self, lang_item: LangItem, span: Option) -> DefId { + pub fn require_lang_item(self, lang_item: LangItem, span: Span) -> DefId { self.lang_items().get(lang_item).unwrap_or_else(|| { self.dcx().emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() }); }) diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 06e41e64fdc..d98b40f0fcf 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -835,7 +835,7 @@ impl<'tcx> BinOp { &BinOp::Cmp => { // these should be integer-like types of the same size. assert_eq!(lhs_ty, rhs_ty); - tcx.ty_ordering_enum(None) + tcx.ty_ordering_enum(DUMMY_SP) } } } diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index a61a6c571a2..3bacdfe5ac8 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -128,8 +128,8 @@ impl OverloadedDeref { /// for this overloaded deref's mutability. pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId { let trait_def_id = match self.mutbl { - hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), - hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), + hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, self.span), + hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, self.span), }; tcx.associated_items(trait_def_id) .in_definition_order() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 57b20a1bba6..0b1e9852d2a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -458,7 +458,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId { - self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None) + self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP) } fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool { @@ -1710,7 +1710,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Gets a `Ty` representing the [`LangItem::OrderingEnum`] #[track_caller] - pub fn ty_ordering_enum(self, span: Option) -> Ty<'tcx> { + pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> { let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span); self.type_of(ordering_enum).no_bound_vars().unwrap() } @@ -2253,7 +2253,7 @@ impl<'tcx> TyCtxt<'tcx> { Ty::new_imm_ref( self, self.lifetimes.re_static, - self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) + self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP)) .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])), ) } @@ -2712,7 +2712,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given a `ty`, return whether it's an `impl Future<...>`. pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; - let future_trait = self.require_lang_item(LangItem::Future, None); + let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP); self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0d99a1b5149..5ba4e5446e9 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -786,7 +786,7 @@ impl<'tcx> Instance<'tcx> { } pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { - let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); + let def_id = tcx.require_lang_item(LangItem::DropInPlace, DUMMY_SP); let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, @@ -798,7 +798,7 @@ impl<'tcx> Instance<'tcx> { } pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { - let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None); + let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, DUMMY_SP); let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, @@ -824,7 +824,7 @@ impl<'tcx> Instance<'tcx> { closure_did: DefId, args: ty::GenericArgsRef<'tcx>, ) -> Instance<'tcx> { - let fn_once = tcx.require_lang_item(LangItem::FnOnce, None); + let fn_once = tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP); let call_once = tcx .associated_items(fn_once) .in_definition_order() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 404674c359e..cbf545c01c5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -593,7 +593,7 @@ impl<'tcx> Ty<'tcx> { ty: Ty<'tcx>, mutbl: ty::Mutability, ) -> Ty<'tcx> { - let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None)); + let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, DUMMY_SP)); Ty::new_adt(tcx, pin, tcx.mk_args(&[Ty::new_ref(tcx, r, ty, mutbl).into()])) } @@ -857,19 +857,19 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = tcx.require_lang_item(LangItem::OwnedBox, None); + let def_id = tcx.require_lang_item(LangItem::OwnedBox, DUMMY_SP); Ty::new_generic_adt(tcx, def_id, ty) } #[inline] pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None); + let def_id = tcx.require_lang_item(LangItem::MaybeUninit, DUMMY_SP); Ty::new_generic_adt(tcx, def_id, ty) } /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes. pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - let context_did = tcx.require_lang_item(LangItem::Context, None); + let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP); let context_adt_ref = tcx.adt_def(context_did); let context_args = tcx.mk_args(&[tcx.lifetimes.re_erased.into()]); let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args); @@ -1549,7 +1549,7 @@ impl<'tcx> Ty<'tcx> { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { let assoc_items = tcx.associated_item_def_ids( - tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + tcx.require_lang_item(hir::LangItem::DiscriminantKind, DUMMY_SP), ); Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()])) } @@ -1629,7 +1629,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => Ok(tcx.types.usize), ty::Dynamic(_, _, ty::Dyn) => { - let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP); Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()])) } @@ -1683,7 +1683,7 @@ impl<'tcx> Ty<'tcx> { match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) { Ok(metadata_ty) => metadata_ty, Err(tail_ty) => { - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, DUMMY_SP); Ty::new_projection(tcx, metadata_def_id, [tail_ty]) } } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 5a97b08db28..b23bc089cd4 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // malloc some memory of suitable size and align: let exchange_malloc = Operand::function_handle( tcx, - tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)), + tcx.require_lang_item(LangItem::ExchangeMalloc, expr_span), [], expr_span, ); diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index a9a07997410..2074fbce0ae 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -307,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) { // Convert `expr.use` to a call like `Clone::clone(&expr)` let success = this.cfg.start_new_block(); - let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); + let clone_trait = this.tcx.require_lang_item(LangItem::Clone, span); let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 210b9cce581..a4609a6053e 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let borrow_kind = super::util::ref_pat_borrow_kind(mutability); let source_info = self.source_info(span); let re_erased = self.tcx.lifetimes.re_erased; - let trait_item = self.tcx.require_lang_item(trait_item, None); + let trait_item = self.tcx.require_lang_item(trait_item, span); let method = trait_method(self.tcx, trait_item, method, [ty]); let ref_src = self.temp(Ty::new_ref(self.tcx, re_erased, ty, mutability), span); // `let ref_src = &src_place;` @@ -437,7 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { val: Operand<'tcx>, ) { let str_ty = self.tcx.types.str_; - let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); + let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, source_info.span); let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]); let bool_ty = self.tcx.types.bool; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 226dc920a49..03448933fa9 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -220,7 +220,7 @@ impl<'tcx> ThirBuildCx<'tcx> { }); // kind = Pin { __pointer: pointer } - let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span)); + let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span); let args = self.tcx.mk_args(&[new_pin_target.into()]); let kind = ExprKind::Adt(Box::new(AdtExpr { adt_def: self.tcx.adt_def(pin_did), diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 8c817605847..24d4136c642 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -189,7 +189,7 @@ impl<'tcx> ThirBuildCx<'tcx> { // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() { - let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span)); + let va_list_did = self.tcx.require_lang_item(LangItem::VaList, param.span); self.tcx .type_of(va_list_did) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 84a0190a7fa..003ad170861 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{mir, span_bug}; use rustc_span::def_id::DefId; -use rustc_span::{Span, sym}; +use rustc_span::{DUMMY_SP, Span, sym}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; @@ -480,8 +480,9 @@ fn type_has_partial_eq_impl<'tcx>( // (If there isn't, then we can safely issue a hard // error, because that's never worked, due to compiler // using `PartialEq::eq` in this scenario in the past.) - let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None); - let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None); + let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, DUMMY_SP); + let structural_partial_eq_trait_id = + tcx.require_lang_item(hir::LangItem::StructuralPeq, DUMMY_SP); let partial_eq_obligation = Obligation::new( tcx, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index cddb2f84778..d5d0d56f528 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -225,7 +225,7 @@ impl<'tcx> TransformVisitor<'tcx> { CoroutineKind::Coroutine(_) => span_bug!(body.span, "`Coroutine`s cannot be fused"), // `gen` continues return `None` CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { - let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); + let option_def_id = self.tcx.require_lang_item(LangItem::Option, body.span); make_aggregate_adt( option_def_id, VariantIdx::ZERO, @@ -242,7 +242,7 @@ impl<'tcx> TransformVisitor<'tcx> { span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - self.tcx.require_lang_item(LangItem::AsyncGenFinished, None), + self.tcx.require_lang_item(LangItem::AsyncGenFinished, body.span), self.tcx.mk_args(&[yield_ty.into()]), ), self.old_yield_ty, @@ -282,7 +282,7 @@ impl<'tcx> TransformVisitor<'tcx> { const ONE: VariantIdx = VariantIdx::from_usize(1); let rvalue = match self.coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { - let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None); + let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, source_info.span); let args = self.tcx.mk_args(&[self.old_ret_ty.into()]); let (variant_idx, operands) = if is_return { (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val) @@ -292,7 +292,7 @@ impl<'tcx> TransformVisitor<'tcx> { make_aggregate_adt(poll_def_id, variant_idx, args, operands) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { - let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); + let option_def_id = self.tcx.require_lang_item(LangItem::Option, source_info.span); let args = self.tcx.mk_args(&[self.old_yield_ty.into()]); let (variant_idx, operands) = if is_return { (ZERO, IndexVec::new()) // None @@ -310,7 +310,10 @@ impl<'tcx> TransformVisitor<'tcx> { span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - self.tcx.require_lang_item(LangItem::AsyncGenFinished, None), + self.tcx.require_lang_item( + LangItem::AsyncGenFinished, + source_info.span, + ), self.tcx.mk_args(&[yield_ty.into()]), ), self.old_yield_ty, @@ -323,7 +326,7 @@ impl<'tcx> TransformVisitor<'tcx> { } CoroutineKind::Coroutine(_) => { let coroutine_state_def_id = - self.tcx.require_lang_item(LangItem::CoroutineState, None); + self.tcx.require_lang_item(LangItem::CoroutineState, source_info.span); let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]); let variant_idx = if is_return { ONE // CoroutineState::Complete(val) @@ -496,7 +499,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let ref_coroutine_ty = body.local_decls.raw[1].ty; - let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span)); + let pin_did = tcx.require_lang_item(LangItem::Pin, body.span); let pin_adt_ref = tcx.adt_def(pin_did); let args = tcx.mk_args(&[ref_coroutine_ty.into()]); let pin_ref_coroutine_ty = Ty::new_adt(tcx, pin_adt_ref, args); @@ -557,7 +560,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty // replace the type of the `resume` argument replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref); - let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None); + let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, body.span); for bb in body.basic_blocks.indices() { let bb_data = &body[bb]; @@ -618,7 +621,7 @@ fn replace_resume_ty_local<'tcx>( #[cfg(debug_assertions)] { if let ty::Adt(resume_ty_adt, _) = local_ty.kind() { - let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", local_ty); @@ -1095,7 +1098,7 @@ fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> { // Poll::Ready(()) - let poll_def_id = tcx.require_lang_item(LangItem::Poll, None); + let poll_def_id = tcx.require_lang_item(LangItem::Poll, source_info.span); let args = tcx.mk_args(&[tcx.types.unit.into()]); let val = Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -1437,7 +1440,7 @@ fn check_field_tys_sized<'tcx>( ), param_env, field_ty.ty, - tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)), + tcx.require_lang_item(hir::LangItem::Sized, field_ty.source_info.span), ); } @@ -1473,14 +1476,14 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { let new_ret_ty = match coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { // Compute Poll - let poll_did = tcx.require_lang_item(LangItem::Poll, None); + let poll_did = tcx.require_lang_item(LangItem::Poll, body.span); let poll_adt_ref = tcx.adt_def(poll_did); let poll_args = tcx.mk_args(&[old_ret_ty.into()]); Ty::new_adt(tcx, poll_adt_ref, poll_args) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { // Compute Option - let option_did = tcx.require_lang_item(LangItem::Option, None); + let option_did = tcx.require_lang_item(LangItem::Option, body.span); let option_adt_ref = tcx.adt_def(option_did); let option_args = tcx.mk_args(&[old_yield_ty.into()]); Ty::new_adt(tcx, option_adt_ref, option_args) @@ -1491,7 +1494,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { } CoroutineKind::Coroutine(_) => { // Compute CoroutineState - let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); + let state_did = tcx.require_lang_item(LangItem::CoroutineState, body.span); let state_adt_ref = tcx.adt_def(state_did); let state_args = tcx.mk_args(&[old_yield_ty.into(), old_ret_ty.into()]); Ty::new_adt(tcx, state_adt_ref, state_args) diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 625e53f9959..6021e795d21 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -42,7 +42,7 @@ fn build_poll_call<'tcx>( context_ref_place: &Place<'tcx>, unwind: UnwindAction, ) -> BasicBlock { - let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, DUMMY_SP); let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]); let poll_fn = Operand::Constant(Box::new(ConstOperand { span: DUMMY_SP, @@ -77,11 +77,8 @@ fn build_pin_fut<'tcx>( let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty); let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span))); - let pin_fut_new_unchecked_fn = Ty::new_fn_def( - tcx, - tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), - [fut_ref_ty], - ); + let pin_fut_new_unchecked_fn = + Ty::new_fn_def(tcx, tcx.require_lang_item(LangItem::PinNewUnchecked, span), [fut_ref_ty]); let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder(); let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span))); let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { @@ -143,13 +140,15 @@ fn build_poll_switch<'tcx>( let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum .discriminant_for_variant( tcx, - poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, None)), + poll_enum_adt + .variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, DUMMY_SP)), ) .unwrap(); let poll_pending_discr = poll_enum .discriminant_for_variant( tcx, - poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, None)), + poll_enum_adt + .variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, DUMMY_SP)), ) .unwrap() .val; @@ -316,16 +315,17 @@ pub(super) fn expand_async_drops<'tcx>( // pending => return rv (yield) // ready => *continue_bb|drop_bb* + let source_info = body[bb].terminator.as_ref().unwrap().source_info; + // Compute Poll<> (aka Poll with void return) - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); - let poll_decl = LocalDecl::new(poll_enum, body.span); + let poll_decl = LocalDecl::new(poll_enum, source_info.span); let poll_unit_place = Place::from(body.local_decls.push(poll_decl)); // First state-loop yield for mainline let context_ref_place = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); - let source_info = body[bb].terminator.as_ref().unwrap().source_info; + Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span))); let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG))); body[bb].statements.push(Statement { source_info, @@ -353,8 +353,9 @@ pub(super) fn expand_async_drops<'tcx>( let mut dropline_context_ref: Option> = None; let mut dropline_call_bb: Option = None; if !is_dropline_bb { - let context_ref_place2: Place<'_> = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); + let context_ref_place2: Place<'_> = Place::from( + body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)), + ); let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield let drop_switch_block = build_poll_switch( tcx, @@ -394,7 +395,7 @@ pub(super) fn expand_async_drops<'tcx>( span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - tcx.require_lang_item(LangItem::AsyncGenPending, None), + tcx.require_lang_item(LangItem::AsyncGenPending, source_info.span), tcx.mk_args(&[yield_ty.into()]), ), full_yield_ty, @@ -404,7 +405,7 @@ pub(super) fn expand_async_drops<'tcx>( } else { // value needed only for return-yields or gen-coroutines, so just const here Operand::Constant(Box::new(ConstOperand { - span: body.span, + span: source_info.span, user_ty: None, const_: Const::from_bool(tcx, false), })) @@ -595,7 +596,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( // Update the body's def to become the drop glue. let coroutine_instance = body.source.instance; - let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); + let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, body.span); let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty)); // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible @@ -666,7 +667,7 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>( } // Replace the return variable: Poll to Poll<()> - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); @@ -717,7 +718,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( let source_info = SourceInfo::outermost(body.span); // Replace the return variable: Poll to Poll<()> - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c15d7d6f732..3a5e2620b14 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -235,11 +235,8 @@ where let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only { // Resolving obj.() - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::AsyncDrop, Some(span)), - [drop_ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::AsyncDrop, span), [drop_ty]); let (drop_trait, trait_args) = match tcx.codegen_select_candidate( ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref), ) { @@ -292,7 +289,7 @@ where (sig.output(), drop_fn_def_id, trait_args) } else { // Resolving async_drop_in_place function for drop_ty - let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, Some(span)); + let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span); let trait_args = tcx.mk_args(&[drop_ty.into()]); let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args); let sig = tcx.instantiate_bound_regions_with_erased(sig); @@ -319,7 +316,7 @@ where // pin_obj_place preparation let pin_obj_new_unchecked_fn = Ty::new_fn_def( tcx, - tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), + tcx.require_lang_item(LangItem::PinNewUnchecked, span), [GenericArg::from(obj_ref_ty)], ); let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap(); @@ -937,7 +934,7 @@ where fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock { debug!("destructor_call_block_sync({:?}, {:?})", self, succ); let tcx = self.tcx(); - let drop_trait = tcx.require_lang_item(LangItem::Drop, None); + let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 9688ac8ed2e..6d45bbc6e16 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -98,7 +98,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) } ty::InstanceKind::ClosureOnceShim { call_once: _, track_caller: _ } => { - let fn_mut = tcx.require_lang_item(LangItem::FnMut, None); + let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) .in_definition_order() diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index fbc8ee9b06c..fd7b7362cd9 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -64,7 +64,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env); let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env); - let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty()); let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig( @@ -220,7 +220,7 @@ fn build_adrop_for_coroutine_shim<'tcx>( body.source.instance = instance; body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); - let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, Some(span))); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let args = tcx.mk_args(&[proxy_ref.into()]); let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args); @@ -308,10 +308,10 @@ fn build_adrop_for_adrop_shim<'tcx>( let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); // ret_ty = `Poll<()>` - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, span)); let ret_ty = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); // env_ty = `Pin<&mut proxy_ty>` - let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None)); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()])); // sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>` let sig = tcx.mk_fn_sig( @@ -376,7 +376,7 @@ fn build_adrop_for_adrop_shim<'tcx>( let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()])); let cor_pin_place = Place::from(locals.push(LocalDecl::new(cor_pin_ty, span))); - let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)); + let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span); // call Pin::new_unchecked(&mut impl_cor) blocks.push(BasicBlockData { statements, @@ -396,7 +396,7 @@ fn build_adrop_for_adrop_shim<'tcx>( }); // When dropping async drop coroutine, we continue its execution: // we call impl::poll (impl_layout, ctx) - let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span); let resume_ctx = Place::from(Local::new(2)); blocks.push(BasicBlockData { statements: vec![], diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index c8aa7588d03..fd91508cc11 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.tcx, self.tcx.require_lang_item( LangItem::CoerceUnsized, - Some(self.body.source_info(location).span), + self.body.source_info(location).span, ), [op_ty, *target_type], )) { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1ee977a5457..173030e0326 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -781,7 +781,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { let tcx = self.tcx; let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| { - let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source))); + let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, source)); if tcx.should_codegen_locally(instance) { this.used_items.push(create_fn_mono_item(tcx, instance, source)); } @@ -921,7 +921,7 @@ fn visit_instance_use<'tcx>( // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to // codegen a call to that function without generating code for the function itself. - let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None); + let def_id = tcx.require_lang_item(LangItem::PanicNounwind, source); let panic_instance = Instance::mono(tcx, def_id); if tcx.should_codegen_locally(panic_instance) { output.push(create_fn_mono_item(tcx, panic_instance, source)); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5c66017bc61..05683940cba 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( ) -> Result { let trait_ref = ty::TraitRef::new( tcx.tcx, - tcx.require_lang_item(LangItem::CoerceUnsized, Some(tcx.span)), + tcx.require_lang_item(LangItem::CoerceUnsized, tcx.span), [source_ty, target_ty], ); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index d2917478e4e..c69991f3fb2 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{ TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, }; use rustc_span::def_id::DefId; -use rustc_span::sym; +use rustc_span::{DUMMY_SP, sym}; use rustc_trait_selection::traits; use tracing::{debug, instrument}; @@ -414,7 +414,7 @@ pub(crate) fn transform_instance<'tcx>( } ty::Coroutine(..) => match tcx.coroutine_kind(instance.def_id()).unwrap() { hir::CoroutineKind::Coroutine(..) => ( - tcx.require_lang_item(LangItem::Coroutine, None), + tcx.require_lang_item(LangItem::Coroutine, DUMMY_SP), Some(instance.args.as_coroutine().resume_ty()), ), hir::CoroutineKind::Desugared(desugaring, _) => { @@ -423,11 +423,11 @@ pub(crate) fn transform_instance<'tcx>( hir::CoroutineDesugaring::AsyncGen => LangItem::AsyncIterator, hir::CoroutineDesugaring::Gen => LangItem::Iterator, }; - (tcx.require_lang_item(lang_item, None), None) + (tcx.require_lang_item(lang_item, DUMMY_SP), None) } }, ty::CoroutineClosure(..) => ( - tcx.require_lang_item(LangItem::FnOnce, None), + tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP), Some( tcx.instantiate_bound_regions_with_erased( instance.args.as_coroutine_closure().coroutine_closure_sig(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 8e2137da655..2c16672d786 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -73,7 +73,7 @@ use rustc_middle::ty::{ TypeVisitableExt, }; use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::{BytePos, DesugaringKind, Pos, Span, sym}; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym}; use tracing::{debug, instrument}; use crate::error_reporting::TypeErrCtxt; @@ -194,7 +194,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => return None, }; - let future_trait = self.tcx.require_lang_item(LangItem::Future, None); + let future_trait = self.tcx.require_lang_item(LangItem::Future, DUMMY_SP); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; self.tcx diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index d8b405e904c..8a67e4ccd45 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -6,7 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, lang_items}; use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; -use rustc_span::{DesugaringKind, Ident, Span, sym}; +use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym}; use tracing::debug; use crate::traits::specialization_graph; @@ -31,9 +31,9 @@ impl CallDesugaringKind { pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), - Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, None), + Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, DUMMY_SP), Self::QuestionBranch | Self::TryBlockFromOutput => { - tcx.require_lang_item(LangItem::Try, None) + tcx.require_lang_item(LangItem::Try, DUMMY_SP) } Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(), Self::Await => tcx.get_diagnostic_item(sym::IntoFuture).unwrap(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 9c301373cf9..3b7fd8b7a20 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -955,7 +955,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; }; - let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); + let clone_trait = self.tcx.require_lang_item(LangItem::Clone, obligation.cause.span); let has_clone = |ty| { self.type_implements_trait(clone_trait, [ty], obligation.param_env) .must_apply_modulo_regions() @@ -3625,7 +3625,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, span: Span, ) { - let future_trait = self.tcx.require_lang_item(LangItem::Future, None); + let future_trait = self.tcx.require_lang_item(LangItem::Future, span); let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let impls_future = self.type_implements_trait( @@ -4141,7 +4141,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let pred = ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Clone, Some(span)), + tcx.require_lang_item(LangItem::Clone, span), [*ty], ), polarity: ty::PredicatePolarity::Positive, diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0dab3adadb0..0118321befb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -38,7 +38,7 @@ impl<'tcx> InferCtxt<'tcx> { return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty); } - let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None); + let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, DUMMY_SP); // This can get called from typeck (by euv), and `moves_by_default` // rightly refuses to work with inference variables, but @@ -49,7 +49,7 @@ impl<'tcx> InferCtxt<'tcx> { fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { let ty = self.resolve_vars_if_possible(ty); - let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, None); + let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id) } @@ -59,12 +59,12 @@ impl<'tcx> InferCtxt<'tcx> { ty: Ty<'tcx>, ) -> bool { let ty = self.resolve_vars_if_possible(ty); - let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None); + let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id) } fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item) } diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index cc5861b5a1f..e77d9e32cb9 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -248,7 +248,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( obligation: &HostEffectObligation<'tcx>, ) -> Result>, EvaluationFailure> { let tcx = selcx.tcx(); - let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, None); + let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, obligation.cause.span); let self_ty = obligation.predicate.self_ty(); let const_conditions = match *self_ty.kind() { @@ -267,7 +267,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( Some(hir::Constness::NotConst) => return Err(EvaluationFailure::NoSolution), // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold. Some(hir::Constness::Const) => { - let drop_def_id = tcx.require_lang_item(LangItem::Drop, None); + let drop_def_id = tcx.require_lang_item(LangItem::Drop, obligation.cause.span); let drop_trait_ref = ty::TraitRef::new(tcx, drop_def_id, [self_ty]); const_conditions.push(drop_trait_ref); } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index a4b6f330b9d..393f458bea2 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -157,7 +157,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( parent_cause.clone(), param_env, inner_ty, - tcx.require_lang_item(lang_item, Some(parent_cause.span)), + tcx.require_lang_item(lang_item, parent_cause.span), ); let errors = ocx.select_all_or_error(); @@ -193,7 +193,7 @@ pub fn all_fields_implement_trait<'tcx>( parent_cause: ObligationCause<'tcx>, lang_item: LangItem, ) -> Result<(), Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>> { - let trait_def_id = tcx.require_lang_item(lang_item, Some(parent_cause.span)); + let trait_def_id = tcx.require_lang_item(lang_item, parent_cause.span); let mut infringing = Vec::new(); for variant in adt.variants() { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index ed0f34b5aa9..6dd80551980 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1117,7 +1117,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.tcx(), selcx.tcx().require_lang_item( LangItem::Sized, - Some(obligation.cause.span), + obligation.cause.span, ), [self_ty], ), @@ -1317,7 +1317,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); - let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, None); + let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, obligation.cause.span); let (trait_ref, yield_ty, return_ty) = super::util::coroutine_trait_ref_and_outputs( tcx, @@ -1375,7 +1375,7 @@ fn confirm_future_candidate<'cx, 'tcx>( debug!(?obligation, ?coroutine_sig, ?obligations, "confirm_future_candidate"); let tcx = selcx.tcx(); - let fut_def_id = tcx.require_lang_item(LangItem::Future, None); + let fut_def_id = tcx.require_lang_item(LangItem::Future, obligation.cause.span); let (trait_ref, return_ty) = super::util::future_trait_ref_and_outputs( tcx, @@ -1421,7 +1421,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( debug!(?obligation, ?gen_sig, ?obligations, "confirm_iterator_candidate"); let tcx = selcx.tcx(); - let iter_def_id = tcx.require_lang_item(LangItem::Iterator, None); + let iter_def_id = tcx.require_lang_item(LangItem::Iterator, obligation.cause.span); let (trait_ref, yield_ty) = super::util::iterator_trait_ref_and_outputs( tcx, @@ -1467,7 +1467,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( debug!(?obligation, ?gen_sig, ?obligations, "confirm_async_iterator_candidate"); let tcx = selcx.tcx(); - let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, None); + let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, obligation.cause.span); let (trait_ref, yield_ty) = super::util::async_iterator_trait_ref_and_outputs( tcx, @@ -1511,12 +1511,13 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); let args = tcx.mk_args(&[self_ty.into()]); let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) { - let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); + let discriminant_def_id = + tcx.require_lang_item(LangItem::Discriminant, obligation.cause.span); assert_eq!(discriminant_def_id, item_def_id); (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, obligation.cause.span); assert_eq!(metadata_def_id, item_def_id); let mut obligations = PredicateObligations::new(); @@ -1538,7 +1539,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( // exist. Instead, `Pointee` should be a supertrait of `Sized`. let sized_predicate = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Sized, obligation.cause.span), [self_ty], ); obligations.push(obligation.with(tcx, sized_predicate)); @@ -1620,7 +1621,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( ) } else { let upvars_projection_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); + tcx.require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span); let tupled_upvars_ty = Ty::new_projection( tcx, upvars_projection_def_id, @@ -1681,8 +1682,9 @@ fn confirm_callable_candidate<'cx, 'tcx>( debug!(?obligation, ?fn_sig, "confirm_callable_candidate"); - let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, None); - let fn_once_output_def_id = tcx.require_lang_item(LangItem::FnOnceOutput, None); + let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, obligation.cause.span); + let fn_once_output_def_id = + tcx.require_lang_item(LangItem::FnOnceOutput, obligation.cause.span); let predicate = super::util::closure_trait_ref_and_return_type( tcx, @@ -1740,8 +1742,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( args.coroutine_captures_by_ref_ty(), ) } else { - let upvars_projection_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); + let upvars_projection_def_id = tcx + .require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span); // When we don't know the closure kind (and therefore also the closure's upvars, // which are computed at the same time), we must delay the computation of the // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait @@ -1798,7 +1800,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), @@ -1831,7 +1834,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c9169127e0b..7acf0f990d1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -318,7 +318,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let make_freeze_obl = |ty| { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Freeze, None), + tcx.require_lang_item(LangItem::Freeze, obligation.cause.span), [ty::GenericArg::from(ty)], ); Obligation::with_depth( @@ -657,7 +657,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let tr = ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)), + self.tcx().require_lang_item(LangItem::Sized, cause.span), [output_ty], ); nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr)); @@ -877,14 +877,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); // We must additionally check that the return type impls `Future + Sized`. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = + tcx.require_lang_item(LangItem::Future, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { ty::TraitRef::new(tcx, future_trait_def_id, [output_ty]) }), )); - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = + tcx.require_lang_item(LangItem::Sized, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { @@ -906,13 +908,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); // We must additionally check that the return type impls `Future + Sized`. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = + tcx.require_lang_item(LangItem::Future, obligation.cause.span); let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]), )); - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = + tcx.require_lang_item(LangItem::Sized, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { @@ -946,10 +950,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item( - LangItem::AsyncFnKindHelper, - Some(obligation.cause.span), - ), + self.tcx() + .require_lang_item(LangItem::AsyncFnKindHelper, obligation.cause.span), [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)], ), )); @@ -1165,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can only make objects from sized types. let tr = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Sized, obligation.cause.span), [source], ); nested.push(predicate_to_obligation(tr.upcast(tcx))); @@ -1359,7 +1361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self_ty.map_bound(|ty| { ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Copy, obligation.cause.span), [ty], ) }), @@ -1411,7 +1413,7 @@ fn pointer_like_goal_for_rpitit<'tcx>( ty::Binder::bind_with_vars( ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), + tcx.require_lang_item(LangItem::PointerLike, cause.span), [Ty::new_projection_from_args(tcx, rpitit_item, args)], ), tcx.mk_bound_variable_kinds(&bound_vars), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3018dad8e09..416865e861e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -541,7 +541,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(cause); let trait_ref = ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)), + self.tcx().require_lang_item(LangItem::Sized, cause.span), [subty], ); self.out.push(traits::Obligation::with_depth( @@ -895,7 +895,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { self.tcx(), self.tcx().require_lang_item( LangItem::BikeshedGuaranteedNoDrop, - Some(self.span), + self.span, ), [ty], ) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 83d7416b03e..bb5187e4f5c 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; use rustc_session::config::OptLevel; +use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_target::callconv::{ AbiMap, ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, FnAbi, PassMode, @@ -124,7 +125,7 @@ fn fn_sig_for_fn_abi<'tcx>( let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); - let pin_did = tcx.require_lang_item(LangItem::Pin, None); + let pin_did = tcx.require_lang_item(LangItem::Pin, DUMMY_SP); let pin_adt_ref = tcx.adt_def(pin_did); let pin_args = tcx.mk_args(&[env_ty.into()]); let env_ty = match coroutine_kind { @@ -149,7 +150,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll` assert_eq!(sig.yield_ty, tcx.types.unit); - let poll_did = tcx.require_lang_item(LangItem::Poll, None); + let poll_did = tcx.require_lang_item(LangItem::Poll, DUMMY_SP); let poll_adt_ref = tcx.adt_def(poll_did); let poll_args = tcx.mk_args(&[sig.return_ty.into()]); let ret_ty = Ty::new_adt(tcx, poll_adt_ref, poll_args); @@ -160,7 +161,7 @@ fn fn_sig_for_fn_abi<'tcx>( { if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); @@ -172,7 +173,7 @@ fn fn_sig_for_fn_abi<'tcx>( } hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => { // The signature should be `Iterator::next(_) -> Option` - let option_did = tcx.require_lang_item(LangItem::Option, None); + let option_did = tcx.require_lang_item(LangItem::Option, DUMMY_SP); let option_adt_ref = tcx.adt_def(option_did); let option_args = tcx.mk_args(&[sig.yield_ty.into()]); let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args); @@ -196,7 +197,7 @@ fn fn_sig_for_fn_abi<'tcx>( { if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); @@ -208,7 +209,7 @@ fn fn_sig_for_fn_abi<'tcx>( } hir::CoroutineKind::Coroutine(_) => { // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState` - let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); + let state_did = tcx.require_lang_item(LangItem::CoroutineState, DUMMY_SP); let state_adt_ref = tcx.adt_def(state_did); let state_args = tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]); let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args); diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index bb2c4172b08..7219f40710e 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -4,6 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::DUMMY_SP; use rustc_trait_selection::traits; fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { @@ -42,7 +43,7 @@ fn is_item_raw<'tcx>( item: LangItem, ) -> bool { let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(query.typing_env); - let trait_def_id = tcx.require_lang_item(item, None); + let trait_def_id = tcx.require_lang_item(item, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, query.value, trait_def_id) } diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 0b4efab1d9c..e900264a76c 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -16,8 +16,7 @@ fn has_structural_eq_impl<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { let ocx = ObligationCtxt::new(infcx); // require `#[derive(PartialEq)]` - let structural_peq_def_id = - infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); + let structural_peq_def_id = infcx.tcx.require_lang_item(LangItem::StructuralPeq, cause.span); ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id); // We deliberately skip *reporting* fulfillment errors (via diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 330aaa25d13..e39fd6b947b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -104,7 +104,7 @@ fn adt_sized_constraint<'tcx>( // perf hack: if there is a `constraint_ty: Sized` bound, then we know // that the type is sized and do not need to check it on the impl. - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP); let predicates = tcx.predicates_of(def.did()).predicates; if predicates.iter().any(|(p, _)| { p.as_trait_clause().is_some_and(|trait_pred| { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9e46d0b47e9..4030bd45866 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1277,7 +1277,7 @@ impl GenericBound { } fn sized_with(cx: &mut DocContext<'_>, modifiers: hir::TraitBoundModifiers) -> GenericBound { - let did = cx.tcx.require_lang_item(LangItem::Sized, None); + let did = cx.tcx.require_lang_item(LangItem::Sized, DUMMY_SP); let empty = ty::Binder::dummy(ty::GenericArgs::empty()); let path = clean_middle_path(cx, did, false, ThinVec::new(), empty); inline::record_extern_fqn(cx, did, ItemType::Trait); diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 5b4ec12cbec..8e16f943e9f 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -439,7 +439,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> tcx, ObligationCause::dummy_with_span(body.span), param_env, - TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]), + TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, body.span), [ty]), ); let mut selcx = SelectionContext::new(&infcx); diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 549d859a6e1..a6bce830149 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -247,7 +247,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => { // Call the lang item associated with this message. - let fn_item = this.tcx.require_lang_item(msg.panic_function(), None); + let fn_item = this.tcx.require_lang_item(msg.panic_function(), this.tcx.span); let instance = ty::Instance::mono(this.tcx.tcx, fn_item); this.call_function( instance, diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 7676b5557d2..25a4ff283ba 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -48,6 +48,7 @@ fn ice() { // Use index let arr = [0; 5]; + //~^ ERROR requires `copy` lang_item let _ = arr[2]; //~^ ERROR cannot index into a value of type `[{integer}; 5]` @@ -61,5 +62,3 @@ fn ice() { // use `start` fn main() {} - -//~? ERROR requires `copy` lang_item diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 409fa05d637..c82bdb00fd1 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -77,13 +77,13 @@ LL | r + a; | {integer} error[E0608]: cannot index into a value of type `[{integer}; 5]` - --> $DIR/lang-item-generic-requirements.rs:51:16 + --> $DIR/lang-item-generic-requirements.rs:52:16 | LL | let _ = arr[2]; | ^^^ error[E0308]: mismatched types - --> $DIR/lang-item-generic-requirements.rs:58:17 + --> $DIR/lang-item-generic-requirements.rs:59:17 | LL | let _: () = Foo; | -- ^^^ expected `()`, found `Foo` @@ -91,6 +91,10 @@ LL | let _: () = Foo; | expected due to this error: requires `copy` lang_item + --> $DIR/lang-item-generic-requirements.rs:50:16 + | +LL | let arr = [0; 5]; + | ^ error: aborting due to 12 previous errors -- cgit 1.4.1-3-g733a5 From 38d69c3f571b668c82cfb90e5bea8bc86530530c Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 9 Jan 2025 20:35:49 +0800 Subject: Add new Tier-3 targets: `loongarch32-unknown-none*` MCP: https://github.com/rust-lang/compiler-team/issues/865 --- compiler/rustc_codegen_gcc/example/alloc_system.rs | 1 + compiler/rustc_codegen_llvm/src/asm.rs | 2 +- .../rustc_codegen_ssa/src/back/link/raw_dylib.rs | 1 + compiler/rustc_codegen_ssa/src/back/metadata.rs | 2 +- compiler/rustc_target/src/asm/mod.rs | 14 +++++-- compiler/rustc_target/src/callconv/mod.rs | 4 +- compiler/rustc_target/src/spec/mod.rs | 3 ++ .../src/spec/targets/loongarch32_unknown_none.rs | 29 +++++++++++++++ .../targets/loongarch32_unknown_none_softfloat.rs | 30 +++++++++++++++ compiler/rustc_target/src/target_features.rs | 6 +-- library/core/Cargo.toml | 2 + library/core/src/sync/atomic.rs | 10 +++-- library/std/Cargo.toml | 2 + library/std/src/env.rs | 1 + library/std/src/os/linux/raw.rs | 1 + library/std/src/sys/alloc/mod.rs | 1 + library/std/src/sys/personality/gcc.rs | 2 +- library/unwind/Cargo.toml | 2 +- library/unwind/src/libunwind.rs | 2 +- src/bootstrap/bootstrap.py | 1 + src/bootstrap/src/core/sanity.rs | 2 + src/doc/rustc/src/platform-support.md | 2 + .../rustc/src/platform-support/loongarch-none.md | 43 +++++++++++++++------- src/librustdoc/clean/cfg.rs | 1 + src/tools/build-manifest/src/main.rs | 2 + src/tools/compiletest/src/common.rs | 1 + src/tools/compiletest/src/directive-list.rs | 2 + src/tools/miri/src/shims/alloc.rs | 5 ++- tests/assembly/targets/targets-elf.rs | 6 +++ tests/ui/check-cfg/well-known-values.stderr | 2 +- 30 files changed, 149 insertions(+), 33 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs create mode 100644 compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 945d34063a6..4d70122496b 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -8,6 +8,7 @@ // add fast paths for low alignment values. #[cfg(any(target_arch = "x86", target_arch = "arm", + target_arch = "loongarch32", target_arch = "m68k", target_arch = "mips", target_arch = "mips32r6", diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 9e3893d5314..4185aef8b31 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -251,7 +251,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::Nvptx64 => {} InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {} InlineAsmArch::Hexagon => {} - InlineAsmArch::LoongArch64 => { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { constraints.extend_from_slice(&[ "~{$fcc0}".to_string(), "~{$fcc1}".to_string(), diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 2c24378afe1..74f39022afb 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -287,6 +287,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] (Architecture::X86_64, None) => elf::EM_X86_64, (Architecture::X86_64_X32, None) => elf::EM_X86_64, (Architecture::Hexagon, None) => elf::EM_HEXAGON, + (Architecture::LoongArch32, None) => elf::EM_LOONGARCH, (Architecture::LoongArch64, None) => elf::EM_LOONGARCH, (Architecture::M68k, None) => elf::EM_68K, (Architecture::Mips, None) => elf::EM_MIPS, diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ec46c71b0e4..a16862c41ee 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -348,7 +348,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { e_flags } - Architecture::LoongArch64 => { + Architecture::LoongArch32 | Architecture::LoongArch64 => { // Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1; diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 9f791603c72..e06f881e4b1 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -226,6 +226,7 @@ pub enum InlineAsmArch { RiscV64, Nvptx64, Hexagon, + LoongArch32, LoongArch64, Mips, Mips64, @@ -260,6 +261,7 @@ impl FromStr for InlineAsmArch { "powerpc" => Ok(Self::PowerPC), "powerpc64" => Ok(Self::PowerPC64), "hexagon" => Ok(Self::Hexagon), + "loongarch32" => Ok(Self::LoongArch32), "loongarch64" => Ok(Self::LoongArch64), "mips" | "mips32r6" => Ok(Self::Mips), "mips64" | "mips64r6" => Ok(Self::Mips64), @@ -365,7 +367,9 @@ impl InlineAsmReg { Self::PowerPC(PowerPCInlineAsmReg::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?), - InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?), + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { + Self::LoongArch(LoongArchInlineAsmReg::parse(name)?) + } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(name)?) } @@ -652,7 +656,9 @@ impl InlineAsmRegClass { Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?), - InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?), + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { + Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?) + } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmRegClass::parse(name)?) } @@ -860,7 +866,7 @@ pub fn allocatable_registers( hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } - InlineAsmArch::LoongArch64 => { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { let mut map = loongarch::regclass_map(); loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map @@ -992,7 +998,7 @@ impl InlineAsmClobberAbi { "C" | "system" => Ok(InlineAsmClobberAbi::Avr), _ => Err(&["C", "system"]), }, - InlineAsmArch::LoongArch64 => match name { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name { "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), _ => Err(&["C", "system"]), }, diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index d2e49cea647..d595fa45fb6 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -648,7 +648,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "avr" => avr::compute_abi_info(self), - "loongarch64" => loongarch::compute_abi_info(cx, self), + "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self), "m68k" => m68k::compute_abi_info(self), "csky" => csky::compute_abi_info(self), "mips" | "mips32r6" => mips::compute_abi_info(cx, self), @@ -691,7 +691,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { match &*spec.arch { "x86" => x86::compute_rust_abi_info(cx, self), "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self), - "loongarch64" => loongarch::compute_rust_abi_info(cx, self), + "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self), "aarch64" => aarch64::compute_rust_abi_info(cx, self), _ => {} }; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6529c2d72c8..b7916df77c8 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1981,6 +1981,8 @@ supported_targets! { ("sparc-unknown-none-elf", sparc_unknown_none_elf), + ("loongarch32-unknown-none", loongarch32_unknown_none), + ("loongarch32-unknown-none-softfloat", loongarch32_unknown_none_softfloat), ("loongarch64-unknown-none", loongarch64_unknown_none), ("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat), @@ -3502,6 +3504,7 @@ impl Target { "msp430" => (Architecture::Msp430, None), "hexagon" => (Architecture::Hexagon, None), "bpf" => (Architecture::Bpf, None), + "loongarch32" => (Architecture::LoongArch32, None), "loongarch64" => (Architecture::LoongArch64, None), "csky" => (Architecture::Csky, None), "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs new file mode 100644 index 00000000000..fb4963b88b0 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs @@ -0,0 +1,29 @@ +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "loongarch32-unknown-none".into(), + metadata: TargetMetadata { + description: Some("Freestanding/bare-metal LoongArch32".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), + arch: "loongarch32".into(), + options: TargetOptions { + cpu: "generic".into(), + features: "+f,+d".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + llvm_abiname: "ilp32d".into(), + max_atomic_width: Some(32), + relocation_model: RelocModel::Static, + panic_strategy: PanicStrategy::Abort, + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs new file mode 100644 index 00000000000..0e65f83a71c --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs @@ -0,0 +1,30 @@ +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "loongarch32-unknown-none".into(), + metadata: TargetMetadata { + description: Some("Freestanding/bare-metal LoongArch32 softfloat".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), + arch: "loongarch32".into(), + options: TargetOptions { + cpu: "generic".into(), + features: "-f,-d".into(), + abi: "softfloat".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + llvm_abiname: "ilp32s".into(), + max_atomic_width: Some(32), + relocation_model: RelocModel::Static, + panic_strategy: PanicStrategy::Abort, + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 682c4c5068f..c1f128fdc87 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -846,7 +846,7 @@ impl Target { "wasm32" | "wasm64" => WASM_FEATURES, "bpf" => BPF_FEATURES, "csky" => CSKY_FEATURES, - "loongarch64" => LOONGARCH_FEATURES, + "loongarch32" | "loongarch64" => LOONGARCH_FEATURES, "s390x" => IBMZ_FEATURES, "sparc" | "sparc64" => SPARC_FEATURES, "m68k" => M68K_FEATURES, @@ -860,7 +860,7 @@ impl Target { "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, - "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, + "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, @@ -1034,7 +1034,7 @@ impl Target { _ => unreachable!(), } } - "loongarch64" => { + "loongarch32" | "loongarch64" => { // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. match &*self.llvm_abiname { diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index f88661ee001..5d65b55bcda 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -29,6 +29,8 @@ debug_typeid = [] [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ + # #[cfg(bootstrap)] loongarch32 + 'cfg(target_arch, values("loongarch32"))', 'cfg(no_fp_fmt_parse)', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ea459f6d92d..e07a372943c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -178,7 +178,7 @@ //! //! | `target_arch` | Size limit | //! |---------------|---------| -//! | `x86`, `arm`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes | +//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes | //! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes | //! //! Atomics loads that are larger than this limit as well as atomic loads with ordering other @@ -349,8 +349,12 @@ pub type Atomic = ::AtomicInner; // This list should only contain architectures which have word-sized atomic-or/ // atomic-and instructions but don't natively support byte-sized atomics. #[cfg(target_has_atomic = "8")] -const EMULATE_ATOMIC_BOOL: bool = - cfg!(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "loongarch64")); +const EMULATE_ATOMIC_BOOL: bool = cfg!(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64" +)); /// A boolean type which can be safely shared between threads. /// diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 196b904d56a..0419336e13a 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -157,6 +157,8 @@ test = true [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ + # #[cfg(bootstrap)] loongarch32 + 'cfg(target_arch, values("loongarch32"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/std/src/env.rs b/library/std/src/env.rs index ce2dc795220..6d7d576b32a 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -1046,6 +1046,7 @@ pub mod consts { /// * `"sparc"` /// * `"sparc64"` /// * `"hexagon"` + /// * `"loongarch32"` /// * `"loongarch64"` /// /// diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index d53674d3c5f..6483f086113 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -231,6 +231,7 @@ mod arch { } #[cfg(any( + target_arch = "loongarch32", target_arch = "loongarch64", target_arch = "mips64", target_arch = "mips64r6", diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 8489e17c971..f3af1f7f599 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -17,6 +17,7 @@ const MIN_ALIGN: usize = if cfg!(any( target_arch = "arm", target_arch = "m68k", target_arch = "csky", + target_arch = "loongarch32", target_arch = "mips", target_arch = "mips32r6", target_arch = "powerpc", diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index b012e47f9aa..75e793f18b8 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -86,7 +86,7 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11 -#[cfg(target_arch = "loongarch64")] +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 // The following code is based on GCC's C and C++ personality routines. For reference, see: diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index df43e6ae80f..0db3f7450f1 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -37,4 +37,4 @@ system-llvm-libunwind = [] [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = ['cfg(emscripten_wasm_eh)'] +check-cfg = ['cfg(emscripten_wasm_eh)', 'cfg(target_arch, values("loongarch32"))'] diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 12582569a57..b350003cbb1 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -81,7 +81,7 @@ pub const unwinder_private_data_size: usize = 2; #[cfg(all(target_arch = "hexagon", target_os = "linux"))] pub const unwinder_private_data_size: usize = 35; -#[cfg(target_arch = "loongarch64")] +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] pub const unwinder_private_data_size: usize = 2; #[repr(C)] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index c60c6b8db64..d8c6be78247 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -394,6 +394,7 @@ def default_build_triple(verbose): "i686": "i686", "i686-AT386": "i686", "i786": "i686", + "loongarch32": "loongarch32", "loongarch64": "loongarch64", "m68k": "m68k", "csky": "csky", diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index af4ec679d08..59ae303e21e 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,8 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e7dfaaf4fd5..e2e2ad9ac3b 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -324,6 +324,8 @@ target | std | host | notes [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment] [`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI] [`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony +[`loongarch32-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32D ABI) +[`loongarch32-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32S ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux [`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) | | | Motorola 680x0 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index a2bd6e5734c..fd90b0a2763 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -1,18 +1,18 @@ # `loongarch*-unknown-none*` -**Tier: 2** +Freestanding/bare-metal LoongArch binaries in ELF format: firmware, kernels, etc. -Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. - -| Target | Description | -|--------|-------------| -| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | -| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | +| Target | Description | Tier | +|--------|-------------|------| +| `loongarch32-unknown-none` | LoongArch 32-bit, ILP32D ABI (freestanding, hard-float) | Tier 3 | +| `loongarch32-unknown-none-softfloat` | LoongArch 32-bit, ILP32S ABI (freestanding, soft-float) | Tier 3 | +| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | Tier 2 | +| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | Tier 2 | ## Target maintainers -[@heiher](https://github.com/heiher) -[@xen0n](https://github.com/xen0n) +- [@heiher](https://github.com/heiher) +- [@xen0n](https://github.com/xen0n) ## Requirements @@ -29,13 +29,13 @@ additional CPU features via the `-C target-feature=` codegen options to rustc, o via the `#[target_feature]` mechanism within Rust code. By default, code generated with the soft-float target should run on any -LoongArch64 hardware, with the hard-float target additionally requiring an FPU; +LoongArch hardware, with the hard-float target additionally requiring an FPU; enabling additional target features may raise this baseline. Code generated with the targets will use the `medium` code model by default. You can change this using the `-C code-model=` option to rustc. -On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. +On `loongarch*-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. [lapcs]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc @@ -52,6 +52,8 @@ list in `bootstrap.toml`: [build] build-stage = 1 target = [ + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", "loongarch64-unknown-none", "loongarch64-unknown-none-softfloat", ] @@ -64,13 +66,28 @@ As the targets support a variety of different environments and do not support ## Building Rust programs +### loongarch32-unknown-none* + +The `loongarch32-unknown-none*` targets are Tier 3, so you must build the Rust +compiler from source to use them. + +```sh +# target flag may be used with any cargo or rustc command +cargo build --target loongarch32-unknown-none +cargo build --target loongarch32-unknown-none-softfloat +``` + +### loongarch64-unknown-none* + Starting with Rust 1.74, precompiled artifacts are provided via `rustup`: ```sh # install cross-compile toolchain rustup target add loongarch64-unknown-none +rustup target add loongarch64-unknown-none-softfloat # target flag may be used with any cargo or rustc command cargo build --target loongarch64-unknown-none +cargo build --target loongarch64-unknown-none-softfloat ``` ## Cross-compilation toolchains and C code @@ -79,10 +96,10 @@ For cross builds, you will need an appropriate LoongArch C/C++ toolchain for linking, or if you want to compile C code along with Rust (such as for Rust crates with C dependencies). -Rust *may* be able to use an `loongarch64-unknown-linux-gnu-` toolchain with +Rust *may* be able to use an `loongarch{32,64}-unknown-linux-{gnu,musl}-` toolchain with appropriate standalone flags to build for this toolchain (depending on the assumptions of that toolchain, see below), or you may wish to use a separate -`loongarch64-unknown-none` toolchain. +`loongarch{32,64}-unknown-none` toolchain. On some LoongArch hosts that use ELF binaries, you *may* be able to use the host C toolchain, if it does not introduce assumptions about the host environment diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index ebc276b38fb..a3762e4117d 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -508,6 +508,7 @@ impl fmt::Display for Display<'_> { (sym::target_arch, Some(arch)) => match arch.as_str() { "aarch64" => "AArch64", "arm" => "ARM", + "loongarch32" => "LoongArch LA32", "loongarch64" => "LoongArch LA64", "m68k" => "M68k", "csky" => "CSKY", diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 741d7e3fa16..c85f2c9442b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -111,6 +111,8 @@ static TARGETS: &[&str] = &[ "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-linux-musl", + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", "loongarch64-unknown-none", "loongarch64-unknown-none-softfloat", "m68k-unknown-linux-gnu", diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 4f93b498741..9b9d94bbead 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -495,6 +495,7 @@ impl Config { "arm64ec", "riscv32", "riscv64", + "loongarch32", "loongarch64", "s390x", // These targets require an additional asm_experimental_arch feature. diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 5757e422ae2..1406553c9ea 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -73,6 +73,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-linux", "ignore-lldb", "ignore-llvm-version", + "ignore-loongarch32", "ignore-loongarch64", "ignore-macabi", "ignore-macos", @@ -196,6 +197,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-i686-unknown-linux-gnu", "only-ios", "only-linux", + "only-loongarch32", "only-loongarch64", "only-loongarch64-unknown-linux-gnu", "only-macos", diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 323b95d5f5f..d7bb16f0858 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -13,10 +13,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // alignment requirement and size less than or equal to the size requested." // So first we need to figure out what the limits are for "fundamental alignment". // This is given by `alignof(max_align_t)`. The following list is taken from - // `library/std/src/sys/pal/common/alloc.rs` (where this is called `MIN_ALIGN`) and should + // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. let max_fundamental_align = match this.tcx.sess.target.arch.as_ref() { - "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "wasm32" => 8, + "x86" | "arm" | "loongarch32" | "mips" | "mips32r6" | "powerpc" | "powerpc64" + | "wasm32" => 8, "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" => 16, arch => bug!("unsupported target architecture for malloc: `{}`", arch), diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 32555911194..edf16548e7d 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -259,6 +259,12 @@ //@ revisions: i686_wrs_vxworks //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks //@ [i686_wrs_vxworks] needs-llvm-components: x86 +//@ revisions: loongarch32_unknown_none +//@ [loongarch32_unknown_none] compile-flags: --target loongarch32-unknown-none +//@ [loongarch32_unknown_none] needs-llvm-components: loongarch +//@ revisions: loongarch32_unknown_none_softfloat +//@ [loongarch32_unknown_none_softfloat] compile-flags: --target loongarch32-unknown-none-softfloat +//@ [loongarch32_unknown_none_softfloat] needs-llvm-components: loongarch //@ revisions: loongarch64_unknown_linux_gnu //@ [loongarch64_unknown_linux_gnu] compile-flags: --target loongarch64-unknown-linux-gnu //@ [loongarch64_unknown_linux_gnu] needs-llvm-components: loongarch diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 7cda6c2eaa5..532c1ab13d1 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa` + = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch32`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` -- cgit 1.4.1-3-g733a5 From 8bce2255e826a11d1aa345d1786f85d22c5f921a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 4 Jun 2025 01:44:40 -0700 Subject: Update `InterpCx::project_field` to take `FieldIdx` As suggested by Ralf in 142005. --- compiler/rustc_abi/src/layout/ty.rs | 11 +++++++++-- compiler/rustc_codegen_cranelift/src/inline_asm.rs | 2 +- compiler/rustc_codegen_cranelift/src/vtable.rs | 5 ++--- compiler/rustc_codegen_ssa/src/mir/block.rs | 4 ++-- compiler/rustc_const_eval/src/const_eval/mod.rs | 4 ++-- .../rustc_const_eval/src/const_eval/valtrees.rs | 6 +++--- compiler/rustc_const_eval/src/interpret/call.rs | 9 ++++----- compiler/rustc_const_eval/src/interpret/cast.rs | 3 ++- .../rustc_const_eval/src/interpret/discriminant.rs | 4 ++-- .../rustc_const_eval/src/interpret/projection.rs | 18 +++++++++--------- compiler/rustc_const_eval/src/interpret/step.rs | 2 +- compiler/rustc_const_eval/src/interpret/traits.rs | 6 +++--- compiler/rustc_const_eval/src/interpret/visitor.rs | 21 ++++++++++++--------- .../rustc_const_eval/src/util/caller_location.rs | 12 ++++++++---- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_typeck/src/inline_asm.rs | 2 +- .../rustc_mir_transform/src/dataflow_const_prop.rs | 7 ++++--- compiler/rustc_mir_transform/src/gvn.rs | 8 +++++--- compiler/rustc_mir_transform/src/jump_threading.rs | 2 +- src/tools/miri/src/eval.rs | 8 ++++---- src/tools/miri/src/helpers.rs | 7 ++++--- src/tools/miri/src/shims/backtrace.rs | 12 ++++++------ src/tools/miri/src/shims/unix/env.rs | 7 ++++--- src/tools/miri/src/shims/unix/freebsd/sync.rs | 8 +++++--- src/tools/miri/src/shims/unix/linux_like/epoll.rs | 6 ++++-- src/tools/miri/src/shims/x86/mod.rs | 6 +++--- 26 files changed, 102 insertions(+), 80 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 4f43c0e6f8e..eb49b977257 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -39,6 +39,13 @@ rustc_index::newtype_index! { pub struct FieldIdx {} } +impl FieldIdx { + /// The second field. + /// + /// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs. + pub const ONE: FieldIdx = FieldIdx::from_u32(1); +} + rustc_index::newtype_index! { /// The *source-order* index of a variant in a type. /// @@ -274,7 +281,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// Finds the one field that is not a 1-ZST. /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. - pub fn non_1zst_field(&self, cx: &C) -> Option<(usize, Self)> + pub fn non_1zst_field(&self, cx: &C) -> Option<(FieldIdx, Self)> where Ty: TyAbiInterface<'a, C> + Copy, { @@ -288,7 +295,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { // More than one non-1-ZST field. return None; } - found = Some((field_idx, field)); + found = Some((FieldIdx::from_usize(field_idx), field)); } found } diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index afee5095549..120d6ff9e38 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -850,7 +850,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); + let ty = fields[FieldIdx::ONE].ty(fx.tcx, args); let ty::Adt(ty, args) = ty.kind() else { unreachable!("expected first field of `MaybeUninit` to be an ADT") }; diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 9d9e0462a9b..05a8e3c3342 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -53,7 +53,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( .layout() .non_1zst_field(fx) .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); - arg = arg.value_field(fx, FieldIdx::new(idx)); + arg = arg.value_field(fx, idx); } } @@ -62,8 +62,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap()); let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr(); - let vtable = - dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx); + let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx); break 'block (ptr, vtable); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1baab62ae43..7cea48ce1cc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1077,7 +1077,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(self, bx, idx); + op = op.extract_field(self, bx, idx.as_usize()); } // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its @@ -1109,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(self, bx, idx); + op = op.extract_field(self, bx, idx.as_usize()); } // Make sure that we've actually unwrapped the rcvr down diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index c0438fb3ff8..6fd0b9d26e3 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,6 +1,6 @@ // Not in interpret to make sure we do not use private implementation details -use rustc_abi::VariantIdx; +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::query::Key; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -60,7 +60,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( let fields_iter = (0..field_count) .map(|i| { - let field_op = ecx.project_field(&down, i).discard_err()?; + let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?; let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true); Some((val, field_op.layout.ty)) }) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 34239ae1d15..58d230af683 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,4 +1,4 @@ -use rustc_abi::{BackendRepr, VariantIdx}; +use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo}; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; @@ -40,7 +40,7 @@ fn branches<'tcx>( } for i in 0..field_count { - let field = ecx.project_field(&place, i).unwrap(); + let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; branches.push(valtree); } @@ -437,7 +437,7 @@ fn valtree_into_mplace<'tcx>( ty::Str | ty::Slice(_) | ty::Array(..) => { ecx.project_index(place, i as u64).unwrap() } - _ => ecx.project_field(&place_adjusted, i).unwrap(), + _ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(), }; debug!(?place_inner); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 789baea0734..37677f9e048 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -62,7 +62,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub(super) fn fn_arg_field( &self, arg: &FnArg<'tcx, M::Provenance>, - field: usize, + field: FieldIdx, ) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> { interp_ok(match arg { FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?), @@ -600,10 +600,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Cow::from( args.iter() .map(|a| interp_ok(a.clone())) - .chain( - (0..untuple_arg.layout().fields.count()) - .map(|i| self.fn_arg_field(untuple_arg, i)), - ) + .chain((0..untuple_arg.layout().fields.count()).map(|i| { + self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i)) + })) .collect::>>()?, ) } else { diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 643a5805019..9e15f4572d7 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,6 +1,6 @@ use std::assert_matches::assert_matches; -use rustc_abi::Integer; +use rustc_abi::{FieldIdx, Integer}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::CastKind; @@ -484,6 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let mut found_cast_field = false; for i in 0..src.layout.fields.count() { let cast_ty_field = cast_ty.field(self, i); + let i = FieldIdx::from_usize(i); let src_field = self.project_field(src, i)?; let dst_field = self.project_field(dest, i)?; if src_field.layout.is_1zst() && cast_ty_field.is_1zst() { diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 020cd65d75d..6c4b000e16b 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -26,7 +26,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // No need to validate that the discriminant here because the // `TyAndLayout::for_variant()` call earlier already checks the // variant is valid. - let tag_dest = self.project_field(dest, tag_field.as_usize())?; + let tag_dest = self.project_field(dest, tag_field)?; self.write_scalar(tag, &tag_dest) } None => { @@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. - let tag_val = self.read_immediate(&self.project_field(op, tag_field.as_usize())?)?; + let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?; assert_eq!(tag_layout.size, tag_val.layout.size); assert_eq!(tag_layout.backend_repr.is_signed(), tag_val.layout.backend_repr.is_signed()); trace!("tag value: {}", tag_val); diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 8ecb3e13d5c..ad47a19a14d 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -10,7 +10,7 @@ use std::marker::PhantomData; use std::ops::Range; -use rustc_abi::{self as abi, Size, VariantIdx}; +use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::{bug, mir, span_bug, ty}; @@ -144,22 +144,22 @@ where /// always possible without allocating, so it can take `&self`. Also return the field's layout. /// This supports both struct and array fields, but not slices! /// - /// This also works for arrays, but then the `usize` index type is restricting. - /// For indexing into arrays, use `mplace_index`. + /// This also works for arrays, but then the `FieldIdx` index type is restricting. + /// For indexing into arrays, use [`Self::project_index`]. pub fn project_field>( &self, base: &P, - field: usize, + field: FieldIdx, ) -> InterpResult<'tcx, P> { // Slices nominally have length 0, so they will panic somewhere in `fields.offset`. debug_assert!( !matches!(base.layout().ty.kind(), ty::Slice(..)), "`field` projection called on a slice -- call `index` projection instead" ); - let offset = base.layout().fields.offset(field); + let offset = base.layout().fields.offset(field.as_usize()); // Computing the layout does normalization, so we get a normalized type out of this // even if the field type is non-normalized (possible e.g. via associated types). - let field_layout = base.layout().field(self, field); + let field_layout = base.layout().field(self, field.as_usize()); // Offset may need adjustment for unsized fields. let (meta, offset) = if field_layout.is_unsized() { @@ -244,7 +244,7 @@ where } _ => span_bug!( self.cur_span(), - "`mplace_index` called on non-array type {:?}", + "`project_index` called on non-array type {:?}", base.layout().ty ), }; @@ -260,7 +260,7 @@ where ) -> InterpResult<'tcx, (P, u64)> { assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd()); // SIMD types must be newtypes around arrays, so all we have to do is project to their only field. - let array = self.project_field(base, 0)?; + let array = self.project_field(base, FieldIdx::ZERO)?; let len = array.len(self)?; interp_ok((array, len)) } @@ -384,7 +384,7 @@ where UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?, // We don't want anything happening here, this is here as a dummy. Subtype(_) => base.transmute(base.layout(), self)?, - Field(field, _) => self.project_field(base, field.index())?, + Field(field, _) => self.project_field(base, field)?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), Index(local) => { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 975325b0c1e..833fcc38817 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -333,7 +333,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } for (field_index, operand) in operands.iter_enumerated() { let field_index = active_field_index.unwrap_or(field_index); - let field_dest = self.project_field(&variant_dest, field_index.as_usize())?; + let field_dest = self.project_field(&variant_dest, field_index)?; let op = self.eval_operand(operand, Some(field_dest.layout))?; self.copy_op(&op, &field_dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index a5029eea5a7..7249ef23bf6 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -1,4 +1,4 @@ -use rustc_abi::{Align, Size}; +use rustc_abi::{Align, FieldIdx, Size}; use rustc_middle::mir::interpret::{InterpResult, Pointer}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, VtblEntry}; @@ -137,8 +137,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)), "`unpack_dyn_star` only makes sense on `dyn*` types" ); - let data = self.project_field(val, 0)?; - let vtable = self.project_field(val, 1)?; + let data = self.project_field(val, FieldIdx::ZERO)?; + let vtable = self.project_field(val, FieldIdx::ONE)?; let vtable = self.read_pointer(&vtable.to_op(self)?)?; let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?; // `data` is already the right thing but has the wrong type. So we transmute it. diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 3647c109a6e..5aea91233bd 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -112,8 +112,10 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // So we transmute it to a raw pointer. let raw_ptr_ty = Ty::new_mut_ptr(*self.ecx().tcx, self.ecx().tcx.types.unit); let raw_ptr_ty = self.ecx().layout_of(raw_ptr_ty)?; - let vtable_field = - self.ecx().project_field(v, 1)?.transmute(raw_ptr_ty, self.ecx())?; + let vtable_field = self + .ecx() + .project_field(v, FieldIdx::ONE)? + .transmute(raw_ptr_ty, self.ecx())?; self.visit_field(v, 1, &vtable_field)?; // Then unpack the first field, and continue. @@ -140,14 +142,16 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // `Box` has two fields: the pointer we care about, and the allocator. assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields"); - let (unique_ptr, alloc) = - (self.ecx().project_field(v, 0)?, self.ecx().project_field(v, 1)?); + let (unique_ptr, alloc) = ( + self.ecx().project_field(v, FieldIdx::ZERO)?, + self.ecx().project_field(v, FieldIdx::ONE)?, + ); // Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`... // (which means another 2 fields, the second of which is a `PhantomData`) assert_eq!(unique_ptr.layout().fields.count(), 2); let (nonnull_ptr, phantom) = ( - self.ecx().project_field(&unique_ptr, 0)?, - self.ecx().project_field(&unique_ptr, 1)?, + self.ecx().project_field(&unique_ptr, FieldIdx::ZERO)?, + self.ecx().project_field(&unique_ptr, FieldIdx::ONE)?, ); assert!( phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()), @@ -156,7 +160,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { ); // ... that contains a `NonNull`... (gladly, only a single field here) assert_eq!(nonnull_ptr.layout().fields.count(), 1); - let raw_ptr = self.ecx().project_field(&nonnull_ptr, 0)?; // the actual raw ptr + let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr // ... whose only field finally is a raw ptr we can dereference. self.visit_box(ty, &raw_ptr)?; @@ -188,9 +192,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { } FieldsShape::Arbitrary { memory_index, .. } => { for idx in Self::aggregate_field_iter(memory_index) { - let idx = idx.as_usize(); let field = self.ecx().project_field(v, idx)?; - self.visit_field(v, idx, &field)?; + self.visit_field(v, idx.as_usize(), &field)?; } } FieldsShape::Array { .. } => { diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 9c867cc615e..65d02d3bafa 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,3 +1,4 @@ +use rustc_abi::FieldIdx; use rustc_hir::LangItem; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, TyCtxt}; @@ -41,11 +42,14 @@ fn alloc_caller_location<'tcx>( let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); // Initialize fields. - ecx.write_immediate(file_wide_ptr, &ecx.project_field(&location, 0).unwrap()) + ecx.write_immediate( + file_wide_ptr, + &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap(), + ) + .expect("writing to memory we just allocated cannot fail"); + ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap()) .expect("writing to memory we just allocated cannot fail"); - ecx.write_scalar(line, &ecx.project_field(&location, 1).unwrap()) - .expect("writing to memory we just allocated cannot fail"); - ecx.write_scalar(col, &ecx.project_field(&location, 2).unwrap()) + ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap()) .expect("writing to memory we just allocated cannot fail"); location diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 846eacce9e1..5d42de74f6c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1100,7 +1100,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { return; }; - if let Some(second_field) = fields.get(FieldIdx::from_u32(1)) { + if let Some(second_field) = fields.get(FieldIdx::ONE) { struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields") .with_span_label(tcx.def_span(second_field.did), "excess field") .emit(); diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index 6399f0a78ae..b59c1752c25 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -171,7 +171,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ if ty.references_error() => return None, ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx(), args); + let ty = fields[FieldIdx::ONE].ty(self.tcx(), args); // FIXME: Are we just trying to map to the `T` in `MaybeUninit`? // If so, just get it from the args. let ty::Adt(ty, args) = ty.kind() else { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 99b95e7312b..0cf8142a560 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -616,7 +616,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { place, operand, &mut |elem, op| match elem { - TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(), + TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(), TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(), TrackElem::Discriminant => { let variant = self.ecx.read_discriminant(op).discard_err()?; @@ -890,7 +890,8 @@ fn try_write_constant<'tcx>( ty::Tuple(elem_tys) => { for (i, elem) in elem_tys.iter().enumerate() { - let Some(field) = map.apply(place, TrackElem::Field(FieldIdx::from_usize(i))) else { + let i = FieldIdx::from_usize(i); + let Some(field) = map.apply(place, TrackElem::Field(i)) else { throw_machine_stop_str!("missing field in tuple") }; let field_dest = ecx.project_field(dest, i)?; @@ -928,7 +929,7 @@ fn try_write_constant<'tcx>( let Some(field) = map.apply(variant_place, TrackElem::Field(i)) else { throw_machine_stop_str!("missing field in ADT") }; - let field_dest = ecx.project_field(&variant_dest, i.as_usize())?; + let field_dest = ecx.project_field(&variant_dest, i)?; try_write_constant(ecx, &field_dest, field, ty, state, map)?; } ecx.write_discriminant(variant_idx, dest)?; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index a91d46ec406..92c30d239b5 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -438,8 +438,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { dest.clone() }; for (field_index, op) in fields.into_iter().enumerate() { - let field_dest = - self.ecx.project_field(&variant_dest, field_index).discard_err()?; + let field_dest = self + .ecx + .project_field(&variant_dest, FieldIdx::from_usize(field_index)) + .discard_err()?; self.ecx.copy_op(op, &field_dest).discard_err()?; } self.ecx @@ -1583,7 +1585,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // We needed to check the variant to avoid trying to read the tag // field from an enum where no fields have variants, since that tag // field isn't in the `Aggregate` from which we're getting values. - Some((FieldIdx::from_usize(field_idx), field_layout.ty)) + Some((field_idx, field_layout.ty)) } else if let ty::Adt(adt, args) = ty.kind() && adt.is_struct() && adt.repr().transparent() diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 31b361ec1a9..48db536c122 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -388,7 +388,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { lhs, constant, &mut |elem, op| match elem { - TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(), + TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(), TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(), TrackElem::Discriminant => { let variant = self.ecx.read_discriminant(op).discard_err()?; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 8fe034d2582..5880e5fbc37 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -359,8 +359,8 @@ pub fn create_ecx<'tcx>( let argvs_layout = ecx.layout_of(Ty::new_array(tcx, u8_ptr_type, u64::try_from(argvs.len()).unwrap()))?; let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?; - for (idx, arg) in argvs.into_iter().enumerate() { - let place = ecx.project_field(&argvs_place, idx)?; + for (arg, idx) in argvs.into_iter().zip(0..) { + let place = ecx.project_index(&argvs_place, idx)?; ecx.write_immediate(arg, &place)?; } ecx.mark_immutable(&argvs_place); @@ -389,8 +389,8 @@ pub fn create_ecx<'tcx>( ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?; ecx.machine.cmd_line = Some(cmd_place.ptr()); // Store the UTF-16 string. We just allocated so we know the bounds are fine. - for (idx, &c) in cmd_utf16.iter().enumerate() { - let place = ecx.project_field(&cmd_place, idx)?; + for (&c, idx) in cmd_utf16.iter().zip(0..) { + let place = ecx.project_index(&cmd_place, idx)?; ecx.write_scalar(Scalar::from_u16(c), &place)?; } ecx.mark_immutable(&cmd_place); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 20ea239b7e5..4edecc864dd 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -326,7 +326,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Option

> { let this = self.eval_context_ref(); let adt = base.layout().ty.ty_adt_def().unwrap(); - for (idx, field) in adt.non_enum_variant().fields.iter().enumerate() { + for (idx, field) in adt.non_enum_variant().fields.iter_enumerated() { if field.name.as_str() == name { return interp_ok(Some(this.project_field(base, idx)?)); } @@ -376,6 +376,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); for (idx, &val) in values.iter().enumerate() { + let idx = FieldIdx::from_usize(idx); let field = this.project_field(dest, idx)?; this.write_int(val, &field)?; } @@ -763,10 +764,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// `EINVAL` in this case. fn read_timespec(&mut self, tp: &MPlaceTy<'tcx>) -> InterpResult<'tcx, Option> { let this = self.eval_context_mut(); - let seconds_place = this.project_field(tp, 0)?; + let seconds_place = this.project_field(tp, FieldIdx::ZERO)?; let seconds_scalar = this.read_scalar(&seconds_place)?; let seconds = seconds_scalar.to_target_isize(this)?; - let nanoseconds_place = this.project_field(tp, 1)?; + let nanoseconds_place = this.project_field(tp, FieldIdx::ONE)?; let nanoseconds_scalar = this.read_scalar(&nanoseconds_place)?; let nanoseconds = nanoseconds_scalar.to_target_isize(this)?; diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index ab11553df63..8606735c913 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -1,4 +1,4 @@ -use rustc_abi::{CanonAbi, Size}; +use rustc_abi::{CanonAbi, FieldIdx, Size}; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{BytePos, Loc, Symbol, hygiene}; @@ -159,23 +159,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { 1 => { this.write_scalar( Scalar::from_target_usize(name.len().to_u64(), this), - &this.project_field(dest, 0)?, + &this.project_field(dest, FieldIdx::from_u32(0))?, )?; this.write_scalar( Scalar::from_target_usize(filename.len().to_u64(), this), - &this.project_field(dest, 1)?, + &this.project_field(dest, FieldIdx::from_u32(1))?, )?; } _ => throw_unsup_format!("unknown `miri_resolve_frame` flags {}", flags), } - this.write_scalar(Scalar::from_u32(lineno), &this.project_field(dest, 2)?)?; - this.write_scalar(Scalar::from_u32(colno), &this.project_field(dest, 3)?)?; + this.write_scalar(Scalar::from_u32(lineno), &this.project_field(dest, FieldIdx::from_u32(2))?)?; + this.write_scalar(Scalar::from_u32(colno), &this.project_field(dest, FieldIdx::from_u32(3))?)?; // Support a 4-field struct for now - this is deprecated // and slated for removal. if num_fields == 5 { - this.write_pointer(fn_ptr, &this.project_field(dest, 4)?)?; + this.write_pointer(fn_ptr, &this.project_field(dest, FieldIdx::from_u32(4))?)?; } interp_ok(()) diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index aebb5757aec..62ac7ee3806 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -2,8 +2,9 @@ use std::ffi::{OsStr, OsString}; use std::io::ErrorKind; use std::{env, mem}; -use rustc_abi::Size; +use rustc_abi::{FieldIdx, Size}; use rustc_data_structures::fx::FxHashMap; +use rustc_index::IndexVec; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; @@ -118,7 +119,7 @@ fn alloc_env_var<'tcx>( /// Allocates an `environ` block with the given list of pointers. fn alloc_environ_block<'tcx>( ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, - mut vars: Vec, + mut vars: IndexVec, ) -> InterpResult<'tcx, Pointer> { // Add trailing null. vars.push(Pointer::null()); @@ -129,7 +130,7 @@ fn alloc_environ_block<'tcx>( u64::try_from(vars.len()).unwrap(), ))?; let vars_place = ecx.allocate(vars_layout, MiriMemoryKind::Runtime.into())?; - for (idx, var) in vars.into_iter().enumerate() { + for (idx, var) in vars.into_iter_enumerated() { let place = ecx.project_field(&vars_place, idx)?; ecx.write_pointer(var, &place)?; } diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs index 54650f35b2c..f4e7d9e58f9 100644 --- a/src/tools/miri/src/shims/unix/freebsd/sync.rs +++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs @@ -2,6 +2,8 @@ use core::time::Duration; +use rustc_abi::FieldIdx; + use crate::concurrency::sync::FutexRef; use crate::*; @@ -214,18 +216,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Only flag allowed is UMTX_ABSTIME. let abs_time = this.eval_libc_u32("UMTX_ABSTIME"); - let timespec_place = this.project_field(ut, 0)?; + let timespec_place = this.project_field(ut, FieldIdx::from_u32(0))?; // Inner `timespec` must still be valid. let duration = match this.read_timespec(×pec_place)? { Some(dur) => dur, None => return interp_ok(None), }; - let flags_place = this.project_field(ut, 1)?; + let flags_place = this.project_field(ut, FieldIdx::from_u32(1))?; let flags = this.read_scalar(&flags_place)?.to_u32()?; let abs_time_flag = flags == abs_time; - let clock_id_place = this.project_field(ut, 2)?; + let clock_id_place = this.project_field(ut, FieldIdx::from_u32(2))?; let clock_id = this.read_scalar(&clock_id_place)?.to_i32()?; let timeout_clock = this.translate_umtx_time_clock_id(clock_id)?; diff --git a/src/tools/miri/src/shims/unix/linux_like/epoll.rs b/src/tools/miri/src/shims/unix/linux_like/epoll.rs index b489595b4cd..f971fb10b19 100644 --- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs @@ -4,6 +4,8 @@ use std::io; use std::rc::{Rc, Weak}; use std::time::Duration; +use rustc_abi::FieldIdx; + use crate::concurrency::VClock; use crate::shims::files::{ DynFileDescriptionRef, FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, @@ -284,8 +286,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if op == epoll_ctl_add || op == epoll_ctl_mod { // Read event bitmask and data from epoll_event passed by caller. - let mut events = this.read_scalar(&this.project_field(&event, 0)?)?.to_u32()?; - let data = this.read_scalar(&this.project_field(&event, 1)?)?.to_u64()?; + let mut events = this.read_scalar(&this.project_field(&event, FieldIdx::ZERO)?)?.to_u32()?; + let data = this.read_scalar(&this.project_field(&event, FieldIdx::ONE)?)?.to_u64()?; // Unset the flag we support to discover if any unsupported flags are used. let mut flags = events; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 7dee8ddd23c..1e82f521249 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,4 +1,4 @@ -use rustc_abi::{CanonAbi, Size}; +use rustc_abi::{CanonAbi, FieldIdx, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; use rustc_middle::ty::Ty; @@ -54,8 +54,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; let (sum, cb_out) = carrying_add(this, cb_in, a, b, op)?; - this.write_scalar(cb_out, &this.project_field(dest, 0)?)?; - this.write_immediate(*sum, &this.project_field(dest, 1)?)?; + this.write_scalar(cb_out, &this.project_field(dest, FieldIdx::ZERO)?)?; + this.write_immediate(*sum, &this.project_field(dest, FieldIdx::ONE)?)?; } // Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions, -- cgit 1.4.1-3-g733a5 From 8808c9d34b04c8c9404aafaba2aeec4142963fa5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 May 2025 18:37:58 +0200 Subject: intrinsics: use const generic to set atomic ordering --- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 28 +- compiler/rustc_codegen_ssa/messages.ftl | 8 - compiler/rustc_codegen_ssa/src/errors.rs | 16 - compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 322 +++---- .../rustc_error_codes/src/error_codes/E0092.md | 15 +- .../rustc_error_codes/src/error_codes/E0093.md | 17 +- .../rustc_error_codes/src/error_codes/E0622.md | 4 +- compiler/rustc_hir_analysis/messages.ftl | 4 - compiler/rustc_hir_analysis/src/check/intrinsic.rs | 59 +- compiler/rustc_hir_analysis/src/errors.rs | 9 - compiler/rustc_span/src/symbol.rs | 16 + library/core/src/intrinsics/mod.rs | 964 ++------------------- library/core/src/sync/atomic.rs | 270 +++--- library/panic_unwind/src/seh.rs | 12 +- src/tools/miri/src/intrinsics/atomic.rs | 153 ++-- .../run-make/atomic-lock-free/atomic_lock_free.rs | 42 +- tests/ui/error-codes/E0092.rs | 6 - tests/ui/error-codes/E0092.stderr | 9 - .../feature-gated-feature-in-macro-arg.stderr | 2 +- tests/ui/intrinsics/auxiliary/cci_intrinsic.rs | 19 +- tests/ui/intrinsics/intrinsic-atomics.rs | 40 +- tests/ui/intrinsics/non-integer-atomic.rs | 52 +- tests/ui/intrinsics/non-integer-atomic.stderr | 88 +- 23 files changed, 667 insertions(+), 1488 deletions(-) delete mode 100644 tests/ui/error-codes/E0092.rs delete mode 100644 tests/ui/error-codes/E0092.stderr (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 27a5df8b152..a0f96d85dc3 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -875,7 +875,6 @@ fn codegen_regular_intrinsic_call<'tcx>( let ptr = ptr.load_scalar(fx); let ty = generic_args.type_at(0); - let _ord = generic_args.const_at(1).to_value(); // FIXME: forward this to cranelift once they support that match ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { // FIXME implement 128bit atomics @@ -906,7 +905,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(ty)); ret.write_cvalue(fx, val); } - _ if intrinsic.as_str().starts_with("atomic_store") => { + sym::atomic_store => { intrinsic_args!(fx, args => (ptr, val); intrinsic); let ptr = ptr.load_scalar(fx); @@ -939,7 +938,7 @@ fn codegen_regular_intrinsic_call<'tcx>( fx.bcx.ins().atomic_store(MemFlags::trusted(), val, ptr); } - _ if intrinsic.as_str().starts_with("atomic_xchg") => { + sym::atomic_xchg => { intrinsic_args!(fx, args => (ptr, new); intrinsic); let ptr = ptr.load_scalar(fx); @@ -960,8 +959,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_cxchg") => { - // both atomic_cxchg_* and atomic_cxchgweak_* + sym::atomic_cxchg | sym::atomic_cxchgweak => { intrinsic_args!(fx, args => (ptr, test_old, new); intrinsic); let ptr = ptr.load_scalar(fx); @@ -984,7 +982,7 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, ret_val) } - _ if intrinsic.as_str().starts_with("atomic_xadd") => { + sym::atomic_xadd => { intrinsic_args!(fx, args => (ptr, amount); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1006,7 +1004,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_xsub") => { + sym::atomic_xsub => { intrinsic_args!(fx, args => (ptr, amount); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1028,7 +1026,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_and") => { + sym::atomic_and => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1049,7 +1047,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_or") => { + sym::atomic_or => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1070,7 +1068,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_xor") => { + sym::atomic_xor => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1091,7 +1089,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_nand") => { + sym::atomic_nand => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1112,7 +1110,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_max") => { + sym::atomic_max => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1133,7 +1131,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_umax") => { + sym::atomic_umax => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1154,7 +1152,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_min") => { + sym::atomic_min => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); @@ -1175,7 +1173,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let old = CValue::by_val(old, layout); ret.write_cvalue(fx, old); } - _ if intrinsic.as_str().starts_with("atomic_umin") => { + sym::atomic_umin => { intrinsic_args!(fx, args => (ptr, src); intrinsic); let ptr = ptr.load_scalar(fx); diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index acb4cbaa13f..91f6af7fb93 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} -codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering - codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument @@ -206,8 +204,6 @@ codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be m codegen_ssa_missing_features = add the missing features in a `target_feature` attribute -codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering - codegen_ssa_missing_query_depgraph = found CGU-reuse attribute but `-Zquery-dep-graph` was not specified @@ -374,10 +370,6 @@ codegen_ssa_unexpected_parameter_name = unexpected parameter name codegen_ssa_unknown_archive_kind = Don't know how to build archive of type: {$kind} -codegen_ssa_unknown_atomic_operation = unknown atomic operation - -codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic - codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]` diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 572d7b1e06a..f843347db92 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -796,22 +796,6 @@ pub(crate) struct ShuffleIndicesEvaluation { pub span: Span, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_missing_memory_ordering)] -pub(crate) struct MissingMemoryOrdering; - -#[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_atomic_ordering)] -pub(crate) struct UnknownAtomicOrdering; - -#[derive(Diagnostic)] -#[diag(codegen_ssa_atomic_compare_exchange)] -pub(crate) struct AtomicCompareExchange; - -#[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_atomic_operation)] -pub(crate) struct UnknownAtomicOperation; - #[derive(Diagnostic)] pub enum InvalidMonomorphization<'tcx> { #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)] diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 8c6f52084c2..a3f09f64a3e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -8,9 +8,10 @@ use rustc_span::sym; use super::FunctionCx; use super::operand::OperandRef; use super::place::PlaceRef; +use crate::common::{AtomicRmwBinOp, SynchronizationScope}; use crate::errors::InvalidMonomorphization; use crate::traits::*; -use crate::{MemFlags, errors, meth, size_of_val}; +use crate::{MemFlags, meth, size_of_val}; fn copy_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, @@ -62,7 +63,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let span = source_info.span; let name = bx.tcx().item_name(instance.def_id()); - let name_str = name.as_str(); let fn_args = instance.args; // If we're swapping something that's *not* an `OperandValue::Ref`, @@ -89,14 +89,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - let ret_llval = |bx: &mut Bx, llval| { - if result.layout.ty.is_bool() { - let val = bx.from_immediate(llval); - bx.store_to_place(val, result.val); - } else if !result.layout.ty.is_unit() { - bx.store_to_place(llval, result.val); - } - Ok(()) + let invalid_monomorphization_int_type = |ty| { + bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); + }; + + let parse_atomic_ordering = |ord: ty::Value<'tcx>| { + let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); + discr.to_atomic_ordering() }; let llval = match name { @@ -336,184 +335,145 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - // This requires that atomic intrinsics follow a specific naming pattern: - // "atomic_[_]" - name if let Some(atomic) = name_str.strip_prefix("atomic_") => { - use rustc_middle::ty::AtomicOrdering::*; - - use crate::common::{AtomicRmwBinOp, SynchronizationScope}; + sym::atomic_load => { + let ty = fn_args.type_at(0); + if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { + invalid_monomorphization_int_type(ty); + return Ok(()); + } + let ordering = fn_args.const_at(1).to_value(); + let layout = bx.layout_of(ty); + let source = args[0].immediate(); + bx.atomic_load( + bx.backend_type(layout), + source, + parse_atomic_ordering(ordering), + layout.size, + ) + } + sym::atomic_store => { + let ty = fn_args.type_at(0); + if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { + invalid_monomorphization_int_type(ty); + return Ok(()); + } + let ordering = fn_args.const_at(1).to_value(); + let size = bx.layout_of(ty).size; + let val = args[1].immediate(); + let ptr = args[0].immediate(); + bx.atomic_store(val, ptr, parse_atomic_ordering(ordering), size); + return Ok(()); + } + sym::atomic_cxchg | sym::atomic_cxchgweak => { + let ty = fn_args.type_at(0); + if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { + invalid_monomorphization_int_type(ty); + return Ok(()); + } + let succ_ordering = fn_args.const_at(1).to_value(); + let fail_ordering = fn_args.const_at(2).to_value(); + let weak = name == sym::atomic_cxchgweak; + let dst = args[0].immediate(); + let cmp = args[1].immediate(); + let src = args[2].immediate(); + let (val, success) = bx.atomic_cmpxchg( + dst, + cmp, + src, + parse_atomic_ordering(succ_ordering), + parse_atomic_ordering(fail_ordering), + weak, + ); + let val = bx.from_immediate(val); + let success = bx.from_immediate(success); - let invalid_monomorphization = |ty| { - bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { - span, - name, - ty, - }); - }; + let dest = result.project_field(bx, 0); + bx.store_to_place(val, dest.val); + let dest = result.project_field(bx, 1); + bx.store_to_place(success, dest.val); - let parse_const_generic_ordering = |ord: ty::Value<'tcx>| { - let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); - discr.to_atomic_ordering() + return Ok(()); + } + // These are all AtomicRMW ops + sym::atomic_max | sym::atomic_min => { + let atom_op = if name == sym::atomic_max { + AtomicRmwBinOp::AtomicMax + } else { + AtomicRmwBinOp::AtomicMin }; - // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first. - match name { - sym::atomic_load => { - let ty = fn_args.type_at(0); - let ordering = fn_args.const_at(1).to_value(); - if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) { - invalid_monomorphization(ty); - return Ok(()); - } - let layout = bx.layout_of(ty); - let source = args[0].immediate(); - let llval = bx.atomic_load( - bx.backend_type(layout), - source, - parse_const_generic_ordering(ordering), - layout.size, - ); - - return ret_llval(bx, llval); - } - - // The rest falls back to below. - _ => {} + let ty = fn_args.type_at(0); + if matches!(ty.kind(), ty::Int(_)) { + let ordering = fn_args.const_at(1).to_value(); + let ptr = args[0].immediate(); + let val = args[1].immediate(); + bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + } else { + invalid_monomorphization_int_type(ty); + return Ok(()); } - - let Some((instruction, ordering)) = atomic.split_once('_') else { - bx.sess().dcx().emit_fatal(errors::MissingMemoryOrdering); + } + sym::atomic_umax | sym::atomic_umin => { + let atom_op = if name == sym::atomic_umax { + AtomicRmwBinOp::AtomicUMax + } else { + AtomicRmwBinOp::AtomicUMin }; - let parse_ordering = |bx: &Bx, s| match s { - "relaxed" => Relaxed, - "acquire" => Acquire, - "release" => Release, - "acqrel" => AcqRel, - "seqcst" => SeqCst, - _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOrdering), + let ty = fn_args.type_at(0); + if matches!(ty.kind(), ty::Uint(_)) { + let ordering = fn_args.const_at(1).to_value(); + let ptr = args[0].immediate(); + let val = args[1].immediate(); + bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + } else { + invalid_monomorphization_int_type(ty); + return Ok(()); + } + } + sym::atomic_xchg + | sym::atomic_xadd + | sym::atomic_xsub + | sym::atomic_and + | sym::atomic_nand + | sym::atomic_or + | sym::atomic_xor => { + let atom_op = match name { + sym::atomic_xchg => AtomicRmwBinOp::AtomicXchg, + sym::atomic_xadd => AtomicRmwBinOp::AtomicAdd, + sym::atomic_xsub => AtomicRmwBinOp::AtomicSub, + sym::atomic_and => AtomicRmwBinOp::AtomicAnd, + sym::atomic_nand => AtomicRmwBinOp::AtomicNand, + sym::atomic_or => AtomicRmwBinOp::AtomicOr, + sym::atomic_xor => AtomicRmwBinOp::AtomicXor, + _ => unreachable!(), }; - match instruction { - "cxchg" | "cxchgweak" => { - let Some((success, failure)) = ordering.split_once('_') else { - bx.sess().dcx().emit_fatal(errors::AtomicCompareExchange); - }; - let ty = fn_args.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { - let weak = instruction == "cxchgweak"; - let dst = args[0].immediate(); - let cmp = args[1].immediate(); - let src = args[2].immediate(); - let (val, success) = bx.atomic_cmpxchg( - dst, - cmp, - src, - parse_ordering(bx, success), - parse_ordering(bx, failure), - weak, - ); - let val = bx.from_immediate(val); - let success = bx.from_immediate(success); - - let dest = result.project_field(bx, 0); - bx.store_to_place(val, dest.val); - let dest = result.project_field(bx, 1); - bx.store_to_place(success, dest.val); - } else { - invalid_monomorphization(ty); - } - return Ok(()); - } - - "store" => { - let ty = fn_args.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { - let size = bx.layout_of(ty).size; - let val = args[1].immediate(); - let ptr = args[0].immediate(); - bx.atomic_store(val, ptr, parse_ordering(bx, ordering), size); - } else { - invalid_monomorphization(ty); - } - return Ok(()); - } - - "fence" => { - bx.atomic_fence( - parse_ordering(bx, ordering), - SynchronizationScope::CrossThread, - ); - return Ok(()); - } - - "singlethreadfence" => { - bx.atomic_fence( - parse_ordering(bx, ordering), - SynchronizationScope::SingleThread, - ); - return Ok(()); - } - - // These are all AtomicRMW ops - "max" | "min" => { - let atom_op = if instruction == "max" { - AtomicRmwBinOp::AtomicMax - } else { - AtomicRmwBinOp::AtomicMin - }; - - let ty = fn_args.type_at(0); - if matches!(ty.kind(), ty::Int(_)) { - let ptr = args[0].immediate(); - let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering)) - } else { - invalid_monomorphization(ty); - return Ok(()); - } - } - "umax" | "umin" => { - let atom_op = if instruction == "umax" { - AtomicRmwBinOp::AtomicUMax - } else { - AtomicRmwBinOp::AtomicUMin - }; - - let ty = fn_args.type_at(0); - if matches!(ty.kind(), ty::Uint(_)) { - let ptr = args[0].immediate(); - let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering)) - } else { - invalid_monomorphization(ty); - return Ok(()); - } - } - op => { - let atom_op = match op { - "xchg" => AtomicRmwBinOp::AtomicXchg, - "xadd" => AtomicRmwBinOp::AtomicAdd, - "xsub" => AtomicRmwBinOp::AtomicSub, - "and" => AtomicRmwBinOp::AtomicAnd, - "nand" => AtomicRmwBinOp::AtomicNand, - "or" => AtomicRmwBinOp::AtomicOr, - "xor" => AtomicRmwBinOp::AtomicXor, - _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOperation), - }; - - let ty = fn_args.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { - let ptr = args[0].immediate(); - let val = args[1].immediate(); - bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering)) - } else { - invalid_monomorphization(ty); - return Ok(()); - } - } + let ty = fn_args.type_at(0); + if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() { + let ordering = fn_args.const_at(1).to_value(); + let ptr = args[0].immediate(); + let val = args[1].immediate(); + bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering)) + } else { + invalid_monomorphization_int_type(ty); + return Ok(()); } } + sym::atomic_fence => { + let ordering = fn_args.const_at(0).to_value(); + bx.atomic_fence(parse_atomic_ordering(ordering), SynchronizationScope::CrossThread); + return Ok(()); + } + + sym::atomic_singlethreadfence => { + let ordering = fn_args.const_at(0).to_value(); + bx.atomic_fence( + parse_atomic_ordering(ordering), + SynchronizationScope::SingleThread, + ); + return Ok(()); + } sym::nontemporal_store => { let dst = args[0].deref(bx.cx()); @@ -556,7 +516,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; - ret_llval(bx, llval) + if result.layout.ty.is_bool() { + let val = bx.from_immediate(llval); + bx.store_to_place(val, result.val); + } else if !result.layout.ty.is_unit() { + bx.store_to_place(llval, result.val); + } + Ok(()) } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md index be459d040c2..9c63798ded7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0092.md +++ b/compiler/rustc_error_codes/src/error_codes/E0092.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + An undefined atomic operation function was declared. Erroneous code example: -```compile_fail,E0092 +```ignore (no longer emitted) #![feature(intrinsics)] #![allow(internal_features)] @@ -12,13 +14,4 @@ unsafe fn atomic_foo(); // error: unrecognized atomic operation ``` Please check you didn't make a mistake in the function's name. All intrinsic -functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in -`library/core/src/intrinsics.rs` in the Rust source code. Example: - -``` -#![feature(intrinsics)] -#![allow(internal_features)] - -#[rustc_intrinsic] -unsafe fn atomic_fence_seqcst(); // ok! -``` +functions are defined in `library/core/src/intrinsics` in the Rust source code. diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md index 9929a069927..3552c2db4cc 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0093.md +++ b/compiler/rustc_error_codes/src/error_codes/E0093.md @@ -17,19 +17,4 @@ fn main() { ``` Please check you didn't make a mistake in the function's name. All intrinsic -functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in -`library/core/src/intrinsics.rs` in the Rust source code. Example: - -``` -#![feature(intrinsics)] -#![allow(internal_features)] - -#[rustc_intrinsic] -unsafe fn atomic_fence_seqcst(); // ok! - -fn main() { - unsafe { - atomic_fence_seqcst(); - } -} -``` +functions are defined in `library/core/src/intrinsics` in the Rust source code. diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md index 9b8131a061e..cc66e067990 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0622.md +++ b/compiler/rustc_error_codes/src/error_codes/E0622.md @@ -4,7 +4,7 @@ An intrinsic was declared without being a function. Erroneous code example: -```no_run +```ignore (no longer emitted) #![feature(intrinsics)] #![allow(internal_features)] @@ -21,7 +21,7 @@ An intrinsic is a function available for use in a given programming language whose implementation is handled specially by the compiler. In order to fix this error, just declare a function. Example: -```no_run +```ignore (no longer emitted) #![feature(intrinsics)] #![allow(internal_features)] diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index a3a0e276f74..4fcd9f8a646 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -565,10 +565,6 @@ hir_analysis_unconstrained_generic_parameter = the {$param_def_kind} `{$param_na hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same {$what} -hir_analysis_unrecognized_atomic_operation = - unrecognized atomic operation function: `{$op}` - .label = unrecognized atomic operation - hir_analysis_unrecognized_intrinsic_function = unrecognized intrinsic function: `{$name}` .label = unrecognized intrinsic diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 234520c1583..d8080d2537b 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -9,10 +9,7 @@ use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol, sym}; use crate::check::check_function_signature; -use crate::errors::{ - UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, - WrongNumberOfGenericArgumentsToIntrinsic, -}; +use crate::errors::{UnrecognizedIntrinsicFunction, WrongNumberOfGenericArgumentsToIntrinsic}; fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, @@ -172,7 +169,6 @@ pub(crate) fn check_intrinsic_type( Ty::new_error_with_message(tcx, span, "expected param") } }; - let name_str = intrinsic_name.as_str(); let bound_vars = tcx.mk_bound_variable_kinds(&[ ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon), @@ -198,32 +194,9 @@ pub(crate) fn check_intrinsic_type( (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty) }; - let (n_tps, n_lts, n_cts, inputs, output, safety) = if name_str.starts_with("atomic_") { - let split: Vec<&str> = name_str.split('_').collect(); - assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format"); - - // Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use - // string ops to strip the suffixes, because the variants all get the same treatment here. - let (n_tps, n_cts, inputs, output) = match split[1] { - "cxchg" | "cxchgweak" => ( - 1, - 0, - vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)], - Ty::new_tup(tcx, &[param(0), tcx.types.bool]), - ), - "load" => (1, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), - "store" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit), - - "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" - | "umin" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)), - "fence" | "singlethreadfence" => (0, 0, Vec::new(), tcx.types.unit), - op => { - tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op }); - return; - } - }; - (n_tps, 0, n_cts, inputs, output, hir::Safety::Unsafe) - } else if intrinsic_name == sym::contract_check_ensures { + let (n_tps, n_lts, n_cts, inputs, output, safety) = if intrinsic_name + == sym::contract_check_ensures + { // contract_check_ensures::(Ret, C) -> Ret // where C: for<'a> Fn(&'a Ret) -> bool, // @@ -694,6 +667,30 @@ pub(crate) fn check_intrinsic_type( sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)), + sym::atomic_cxchg | sym::atomic_cxchgweak => ( + 1, + 2, + vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)], + Ty::new_tup(tcx, &[param(0), tcx.types.bool]), + ), + sym::atomic_load => (1, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), + sym::atomic_store => { + (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) + } + + sym::atomic_xchg + | sym::atomic_xadd + | sym::atomic_xsub + | sym::atomic_and + | sym::atomic_nand + | sym::atomic_or + | sym::atomic_xor + | sym::atomic_max + | sym::atomic_min + | sym::atomic_umax + | sym::atomic_umin => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)), + sym::atomic_fence | sym::atomic_singlethreadfence => (0, 1, Vec::new(), tcx.types.unit), + other => { tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other }); return; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 152714b3407..a27d1ed6c53 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -161,15 +161,6 @@ pub(crate) enum AssocItemNotFoundSugg<'a> { }, } -#[derive(Diagnostic)] -#[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)] -pub(crate) struct UnrecognizedAtomicOperation<'a> { - #[primary_span] - #[label] - pub span: Span, - pub op: &'a str, -} - #[derive(Diagnostic)] #[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = E0094)] pub(crate) struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4e842a8f93a..d66f98871b9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -515,8 +515,24 @@ symbols! { async_iterator_poll_next, async_trait_bounds, atomic, + atomic_and, + atomic_cxchg, + atomic_cxchgweak, + atomic_fence, atomic_load, + atomic_max, + atomic_min, atomic_mod, + atomic_nand, + atomic_or, + atomic_singlethreadfence, + atomic_store, + atomic_umax, + atomic_umin, + atomic_xadd, + atomic_xchg, + atomic_xor, + atomic_xsub, atomics, att_syntax, attr, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index bde90464acb..954c3754084 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -84,578 +84,97 @@ pub enum AtomicOrdering { /// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Relaxed`] as both the success and failure parameters. +/// [`atomic`] types via the `compare_exchange` method. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Acquire`] as both the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange` method by passing -/// [`Ordering::SeqCst`] as both the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Relaxed`] as both the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_relaxed_relaxed( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_relaxed_acquire( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acquire_relaxed( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Acquire`] as both the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acquire_acquire( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_release_relaxed( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_release_acquire( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); -/// Stores a value if the current value is the same as the `old` value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `compare_exchange_weak` method by passing -/// [`Ordering::SeqCst`] as both the success and failure parameters. -/// For example, [`AtomicBool::compare_exchange_weak`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - -/// Loads the current value of the pointer. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `load` method. For example, [`AtomicBool::load`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_load(src: *const T) -> T; - -/// Stores the value at the specified memory location. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `store` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T); -/// Stores the value at the specified memory location. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `store` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_store_release(dst: *mut T, val: T); -/// Stores the value at the specified memory location. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `store` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_store_relaxed(dst: *mut T, val: T); - -/// Stores the value at the specified memory location, returning the old value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `swap` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; -/// Stores the value at the specified memory location, returning the old value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `swap` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; -/// Stores the value at the specified memory location, returning the old value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `swap` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T; -/// Stores the value at the specified memory location, returning the old value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `swap` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xchg_acqrel(dst: *mut T, src: T) -> T; -/// Stores the value at the specified memory location, returning the old value. -/// `T` must be an integer or pointer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `swap` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xchg_relaxed(dst: *mut T, src: T) -> T; - -/// Adds to the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_add` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; -/// Adds to the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_add` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; -/// Adds to the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_add` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T; -/// Adds to the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_add` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xadd_acqrel(dst: *mut T, src: T) -> T; -/// Adds to the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_add` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xadd_relaxed(dst: *mut T, src: T) -> T; - -/// Subtract from the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_sub` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; -/// Subtract from the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_sub` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; -/// Subtract from the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_sub` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T; -/// Subtract from the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. +pub unsafe fn atomic_cxchg< + T: Copy, + const ORD_SUCC: AtomicOrdering, + const ORD_FAIL: AtomicOrdering, +>( + dst: *mut T, + old: T, + src: T, +) -> (T, bool); + +/// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. The comparison may spuriously fail. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_sub` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +/// [`atomic`] types via the `compare_exchange_weak` method. +/// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_acqrel(dst: *mut T, src: T) -> T; -/// Subtract from the current value, returning the previous value. +pub unsafe fn atomic_cxchgweak< + T: Copy, + const ORD_SUCC: AtomicOrdering, + const ORD_FAIL: AtomicOrdering, +>( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool); + +/// Loads the current value of the pointer. /// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_sub` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +/// [`atomic`] types via the `load` method. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_load(src: *const T) -> T; -/// Bitwise and with the current value, returning the previous value. +/// Stores the value at the specified memory location. /// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_and` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`]. +/// [`atomic`] types via the `store` method. For example, [`AtomicBool::store`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_seqcst(dst: *mut T, src: T) -> T; -/// Bitwise and with the current value, returning the previous value. +pub unsafe fn atomic_store(dst: *mut T, val: T); + +/// Stores the value at the specified memory location, returning the old value. /// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_and` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`]. +/// [`atomic`] types via the `swap` method. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_acquire(dst: *mut T, src: T) -> T; -/// Bitwise and with the current value, returning the previous value. +pub unsafe fn atomic_xchg(dst: *mut T, src: T) -> T; + +/// Adds to the current value, returning the previous value. /// `T` must be an integer or pointer type. /// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_and` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`]. +/// [`atomic`] types via the `fetch_add` method. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_release(dst: *mut T, src: T) -> T; -/// Bitwise and with the current value, returning the previous value. +pub unsafe fn atomic_xadd(dst: *mut T, src: T) -> T; + +/// Subtract from the current value, returning the previous value. /// `T` must be an integer or pointer type. /// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_and` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`]. +/// [`atomic`] types via the `fetch_sub` method. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_acqrel(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_xsub(dst: *mut T, src: T) -> T; + /// Bitwise and with the current value, returning the previous value. /// `T` must be an integer or pointer type. /// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_and` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`]. +/// [`atomic`] types via the `fetch_and` method. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_and(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// `T` must be an integer or pointer type. @@ -663,55 +182,10 @@ pub unsafe fn atomic_and_relaxed(dst: *mut T, src: T) -> T; /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`AtomicBool`] type via the `fetch_nand` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_nand_seqcst(dst: *mut T, src: T) -> T; -/// Bitwise nand with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`AtomicBool`] type via the `fetch_nand` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_nand_acquire(dst: *mut T, src: T) -> T; -/// Bitwise nand with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`AtomicBool`] type via the `fetch_nand` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_nand_release(dst: *mut T, src: T) -> T; -/// Bitwise nand with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`AtomicBool`] type via the `fetch_nand` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_nand_acqrel(dst: *mut T, src: T) -> T; -/// Bitwise nand with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`AtomicBool`] type via the `fetch_nand` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +/// [`AtomicBool`] type via the `fetch_nand` method. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_nand(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// `T` must be an integer or pointer type. @@ -719,55 +193,10 @@ pub unsafe fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_or` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_or_seqcst(dst: *mut T, src: T) -> T; -/// Bitwise or with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_or` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_or_acquire(dst: *mut T, src: T) -> T; -/// Bitwise or with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_or` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_or_release(dst: *mut T, src: T) -> T; -/// Bitwise or with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_or` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_or_acqrel(dst: *mut T, src: T) -> T; -/// Bitwise or with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_or` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`]. +/// [`atomic`] types via the `fetch_or` method. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_or(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// `T` must be an integer or pointer type. @@ -775,325 +204,62 @@ pub unsafe fn atomic_or_relaxed(dst: *mut T, src: T) -> T; /// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_xor` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xor_seqcst(dst: *mut T, src: T) -> T; -/// Bitwise xor with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_xor` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xor_acquire(dst: *mut T, src: T) -> T; -/// Bitwise xor with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_xor` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xor_release(dst: *mut T, src: T) -> T; -/// Bitwise xor with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_xor` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_xor_acqrel(dst: *mut T, src: T) -> T; -/// Bitwise xor with the current value, returning the previous value. -/// `T` must be an integer or pointer type. -/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new -/// value stored at `*dst` will have the provenance of the old value stored there. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] types via the `fetch_xor` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +/// [`atomic`] types via the `fetch_xor` method. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_xor(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. /// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_max` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_max_seqcst(dst: *mut T, src: T) -> T; -/// Maximum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_max` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_max_acquire(dst: *mut T, src: T) -> T; -/// Maximum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_max` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_max_release(dst: *mut T, src: T) -> T; -/// Maximum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_max` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_max_acqrel(dst: *mut T, src: T) -> T; -/// Maximum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_max` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`]. +/// [`atomic`] signed integer types via the `fetch_max` method. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_max(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_min` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_min_seqcst(dst: *mut T, src: T) -> T; -/// Minimum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_min` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_min_acquire(dst: *mut T, src: T) -> T; -/// Minimum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_min` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_min_release(dst: *mut T, src: T) -> T; -/// Minimum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_min` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_min_acqrel(dst: *mut T, src: T) -> T; -/// Minimum with the current value using a signed comparison. -/// `T` must be a signed integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] signed integer types via the `fetch_min` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`]. +/// [`atomic`] signed integer types via the `fetch_min` method. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_min(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_min` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umin_seqcst(dst: *mut T, src: T) -> T; -/// Minimum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_min` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umin_acquire(dst: *mut T, src: T) -> T; -/// Minimum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_min` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umin_release(dst: *mut T, src: T) -> T; -/// Minimum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_min` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umin_acqrel(dst: *mut T, src: T) -> T; -/// Minimum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_min` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`]. +/// [`atomic`] unsigned integer types via the `fetch_min` method. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_umin(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_max` method by passing -/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umax_seqcst(dst: *mut T, src: T) -> T; -/// Maximum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_max` method by passing -/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umax_acquire(dst: *mut T, src: T) -> T; -/// Maximum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_max` method by passing -/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umax_release(dst: *mut T, src: T) -> T; -/// Maximum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_max` method by passing -/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`]. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_umax_acqrel(dst: *mut T, src: T) -> T; -/// Maximum with the current value using an unsigned comparison. -/// `T` must be an unsigned integer type. -/// -/// The stabilized version of this intrinsic is available on the -/// [`atomic`] unsigned integer types via the `fetch_max` method by passing -/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`]. +/// [`atomic`] unsigned integer types via the `fetch_max` method. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_relaxed(dst: *mut T, src: T) -> T; +pub unsafe fn atomic_umax(dst: *mut T, src: T) -> T; /// An atomic fence. /// /// The stabilized version of this intrinsic is available in -/// [`atomic::fence`] by passing [`Ordering::SeqCst`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_fence_seqcst(); -/// An atomic fence. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::fence`] by passing [`Ordering::Acquire`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_fence_acquire(); -/// An atomic fence. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::fence`] by passing [`Ordering::Release`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_fence_release(); -/// An atomic fence. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::fence`] by passing [`Ordering::AcqRel`] -/// as the `order`. +/// [`atomic::fence`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_fence_acqrel(); +pub unsafe fn atomic_fence(); -/// A compiler-only memory barrier. -/// -/// Memory accesses will never be reordered across this barrier by the -/// compiler, but no instructions will be emitted for it. This is -/// appropriate for operations on the same thread that may be preempted, -/// such as when interacting with signal handlers. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_seqcst(); -/// A compiler-only memory barrier. -/// -/// Memory accesses will never be reordered across this barrier by the -/// compiler, but no instructions will be emitted for it. This is -/// appropriate for operations on the same thread that may be preempted, -/// such as when interacting with signal handlers. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_acquire(); -/// A compiler-only memory barrier. -/// -/// Memory accesses will never be reordered across this barrier by the -/// compiler, but no instructions will be emitted for it. This is -/// appropriate for operations on the same thread that may be preempted, -/// such as when interacting with signal handlers. -/// -/// The stabilized version of this intrinsic is available in -/// [`atomic::compiler_fence`] by passing [`Ordering::Release`] -/// as the `order`. -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_release(); -/// A compiler-only memory barrier. -/// -/// Memory accesses will never be reordered across this barrier by the -/// compiler, but no instructions will be emitted for it. This is -/// appropriate for operations on the same thread that may be preempted, -/// such as when interacting with signal handlers. +/// An atomic fence for synchronization within a single thread. /// /// The stabilized version of this intrinsic is available in -/// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`] -/// as the `order`. +/// [`atomic::compiler_fence`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_acqrel(); +pub unsafe fn atomic_singlethreadfence(); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ea459f6d92d..453687a949b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -245,6 +245,7 @@ use self::Ordering::*; use crate::cell::UnsafeCell; use crate::hint::spin_loop; +use crate::intrinsics::AtomicOrdering as AO; use crate::{fmt, intrinsics}; trait Sealed {} @@ -3811,9 +3812,9 @@ unsafe fn atomic_store(dst: *mut T, val: T, order: Ordering) { // SAFETY: the caller must uphold the safety contract for `atomic_store`. unsafe { match order { - Relaxed => intrinsics::atomic_store_relaxed(dst, val), - Release => intrinsics::atomic_store_release(dst, val), - SeqCst => intrinsics::atomic_store_seqcst(dst, val), + Relaxed => intrinsics::atomic_store::(dst, val), + Release => intrinsics::atomic_store::(dst, val), + SeqCst => intrinsics::atomic_store::(dst, val), Acquire => panic!("there is no such thing as an acquire store"), AcqRel => panic!("there is no such thing as an acquire-release store"), } @@ -3823,13 +3824,12 @@ unsafe fn atomic_store(dst: *mut T, val: T, order: Ordering) { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { - use intrinsics::AtomicOrdering; // SAFETY: the caller must uphold the safety contract for `atomic_load`. unsafe { match order { - Relaxed => intrinsics::atomic_load::(dst), - Acquire => intrinsics::atomic_load::(dst), - SeqCst => intrinsics::atomic_load::(dst), + Relaxed => intrinsics::atomic_load::(dst), + Acquire => intrinsics::atomic_load::(dst), + SeqCst => intrinsics::atomic_load::(dst), Release => panic!("there is no such thing as a release load"), AcqRel => panic!("there is no such thing as an acquire-release load"), } @@ -3843,11 +3843,11 @@ unsafe fn atomic_swap(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_swap`. unsafe { match order { - Relaxed => intrinsics::atomic_xchg_relaxed(dst, val), - Acquire => intrinsics::atomic_xchg_acquire(dst, val), - Release => intrinsics::atomic_xchg_release(dst, val), - AcqRel => intrinsics::atomic_xchg_acqrel(dst, val), - SeqCst => intrinsics::atomic_xchg_seqcst(dst, val), + Relaxed => intrinsics::atomic_xchg::(dst, val), + Acquire => intrinsics::atomic_xchg::(dst, val), + Release => intrinsics::atomic_xchg::(dst, val), + AcqRel => intrinsics::atomic_xchg::(dst, val), + SeqCst => intrinsics::atomic_xchg::(dst, val), } } } @@ -3860,11 +3860,11 @@ unsafe fn atomic_add(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_add`. unsafe { match order { - Relaxed => intrinsics::atomic_xadd_relaxed(dst, val), - Acquire => intrinsics::atomic_xadd_acquire(dst, val), - Release => intrinsics::atomic_xadd_release(dst, val), - AcqRel => intrinsics::atomic_xadd_acqrel(dst, val), - SeqCst => intrinsics::atomic_xadd_seqcst(dst, val), + Relaxed => intrinsics::atomic_xadd::(dst, val), + Acquire => intrinsics::atomic_xadd::(dst, val), + Release => intrinsics::atomic_xadd::(dst, val), + AcqRel => intrinsics::atomic_xadd::(dst, val), + SeqCst => intrinsics::atomic_xadd::(dst, val), } } } @@ -3877,11 +3877,11 @@ unsafe fn atomic_sub(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_sub`. unsafe { match order { - Relaxed => intrinsics::atomic_xsub_relaxed(dst, val), - Acquire => intrinsics::atomic_xsub_acquire(dst, val), - Release => intrinsics::atomic_xsub_release(dst, val), - AcqRel => intrinsics::atomic_xsub_acqrel(dst, val), - SeqCst => intrinsics::atomic_xsub_seqcst(dst, val), + Relaxed => intrinsics::atomic_xsub::(dst, val), + Acquire => intrinsics::atomic_xsub::(dst, val), + Release => intrinsics::atomic_xsub::(dst, val), + AcqRel => intrinsics::atomic_xsub::(dst, val), + SeqCst => intrinsics::atomic_xsub::(dst, val), } } } @@ -3902,21 +3902,51 @@ pub unsafe fn atomic_compare_exchange( // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`. let (val, ok) = unsafe { match (success, failure) { - (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new), - (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), - (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), - (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new), - (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new), - (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), - (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new), - (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), - (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), - (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new), - (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new), - (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), - (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new), - (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new), - (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new), + (Relaxed, Relaxed) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Relaxed, Acquire) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Relaxed, SeqCst) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Acquire, Relaxed) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Acquire, Acquire) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Acquire, SeqCst) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Release, Relaxed) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Release, Acquire) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (Release, SeqCst) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (AcqRel, Relaxed) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (AcqRel, Acquire) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (AcqRel, SeqCst) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (SeqCst, Relaxed) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (SeqCst, Acquire) => { + intrinsics::atomic_cxchg::(dst, old, new) + } + (SeqCst, SeqCst) => { + intrinsics::atomic_cxchg::(dst, old, new) + } (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"), (_, Release) => panic!("there is no such thing as a release failure ordering"), } @@ -3937,21 +3967,51 @@ unsafe fn atomic_compare_exchange_weak( // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`. let (val, ok) = unsafe { match (success, failure) { - (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new), - (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new), - (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new), - (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new), - (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new), - (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new), - (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new), - (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new), - (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new), - (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new), - (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new), - (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new), - (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new), - (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new), - (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new), + (Relaxed, Relaxed) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Relaxed, Acquire) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Relaxed, SeqCst) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Acquire, Relaxed) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Acquire, Acquire) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Acquire, SeqCst) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Release, Relaxed) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Release, Acquire) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (Release, SeqCst) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (AcqRel, Relaxed) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (AcqRel, Acquire) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (AcqRel, SeqCst) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (SeqCst, Relaxed) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (SeqCst, Acquire) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } + (SeqCst, SeqCst) => { + intrinsics::atomic_cxchgweak::(dst, old, new) + } (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"), (_, Release) => panic!("there is no such thing as a release failure ordering"), } @@ -3966,11 +4026,11 @@ unsafe fn atomic_and(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_and` unsafe { match order { - Relaxed => intrinsics::atomic_and_relaxed(dst, val), - Acquire => intrinsics::atomic_and_acquire(dst, val), - Release => intrinsics::atomic_and_release(dst, val), - AcqRel => intrinsics::atomic_and_acqrel(dst, val), - SeqCst => intrinsics::atomic_and_seqcst(dst, val), + Relaxed => intrinsics::atomic_and::(dst, val), + Acquire => intrinsics::atomic_and::(dst, val), + Release => intrinsics::atomic_and::(dst, val), + AcqRel => intrinsics::atomic_and::(dst, val), + SeqCst => intrinsics::atomic_and::(dst, val), } } } @@ -3982,11 +4042,11 @@ unsafe fn atomic_nand(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_nand` unsafe { match order { - Relaxed => intrinsics::atomic_nand_relaxed(dst, val), - Acquire => intrinsics::atomic_nand_acquire(dst, val), - Release => intrinsics::atomic_nand_release(dst, val), - AcqRel => intrinsics::atomic_nand_acqrel(dst, val), - SeqCst => intrinsics::atomic_nand_seqcst(dst, val), + Relaxed => intrinsics::atomic_nand::(dst, val), + Acquire => intrinsics::atomic_nand::(dst, val), + Release => intrinsics::atomic_nand::(dst, val), + AcqRel => intrinsics::atomic_nand::(dst, val), + SeqCst => intrinsics::atomic_nand::(dst, val), } } } @@ -3998,11 +4058,11 @@ unsafe fn atomic_or(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_or` unsafe { match order { - SeqCst => intrinsics::atomic_or_seqcst(dst, val), - Acquire => intrinsics::atomic_or_acquire(dst, val), - Release => intrinsics::atomic_or_release(dst, val), - AcqRel => intrinsics::atomic_or_acqrel(dst, val), - Relaxed => intrinsics::atomic_or_relaxed(dst, val), + SeqCst => intrinsics::atomic_or::(dst, val), + Acquire => intrinsics::atomic_or::(dst, val), + Release => intrinsics::atomic_or::(dst, val), + AcqRel => intrinsics::atomic_or::(dst, val), + Relaxed => intrinsics::atomic_or::(dst, val), } } } @@ -4014,16 +4074,16 @@ unsafe fn atomic_xor(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_xor` unsafe { match order { - SeqCst => intrinsics::atomic_xor_seqcst(dst, val), - Acquire => intrinsics::atomic_xor_acquire(dst, val), - Release => intrinsics::atomic_xor_release(dst, val), - AcqRel => intrinsics::atomic_xor_acqrel(dst, val), - Relaxed => intrinsics::atomic_xor_relaxed(dst, val), + SeqCst => intrinsics::atomic_xor::(dst, val), + Acquire => intrinsics::atomic_xor::(dst, val), + Release => intrinsics::atomic_xor::(dst, val), + AcqRel => intrinsics::atomic_xor::(dst, val), + Relaxed => intrinsics::atomic_xor::(dst, val), } } } -/// returns the max value (signed comparison) +/// Updates `*dst` to the max value of `val` and the old value (signed comparison) #[inline] #[cfg(target_has_atomic)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4031,16 +4091,16 @@ unsafe fn atomic_max(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_max` unsafe { match order { - Relaxed => intrinsics::atomic_max_relaxed(dst, val), - Acquire => intrinsics::atomic_max_acquire(dst, val), - Release => intrinsics::atomic_max_release(dst, val), - AcqRel => intrinsics::atomic_max_acqrel(dst, val), - SeqCst => intrinsics::atomic_max_seqcst(dst, val), + Relaxed => intrinsics::atomic_max::(dst, val), + Acquire => intrinsics::atomic_max::(dst, val), + Release => intrinsics::atomic_max::(dst, val), + AcqRel => intrinsics::atomic_max::(dst, val), + SeqCst => intrinsics::atomic_max::(dst, val), } } } -/// returns the min value (signed comparison) +/// Updates `*dst` to the min value of `val` and the old value (signed comparison) #[inline] #[cfg(target_has_atomic)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4048,16 +4108,16 @@ unsafe fn atomic_min(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_min` unsafe { match order { - Relaxed => intrinsics::atomic_min_relaxed(dst, val), - Acquire => intrinsics::atomic_min_acquire(dst, val), - Release => intrinsics::atomic_min_release(dst, val), - AcqRel => intrinsics::atomic_min_acqrel(dst, val), - SeqCst => intrinsics::atomic_min_seqcst(dst, val), + Relaxed => intrinsics::atomic_min::(dst, val), + Acquire => intrinsics::atomic_min::(dst, val), + Release => intrinsics::atomic_min::(dst, val), + AcqRel => intrinsics::atomic_min::(dst, val), + SeqCst => intrinsics::atomic_min::(dst, val), } } } -/// returns the max value (unsigned comparison) +/// Updates `*dst` to the max value of `val` and the old value (unsigned comparison) #[inline] #[cfg(target_has_atomic)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4065,16 +4125,16 @@ unsafe fn atomic_umax(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_umax` unsafe { match order { - Relaxed => intrinsics::atomic_umax_relaxed(dst, val), - Acquire => intrinsics::atomic_umax_acquire(dst, val), - Release => intrinsics::atomic_umax_release(dst, val), - AcqRel => intrinsics::atomic_umax_acqrel(dst, val), - SeqCst => intrinsics::atomic_umax_seqcst(dst, val), + Relaxed => intrinsics::atomic_umax::(dst, val), + Acquire => intrinsics::atomic_umax::(dst, val), + Release => intrinsics::atomic_umax::(dst, val), + AcqRel => intrinsics::atomic_umax::(dst, val), + SeqCst => intrinsics::atomic_umax::(dst, val), } } } -/// returns the min value (unsigned comparison) +/// Updates `*dst` to the min value of `val` and the old value (unsigned comparison) #[inline] #[cfg(target_has_atomic)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4082,11 +4142,11 @@ unsafe fn atomic_umin(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_umin` unsafe { match order { - Relaxed => intrinsics::atomic_umin_relaxed(dst, val), - Acquire => intrinsics::atomic_umin_acquire(dst, val), - Release => intrinsics::atomic_umin_release(dst, val), - AcqRel => intrinsics::atomic_umin_acqrel(dst, val), - SeqCst => intrinsics::atomic_umin_seqcst(dst, val), + Relaxed => intrinsics::atomic_umin::(dst, val), + Acquire => intrinsics::atomic_umin::(dst, val), + Release => intrinsics::atomic_umin::(dst, val), + AcqRel => intrinsics::atomic_umin::(dst, val), + SeqCst => intrinsics::atomic_umin::(dst, val), } } } @@ -4178,10 +4238,10 @@ pub fn fence(order: Ordering) { // SAFETY: using an atomic fence is safe. unsafe { match order { - Acquire => intrinsics::atomic_fence_acquire(), - Release => intrinsics::atomic_fence_release(), - AcqRel => intrinsics::atomic_fence_acqrel(), - SeqCst => intrinsics::atomic_fence_seqcst(), + Acquire => intrinsics::atomic_fence::<{ AO::Acquire }>(), + Release => intrinsics::atomic_fence::<{ AO::Release }>(), + AcqRel => intrinsics::atomic_fence::<{ AO::AcqRel }>(), + SeqCst => intrinsics::atomic_fence::<{ AO::SeqCst }>(), Relaxed => panic!("there is no such thing as a relaxed fence"), } } @@ -4256,11 +4316,11 @@ pub fn compiler_fence(order: Ordering) { // SAFETY: using an atomic fence is safe. unsafe { match order { - Acquire => intrinsics::atomic_singlethreadfence_acquire(), - Release => intrinsics::atomic_singlethreadfence_release(), - AcqRel => intrinsics::atomic_singlethreadfence_acqrel(), - SeqCst => intrinsics::atomic_singlethreadfence_seqcst(), - Relaxed => panic!("there is no such thing as a relaxed compiler fence"), + Acquire => intrinsics::atomic_singlethreadfence::<{ AO::Acquire }>(), + Release => intrinsics::atomic_singlethreadfence::<{ AO::Release }>(), + AcqRel => intrinsics::atomic_singlethreadfence::<{ AO::AcqRel }>(), + SeqCst => intrinsics::atomic_singlethreadfence::<{ AO::SeqCst }>(), + Relaxed => panic!("there is no such thing as a relaxed fence"), } } } diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 3794b56c089..003ac4f0cd3 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -291,7 +291,7 @@ cfg_if::cfg_if! { } pub(crate) unsafe fn panic(data: Box) -> u32 { - use core::intrinsics::atomic_store_seqcst; + use core::intrinsics::{AtomicOrdering, atomic_store}; // _CxxThrowException executes entirely on this stack frame, so there's no // need to otherwise transfer `data` to the heap. We just pass a stack @@ -325,23 +325,23 @@ pub(crate) unsafe fn panic(data: Box) -> u32 { // In any case, we basically need to do something like this until we can // express more operations in statics (and we may never be able to). unsafe { - atomic_store_seqcst( + atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut THROW_INFO.pmfnUnwind).cast(), ptr_t::new(exception_cleanup as *mut u8).raw(), ); - atomic_store_seqcst( + atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut THROW_INFO.pCatchableTypeArray).cast(), ptr_t::new((&raw mut CATCHABLE_TYPE_ARRAY).cast()).raw(), ); - atomic_store_seqcst( + atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(), ptr_t::new((&raw mut CATCHABLE_TYPE).cast()).raw(), ); - atomic_store_seqcst( + atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut CATCHABLE_TYPE.pType).cast(), ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(), ); - atomic_store_seqcst( + atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut CATCHABLE_TYPE.copyFunction).cast(), ptr_t::new(exception_copy as *mut u8).raw(), ); diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index a61226eeed9..0a59a707a10 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); - let intrinsic_structure: Vec<_> = intrinsic_name.split('_').collect(); + let get_ord_at = |i: usize| { + let ordering = generic_args.const_at(i).to_value(); + ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering() + }; - fn read_ord(ord: &str) -> AtomicReadOrd { + fn read_ord(ord: AtomicOrdering) -> AtomicReadOrd { match ord { - "seqcst" => AtomicReadOrd::SeqCst, - "acquire" => AtomicReadOrd::Acquire, - "relaxed" => AtomicReadOrd::Relaxed, - _ => panic!("invalid read ordering `{ord}`"), - } - } - - fn read_ord_const_generic(o: AtomicOrdering) -> AtomicReadOrd { - match o { AtomicOrdering::SeqCst => AtomicReadOrd::SeqCst, AtomicOrdering::Acquire => AtomicReadOrd::Acquire, AtomicOrdering::Relaxed => AtomicReadOrd::Relaxed, - _ => panic!("invalid read ordering `{o:?}`"), + _ => panic!("invalid read ordering `{ord:?}`"), } } - fn write_ord(ord: &str) -> AtomicWriteOrd { + fn write_ord(ord: AtomicOrdering) -> AtomicWriteOrd { match ord { - "seqcst" => AtomicWriteOrd::SeqCst, - "release" => AtomicWriteOrd::Release, - "relaxed" => AtomicWriteOrd::Relaxed, - _ => panic!("invalid write ordering `{ord}`"), + AtomicOrdering::SeqCst => AtomicWriteOrd::SeqCst, + AtomicOrdering::Release => AtomicWriteOrd::Release, + AtomicOrdering::Relaxed => AtomicWriteOrd::Relaxed, + _ => panic!("invalid write ordering `{ord:?}`"), } } - fn rw_ord(ord: &str) -> AtomicRwOrd { + fn rw_ord(ord: AtomicOrdering) -> AtomicRwOrd { match ord { - "seqcst" => AtomicRwOrd::SeqCst, - "acqrel" => AtomicRwOrd::AcqRel, - "acquire" => AtomicRwOrd::Acquire, - "release" => AtomicRwOrd::Release, - "relaxed" => AtomicRwOrd::Relaxed, - _ => panic!("invalid read-write ordering `{ord}`"), + AtomicOrdering::SeqCst => AtomicRwOrd::SeqCst, + AtomicOrdering::AcqRel => AtomicRwOrd::AcqRel, + AtomicOrdering::Acquire => AtomicRwOrd::Acquire, + AtomicOrdering::Release => AtomicRwOrd::Release, + AtomicOrdering::Relaxed => AtomicRwOrd::Relaxed, } } - fn fence_ord(ord: &str) -> AtomicFenceOrd { + fn fence_ord(ord: AtomicOrdering) -> AtomicFenceOrd { match ord { - "seqcst" => AtomicFenceOrd::SeqCst, - "acqrel" => AtomicFenceOrd::AcqRel, - "acquire" => AtomicFenceOrd::Acquire, - "release" => AtomicFenceOrd::Release, - _ => panic!("invalid fence ordering `{ord}`"), + AtomicOrdering::SeqCst => AtomicFenceOrd::SeqCst, + AtomicOrdering::AcqRel => AtomicFenceOrd::AcqRel, + AtomicOrdering::Acquire => AtomicFenceOrd::Acquire, + AtomicOrdering::Release => AtomicFenceOrd::Release, + _ => panic!("invalid fence ordering `{ord:?}`"), } } - match &*intrinsic_structure { - // New-style intrinsics that use const generics - ["load"] => { - let ordering = generic_args.const_at(1).to_value(); - let ordering = - ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering(); - this.atomic_load(args, dest, read_ord_const_generic(ordering))?; + match intrinsic_name { + "load" => { + let ord = get_ord_at(1); + this.atomic_load(args, dest, read_ord(ord))?; + } + + "store" => { + let ord = get_ord_at(1); + this.atomic_store(args, write_ord(ord))? } - // Old-style intrinsics that have the ordering in the intrinsic name - ["store", ord] => this.atomic_store(args, write_ord(ord))?, - - ["fence", ord] => this.atomic_fence_intrinsic(args, fence_ord(ord))?, - ["singlethreadfence", ord] => this.compiler_fence_intrinsic(args, fence_ord(ord))?, - - ["xchg", ord] => this.atomic_exchange(args, dest, rw_ord(ord))?, - ["cxchg", ord1, ord2] => - this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?, - ["cxchgweak", ord1, ord2] => - this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?, - - ["or", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?, - ["xor", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?, - ["and", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?, - ["nand", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?, - ["xadd", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?, - ["xsub", ord] => - this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?, - ["min", ord] => { + "fence" => { + let ord = get_ord_at(0); + this.atomic_fence_intrinsic(args, fence_ord(ord))? + } + "singlethreadfence" => { + let ord = get_ord_at(0); + this.compiler_fence_intrinsic(args, fence_ord(ord))?; + } + + "xchg" => { + let ord = get_ord_at(1); + this.atomic_exchange(args, dest, rw_ord(ord))?; + } + "cxchg" => { + let ord1 = get_ord_at(1); + let ord2 = get_ord_at(2); + this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?; + } + "cxchgweak" => { + let ord1 = get_ord_at(1); + let ord2 = get_ord_at(2); + this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?; + } + + "or" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?; + } + "xor" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?; + } + "and" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?; + } + "nand" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?; + } + "xadd" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?; + } + "xsub" => { + let ord = get_ord_at(1); + this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?; + } + "min" => { + let ord = get_ord_at(1); // Later we will use the type to indicate signed vs unsigned, // so make sure it matches the intrinsic name. assert!(matches!(args[1].layout.ty.kind(), ty::Int(_))); this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?; } - ["umin", ord] => { + "umin" => { + let ord = get_ord_at(1); // Later we will use the type to indicate signed vs unsigned, // so make sure it matches the intrinsic name. assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_))); this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?; } - ["max", ord] => { + "max" => { + let ord = get_ord_at(1); // Later we will use the type to indicate signed vs unsigned, // so make sure it matches the intrinsic name. assert!(matches!(args[1].layout.ty.kind(), ty::Int(_))); this.atomic_rmw_op(args, dest, AtomicOp::Max, rw_ord(ord))?; } - ["umax", ord] => { + "umax" => { + let ord = get_ord_at(1); // Later we will use the type to indicate signed vs unsigned, // so make sure it matches the intrinsic name. assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_))); diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index b49c5044f31..e8bbd420cc4 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -1,9 +1,20 @@ #![feature(no_core, intrinsics, lang_items)] +#![feature(adt_const_params)] #![crate_type = "rlib"] #![no_core] +pub enum AtomicOrdering { + // These values must match the compiler's `AtomicOrdering` defined in + // `rustc_middle/src/ty/consts/int.rs`! + Relaxed = 0, + Release = 1, + Acquire = 2, + AcqRel = 3, + SeqCst = 4, +} + #[rustc_intrinsic] -unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; +unsafe fn atomic_xadd(dst: *mut T, src: T) -> T; #[lang = "sized"] trait Sized {} @@ -11,55 +22,58 @@ trait Sized {} trait Copy {} #[lang = "freeze"] trait Freeze {} +#[lang = "const_param_ty"] +pub trait ConstParamTy {} impl Copy for *mut T {} +impl ConstParamTy for AtomicOrdering {} #[cfg(target_has_atomic = "8")] pub unsafe fn atomic_u8(x: *mut u8) { - atomic_xadd_seqcst(x, 1); - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "8")] pub unsafe fn atomic_i8(x: *mut i8) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "16")] pub unsafe fn atomic_u16(x: *mut u16) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "16")] pub unsafe fn atomic_i16(x: *mut i16) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "32")] pub unsafe fn atomic_u32(x: *mut u32) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "32")] pub unsafe fn atomic_i32(x: *mut i32) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "64")] pub unsafe fn atomic_u64(x: *mut u64) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "64")] pub unsafe fn atomic_i64(x: *mut i64) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "128")] pub unsafe fn atomic_u128(x: *mut u128) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "128")] pub unsafe fn atomic_i128(x: *mut i128) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "ptr")] pub unsafe fn atomic_usize(x: *mut usize) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } #[cfg(target_has_atomic = "ptr")] pub unsafe fn atomic_isize(x: *mut isize) { - atomic_xadd_seqcst(x, 1); + atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1); } diff --git a/tests/ui/error-codes/E0092.rs b/tests/ui/error-codes/E0092.rs deleted file mode 100644 index 19a7c65a48e..00000000000 --- a/tests/ui/error-codes/E0092.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(intrinsics)] - -#[rustc_intrinsic] -unsafe fn atomic_foo(); //~ ERROR E0092 - -fn main() {} diff --git a/tests/ui/error-codes/E0092.stderr b/tests/ui/error-codes/E0092.stderr deleted file mode 100644 index 003c989fd59..00000000000 --- a/tests/ui/error-codes/E0092.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0092]: unrecognized atomic operation function: `foo` - --> $DIR/E0092.rs:4:11 - | -LL | unsafe fn atomic_foo(); - | ^^^^^^^^^^ unrecognized atomic operation - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0092`. diff --git a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr index aaaaeece67a..fb05273b6ff 100644 --- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr +++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr @@ -7,7 +7,7 @@ LL | #[rustc_intrinsic] = help: add `#![feature(intrinsics)]` 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[E0133]: call to unsafe function `atomic_fence` is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `main::atomic_fence` is unsafe and requires unsafe function or block --> $DIR/feature-gated-feature-in-macro-arg.rs:11:9 | LL | atomic_fence(); diff --git a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs index 1014ac6f560..ab4604b77b3 100644 --- a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs +++ b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs @@ -1,11 +1,24 @@ -#![feature(intrinsics)] +#![feature(intrinsics, adt_const_params)] pub mod rusti { + use std::marker::ConstParamTy; + + #[derive(Debug, ConstParamTy, PartialEq, Eq)] + pub enum AtomicOrdering { + // These values must match the compiler's `AtomicOrdering` defined in + // `rustc_middle/src/ty/consts/int.rs`! + Relaxed = 0, + Release = 1, + Acquire = 2, + AcqRel = 3, + SeqCst = 4, + } + #[rustc_intrinsic] - pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; + pub unsafe fn atomic_xchg(dst: *mut T, src: T) -> T; } #[inline(always)] pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize { - unsafe { rusti::atomic_xchg_seqcst(dst, src) } + unsafe { rusti::atomic_xchg::<_, { rusti::AtomicOrdering::SeqCst }>(dst, src) } } diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs index f96c6dc832e..2275aafff83 100644 --- a/tests/ui/intrinsics/intrinsic-atomics.rs +++ b/tests/ui/intrinsics/intrinsic-atomics.rs @@ -1,50 +1,50 @@ //@ run-pass #![feature(core_intrinsics)] -use std::intrinsics::{self as rusti, AtomicOrdering}; +use std::intrinsics::{self as rusti, AtomicOrdering::*}; pub fn main() { unsafe { let mut x: Box<_> = Box::new(1); - assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::SeqCst }>(&*x), 1); + assert_eq!(rusti::atomic_load::<_, { SeqCst }>(&*x), 1); *x = 5; - assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::Acquire }>(&*x), 5); + assert_eq!(rusti::atomic_load::<_, { Acquire }>(&*x), 5); - rusti::atomic_store_seqcst(&mut *x, 3); + rusti::atomic_store::<_, { SeqCst }>(&mut *x, 3); assert_eq!(*x, 3); - rusti::atomic_store_release(&mut *x, 1); + rusti::atomic_store::<_, { Release }>(&mut *x, 1); assert_eq!(*x, 1); - assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true)); + assert_eq!(rusti::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(&mut *x, 1, 2), (1, true)); assert_eq!(*x, 2); - assert_eq!(rusti::atomic_cxchg_acquire_acquire(&mut *x, 1, 3), (2, false)); + assert_eq!(rusti::atomic_cxchg::<_, { Acquire }, { Acquire }>(&mut *x, 1, 3), (2, false)); assert_eq!(*x, 2); - assert_eq!(rusti::atomic_cxchg_release_relaxed(&mut *x, 2, 1), (2, true)); + assert_eq!(rusti::atomic_cxchg::<_, { Release }, { Relaxed }>(&mut *x, 2, 1), (2, true)); assert_eq!(*x, 1); - assert_eq!(rusti::atomic_xchg_seqcst(&mut *x, 0), 1); + assert_eq!(rusti::atomic_xchg::<_, { SeqCst }>(&mut *x, 0), 1); assert_eq!(*x, 0); - assert_eq!(rusti::atomic_xchg_acquire(&mut *x, 1), 0); + assert_eq!(rusti::atomic_xchg::<_, { Acquire }>(&mut *x, 1), 0); assert_eq!(*x, 1); - assert_eq!(rusti::atomic_xchg_release(&mut *x, 0), 1); + assert_eq!(rusti::atomic_xchg::<_, { Release }>(&mut *x, 0), 1); assert_eq!(*x, 0); - assert_eq!(rusti::atomic_xadd_seqcst(&mut *x, 1), 0); - assert_eq!(rusti::atomic_xadd_acquire(&mut *x, 1), 1); - assert_eq!(rusti::atomic_xadd_release(&mut *x, 1), 2); + assert_eq!(rusti::atomic_xadd::<_, { SeqCst }>(&mut *x, 1), 0); + assert_eq!(rusti::atomic_xadd::<_, { Acquire }>(&mut *x, 1), 1); + assert_eq!(rusti::atomic_xadd::<_, { Release }>(&mut *x, 1), 2); assert_eq!(*x, 3); - assert_eq!(rusti::atomic_xsub_seqcst(&mut *x, 1), 3); - assert_eq!(rusti::atomic_xsub_acquire(&mut *x, 1), 2); - assert_eq!(rusti::atomic_xsub_release(&mut *x, 1), 1); + assert_eq!(rusti::atomic_xsub::<_, { SeqCst }>(&mut *x, 1), 3); + assert_eq!(rusti::atomic_xsub::<_, { Acquire }>(&mut *x, 1), 2); + assert_eq!(rusti::atomic_xsub::<_, { Release }>(&mut *x, 1), 1); assert_eq!(*x, 0); loop { - let res = rusti::atomic_cxchgweak_seqcst_seqcst(&mut *x, 0, 1); + let res = rusti::atomic_cxchgweak::<_, { SeqCst }, { SeqCst }>(&mut *x, 0, 1); assert_eq!(res.0, 0); if res.1 { break; @@ -53,7 +53,7 @@ pub fn main() { assert_eq!(*x, 1); loop { - let res = rusti::atomic_cxchgweak_acquire_acquire(&mut *x, 1, 2); + let res = rusti::atomic_cxchgweak::<_, { Acquire }, { Acquire }>(&mut *x, 1, 2); assert_eq!(res.0, 1); if res.1 { break; @@ -62,7 +62,7 @@ pub fn main() { assert_eq!(*x, 2); loop { - let res = rusti::atomic_cxchgweak_release_relaxed(&mut *x, 2, 3); + let res = rusti::atomic_cxchgweak::<_, { Release }, { Relaxed }>(&mut *x, 2, 3); assert_eq!(res.0, 2); if res.1 { break; diff --git a/tests/ui/intrinsics/non-integer-atomic.rs b/tests/ui/intrinsics/non-integer-atomic.rs index 5464bf747fa..853c163710f 100644 --- a/tests/ui/intrinsics/non-integer-atomic.rs +++ b/tests/ui/intrinsics/non-integer-atomic.rs @@ -4,7 +4,7 @@ #![allow(warnings)] #![crate_type = "rlib"] -use std::intrinsics::{self, AtomicOrdering}; +use std::intrinsics::{self, AtomicOrdering::*}; #[derive(Copy, Clone)] pub struct Foo(i64); @@ -12,81 +12,81 @@ pub type Bar = &'static dyn Fn(); pub type Quux = [u8; 100]; pub unsafe fn test_bool_load(p: &mut bool, v: bool) { - intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + intrinsics::atomic_load::<_, { SeqCst }>(p); //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `bool` } pub unsafe fn test_bool_store(p: &mut bool, v: bool) { - intrinsics::atomic_store_seqcst(p, v); - //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool` + intrinsics::atomic_store::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `bool` } pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) { - intrinsics::atomic_xchg_seqcst(p, v); - //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool` + intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `bool` } pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) { - intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool` + intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `bool` } pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) { - intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + intrinsics::atomic_load::<_, { SeqCst }>(p); //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `Foo` } pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) { - intrinsics::atomic_store_seqcst(p, v); - //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo` + intrinsics::atomic_store::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `Foo` } pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) { - intrinsics::atomic_xchg_seqcst(p, v); - //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo` + intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `Foo` } pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) { - intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo` + intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `Foo` } pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) { - intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + intrinsics::atomic_load::<_, { SeqCst }>(p); //~^ ERROR expected basic integer type, found `&dyn Fn()` } pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) { - intrinsics::atomic_store_seqcst(p, v); + intrinsics::atomic_store::<_, { SeqCst }>(p, v); //~^ ERROR expected basic integer type, found `&dyn Fn()` } pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) { - intrinsics::atomic_xchg_seqcst(p, v); + intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); //~^ ERROR expected basic integer type, found `&dyn Fn()` } pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) { - intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); //~^ ERROR expected basic integer type, found `&dyn Fn()` } pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) { - intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); + intrinsics::atomic_load::<_, { SeqCst }>(p); //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]` } pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) { - intrinsics::atomic_store_seqcst(p, v); - //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + intrinsics::atomic_store::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]` } pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) { - intrinsics::atomic_xchg_seqcst(p, v); - //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]` } pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) { - intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]` } diff --git a/tests/ui/intrinsics/non-integer-atomic.stderr b/tests/ui/intrinsics/non-integer-atomic.stderr index 58c2dc00c66..e539d99b8ae 100644 --- a/tests/ui/intrinsics/non-integer-atomic.stderr +++ b/tests/ui/intrinsics/non-integer-atomic.stderr @@ -1,98 +1,98 @@ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:15:5 | -LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool` +error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:20:5 | -LL | intrinsics::atomic_store_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_store::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool` +error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:25:5 | -LL | intrinsics::atomic_xchg_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool` +error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool` --> $DIR/non-integer-atomic.rs:30:5 | -LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:35:5 | -LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo` +error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:40:5 | -LL | intrinsics::atomic_store_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_store::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo` +error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:45:5 | -LL | intrinsics::atomic_xchg_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo` +error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo` --> $DIR/non-integer-atomic.rs:50:5 | -LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:55:5 | -LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` +error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:60:5 | -LL | intrinsics::atomic_store_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_store::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` +error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:65:5 | -LL | intrinsics::atomic_xchg_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` +error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn Fn()` --> $DIR/non-integer-atomic.rs:70:5 | -LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:75:5 | -LL | intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_load::<_, { SeqCst }>(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:80:5 | -LL | intrinsics::atomic_store_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_store::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:85:5 | -LL | intrinsics::atomic_xchg_seqcst(p, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_xchg::<_, { SeqCst }>(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]` --> $DIR/non-integer-atomic.rs:90:5 | -LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 16 previous errors -- cgit 1.4.1-3-g733a5 From 2e1965831526407bada7abec631d7b7e9f6cbc7d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 11 Feb 2025 22:09:16 -0800 Subject: Remove rustc's notion of "preferred" alignment AKA `__alignof` In PR 90877 T-lang decided not to remove `intrinsics::pref_align_of`. However, the intrinsic and its supporting code 1. is a nightly feature, so can be removed at compiler/libs discretion 2. requires considerable effort in the compiler to support, as it necessarily complicates every single site reasoning about alignment 3. has been justified based on relevance to codegen, but it is only a requirement for C++ (not C, not Rust) stack frame layout for AIX, in ways Rust would not consider even with increased C++ interop 4. is only used by rustc to overalign some globals, not correctness 5. can be adequately replaced by other rules for globals, as it mostly affects alignments for a few types under 16 bytes of alignment 6. has only one clear benefactor: automating C -> Rust translation for GNU extensions like `__alignof` 7. such code was likely intended to be `alignof` or `_Alignof`, because the GNU extension is a "false friend" of the C keyword, which makes the choice to support such a mapping very questionable 8. makes it easy to do incorrect codegen in the compiler by its mere presence as usual Rust rules of alignment (e.g. `size == align * N`) do not hold with preferred alignment The implementation is clearly damaging the code quality of the compiler. Thus it is within the compiler team's purview to simply rip it out. If T-lang wishes to have this intrinsic restored for c2rust's benefit, it would have to use a radically different implementation that somehow does not cause internal incorrectness. Until then, remove the intrinsic and its supporting code, as one tool and an ill-considered GCC extension cannot justify risking correctness. Because we touch a fair amount of the compiler to change this at all, and unfortunately the duplication of AbiAndPrefAlign is deep-rooted, we keep an "AbiAlign" type which we can wean code off later. --- compiler/rustc_abi/src/layout.rs | 20 ++--- compiler/rustc_abi/src/layout/ty.rs | 4 +- compiler/rustc_abi/src/lib.rs | 90 +++++++++++----------- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 6 +- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 6 +- .../rustc_const_eval/src/interpret/intrinsics.rs | 15 +--- compiler/rustc_feature/src/removed.rs | 2 + library/core/src/intrinsics/mod.rs | 9 --- tests/ui/abi/c-zst.aarch64-darwin.stderr | 6 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 6 +- tests/ui/abi/c-zst.s390x-linux.stderr | 6 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 6 +- tests/ui/abi/c-zst.x86_64-linux.stderr | 6 +- tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 6 +- tests/ui/abi/debug.stderr | 72 ++++++----------- tests/ui/abi/sysv64-zst.stderr | 6 +- tests/ui/intrinsics/intrinsic-alignment.rs | 25 ++---- tests/ui/layout/debug.stderr | 54 +++++-------- tests/ui/layout/enum.stderr | 2 +- tests/ui/layout/hexagon-enum.stderr | 30 +++----- ...96158-scalarpair-payload-might-be-uninit.stderr | 51 ++++-------- .../ui/layout/issue-96185-overaligned-enum.stderr | 18 ++--- tests/ui/layout/thumb-enum.stderr | 30 +++----- tests/ui/layout/zero-sized-array-enum-niche.stderr | 39 ++++------ ...-dead-variants.aarch64-unknown-linux-gnu.stderr | 24 ++---- .../repr-c-dead-variants.armebv7r-none-eabi.stderr | 24 ++---- ...epr-c-dead-variants.i686-pc-windows-msvc.stderr | 24 ++---- ...c-dead-variants.x86_64-unknown-linux-gnu.stderr | 24 ++---- tests/ui/repr/repr-c-int-dead-variants.stderr | 24 ++---- tests/ui/type/pattern_types/or_patterns.stderr | 6 +- tests/ui/type/pattern_types/range_patterns.stderr | 33 +++----- 31 files changed, 230 insertions(+), 444 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 21fd6be39fa..58a7fcae9f6 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -8,7 +8,7 @@ use rustc_index::bit_set::BitMatrix; use tracing::debug; use crate::{ - AbiAndPrefAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, + AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, Variants, WrappingRange, }; @@ -173,13 +173,7 @@ impl LayoutCalculator { // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close // to a vector as possible. - ( - BackendRepr::Memory { sized: true }, - AbiAndPrefAlign { - abi: Align::max_aligned_factor(size), - pref: dl.llvmlike_vector_align(size).pref, - }, - ) + (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) }) } else { (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size)) }; @@ -435,13 +429,13 @@ impl LayoutCalculator { } if let Some(pack) = repr.pack { - align = align.min(AbiAndPrefAlign::new(pack)); + align = align.min(AbiAlign::new(pack)); } // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). // See documentation on `LayoutS::unadjusted_abi_align`. let unadjusted_abi_align = align.abi; if let Some(repr_align) = repr.align { - align = align.max(AbiAndPrefAlign::new(repr_align)); + align = align.max(AbiAlign::new(repr_align)); } // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate. let align = align; @@ -1289,7 +1283,7 @@ impl LayoutCalculator { if let StructKind::Prefixed(prefix_size, prefix_align) = kind { let prefix_align = if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; - align = align.max(AbiAndPrefAlign::new(prefix_align)); + align = align.max(AbiAlign::new(prefix_align)); offset = prefix_size.align_to(prefix_align); } for &i in &inverse_memory_index { @@ -1308,7 +1302,7 @@ impl LayoutCalculator { // Invariant: offset < dl.obj_size_bound() <= 1<<61 let field_align = if let Some(pack) = pack { - field.align.min(AbiAndPrefAlign::new(pack)) + field.align.min(AbiAlign::new(pack)) } else { field.align }; @@ -1342,7 +1336,7 @@ impl LayoutCalculator { // See documentation on `LayoutS::unadjusted_abi_align`. let unadjusted_abi_align = align.abi; if let Some(repr_align) = repr.align { - align = align.max(AbiAndPrefAlign::new(repr_align)); + align = align.max(AbiAlign::new(repr_align)); } // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate. let align = align; diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index b5f93351d68..bb880a58e52 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -5,7 +5,7 @@ use rustc_data_structures::intern::Interned; use rustc_macros::HashStable_Generic; use crate::{ - AbiAndPrefAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche, + AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche, PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants, }; @@ -100,7 +100,7 @@ impl<'a> Layout<'a> { self.0.0.largest_niche } - pub fn align(self) -> AbiAndPrefAlign { + pub fn align(self) -> AbiAlign { self.0.0.align } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 46b7a0c1e77..29e36c021ed 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -226,22 +226,22 @@ pub const MAX_SIMD_LANES: u64 = 1 << 0xF; #[derive(Debug, PartialEq, Eq)] pub struct TargetDataLayout { pub endian: Endian, - pub i1_align: AbiAndPrefAlign, - pub i8_align: AbiAndPrefAlign, - pub i16_align: AbiAndPrefAlign, - pub i32_align: AbiAndPrefAlign, - pub i64_align: AbiAndPrefAlign, - pub i128_align: AbiAndPrefAlign, - pub f16_align: AbiAndPrefAlign, - pub f32_align: AbiAndPrefAlign, - pub f64_align: AbiAndPrefAlign, - pub f128_align: AbiAndPrefAlign, + pub i1_align: AbiAlign, + pub i8_align: AbiAlign, + pub i16_align: AbiAlign, + pub i32_align: AbiAlign, + pub i64_align: AbiAlign, + pub i128_align: AbiAlign, + pub f16_align: AbiAlign, + pub f32_align: AbiAlign, + pub f64_align: AbiAlign, + pub f128_align: AbiAlign, pub pointer_size: Size, - pub pointer_align: AbiAndPrefAlign, - pub aggregate_align: AbiAndPrefAlign, + pub pointer_align: AbiAlign, + pub aggregate_align: AbiAlign, /// Alignments for vector types. - pub vector_align: Vec<(Size, AbiAndPrefAlign)>, + pub vector_align: Vec<(Size, AbiAlign)>, pub instruction_address_space: AddressSpace, @@ -257,22 +257,22 @@ impl Default for TargetDataLayout { let align = |bits| Align::from_bits(bits).unwrap(); TargetDataLayout { endian: Endian::Big, - i1_align: AbiAndPrefAlign::new(align(8)), - i8_align: AbiAndPrefAlign::new(align(8)), - i16_align: AbiAndPrefAlign::new(align(16)), - i32_align: AbiAndPrefAlign::new(align(32)), - i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, - i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, - f16_align: AbiAndPrefAlign::new(align(16)), - f32_align: AbiAndPrefAlign::new(align(32)), - f64_align: AbiAndPrefAlign::new(align(64)), - f128_align: AbiAndPrefAlign::new(align(128)), + i1_align: AbiAlign::new(align(8)), + i8_align: AbiAlign::new(align(8)), + i16_align: AbiAlign::new(align(16)), + i32_align: AbiAlign::new(align(32)), + i64_align: AbiAlign::new(align(32)), + i128_align: AbiAlign::new(align(32)), + f16_align: AbiAlign::new(align(16)), + f32_align: AbiAlign::new(align(32)), + f64_align: AbiAlign::new(align(64)), + f128_align: AbiAlign::new(align(128)), pointer_size: Size::from_bits(64), - pointer_align: AbiAndPrefAlign::new(align(64)), - aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) }, + pointer_align: AbiAlign::new(align(64)), + aggregate_align: AbiAlign { abi: align(8) }, vector_align: vec![ - (Size::from_bits(64), AbiAndPrefAlign::new(align(64))), - (Size::from_bits(128), AbiAndPrefAlign::new(align(128))), + (Size::from_bits(64), AbiAlign::new(align(64))), + (Size::from_bits(128), AbiAlign::new(align(128))), ], instruction_address_space: AddressSpace::DATA, c_enum_min_size: Integer::I32, @@ -330,8 +330,7 @@ impl TargetDataLayout { .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err }) }; let abi = parse_bits(s[0], "alignment", cause)?; - let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; - Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? }) + Ok(AbiAlign::new(align_from_bits(abi)?)) }; let mut dl = TargetDataLayout::default(); @@ -426,7 +425,7 @@ impl TargetDataLayout { /// psABI-mandated alignment for a vector type, if any #[inline] - fn cabi_vector_align(&self, vec_size: Size) -> Option { + fn cabi_vector_align(&self, vec_size: Size) -> Option { self.vector_align .iter() .find(|(size, _align)| *size == vec_size) @@ -435,8 +434,8 @@ impl TargetDataLayout { /// an alignment resembling the one LLVM would pick for a vector #[inline] - pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { - self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new( + pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign { + self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new( Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(), )) } @@ -864,25 +863,24 @@ impl Align { /// It is of effectively no consequence for layout in structs and on the stack. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub struct AbiAndPrefAlign { +pub struct AbiAlign { pub abi: Align, - pub pref: Align, } -impl AbiAndPrefAlign { +impl AbiAlign { #[inline] - pub fn new(align: Align) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: align, pref: align } + pub fn new(align: Align) -> AbiAlign { + AbiAlign { abi: align } } #[inline] - pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) } + pub fn min(self, other: AbiAlign) -> AbiAlign { + AbiAlign { abi: self.abi.min(other.abi) } } #[inline] - pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) } + pub fn max(self, other: AbiAlign) -> AbiAlign { + AbiAlign { abi: self.abi.max(other.abi) } } } @@ -945,7 +943,7 @@ impl Integer { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Integer::*; let dl = cx.data_layout(); @@ -1058,7 +1056,7 @@ impl Float { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Float::*; let dl = cx.data_layout(); @@ -1102,7 +1100,7 @@ impl Primitive { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Primitive::*; let dl = cx.data_layout(); @@ -1225,7 +1223,7 @@ impl Scalar { } } - pub fn align(self, cx: &impl HasDataLayout) -> AbiAndPrefAlign { + pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign { self.primitive().align(cx) } @@ -1731,7 +1729,7 @@ pub struct LayoutData { /// especially in the case of by-pointer struct returns, which allocate stack even when unused. pub uninhabited: bool, - pub align: AbiAndPrefAlign, + pub align: AbiAlign, pub size: Size, /// The largest alignment explicitly requested with `repr(align)` on this type or any field. diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index a0f96d85dc3..1d1cf884e48 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -812,11 +812,7 @@ fn codegen_regular_intrinsic_call<'tcx>( dest.write_cvalue(fx, val); } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { intrinsic_args!(fx, args => (); intrinsic); let const_val = fx diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index a3f09f64a3e..e217c09939e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -150,11 +150,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } value } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap(); OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 64467a90136..ab27182c211 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -50,13 +50,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env)) } - sym::pref_align_of => { - // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - let layout = tcx - .layout_of(typing_env.as_query_input(tp_ty)) - .map_err(|e| err_inval!(Layout(*e)))?; - ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) - } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128()) @@ -144,14 +137,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(result, self), dest)?; } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { let gid = GlobalId { instance, promoted: None }; let ty = match intrinsic_name { - sym::pref_align_of | sym::variant_count => self.tcx.types.usize, + sym::variant_count => self.tcx.types.usize, sym::needs_drop => self.tcx.types.bool, sym::type_id => self.tcx.types.u128, sym::type_name => Ty::new_static_str(self.tcx.tcx), diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 687d859df53..013e1d5d0fa 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -207,6 +207,8 @@ declare_features! ( /// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`. (removed, precise_pointer_size_matching, "1.32.0", Some(56354), Some("removed in favor of half-open ranges")), + (removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971), + Some("removed due to marginal use and inducing compiler complications")), (removed, proc_macro_expr, "1.27.0", Some(54727), Some("subsumed by `#![feature(proc_macro_hygiene)]`")), (removed, proc_macro_gen, "1.27.0", Some(54727), diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 954c3754084..4434ceb49bc 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2651,15 +2651,6 @@ pub const fn size_of() -> usize; #[rustc_intrinsic] pub const fn min_align_of() -> usize; -/// The preferred alignment of a type. -/// -/// This intrinsic does not have a stable counterpart. -/// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). -#[rustc_nounwind] -#[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_intrinsic] -pub const unsafe fn pref_align_of() -> usize; - /// Returns the number of variants of the type `T` cast to a `usize`; /// if `T` has no variants, returns `0`. Uninhabited variants will be counted. /// diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 48fa2bf29bc..5e09145a271 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index bfdf94c9900..b8d6c632b97 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index bfdf94c9900..b8d6c632b97 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index bfdf94c9900..b8d6c632b97 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 48fa2bf29bc..5e09145a271 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index bfdf94c9900..b8d6c632b97 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 480f3f04215..8ed6dedf4d5 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(test) = FnAbi { ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -44,9 +43,8 @@ error: fn_abi_of(test) = FnAbi { ty: bool, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -103,9 +101,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ty: bool, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -151,9 +148,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -201,9 +197,8 @@ error: fn_abi_of(test_generic) = FnAbi { ty: *const T, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -241,9 +236,8 @@ error: fn_abi_of(test_generic) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -288,9 +282,8 @@ error: ABIs are not compatible ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -327,9 +320,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -362,9 +354,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -401,9 +392,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -442,9 +432,8 @@ error: ABIs are not compatible ty: [u8; 32], layout: Layout { size: Size(32 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -482,9 +471,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -517,9 +505,8 @@ error: ABIs are not compatible ty: [u32; 32], layout: Layout { size: Size(128 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -557,9 +544,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -598,9 +584,8 @@ error: ABIs are not compatible ty: f32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -636,9 +621,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -671,9 +655,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -710,9 +693,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -751,9 +733,8 @@ error: ABIs are not compatible ty: i32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -790,9 +771,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -825,9 +805,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -864,9 +843,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -925,9 +903,8 @@ error: fn_abi_of(assoc_test) = FnAbi { ty: &S, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -977,9 +954,8 @@ error: fn_abi_of(assoc_test) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index f91d1b5fa63..2233e8e4f62 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index a467c445d61..30a523f364c 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -23,18 +23,12 @@ use std::intrinsics as rusti; mod m { #[cfg(target_arch = "x86")] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 4); - } + assert_eq!(crate::rusti::min_align_of::(), 4); } #[cfg(not(target_arch = "x86"))] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } @@ -42,30 +36,21 @@ mod m { mod m { #[cfg(target_arch = "x86_64")] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } #[cfg(target_os = "windows")] mod m { pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } #[cfg(target_family = "wasm")] mod m { pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index abaa16cdefa..b2ce6385ab6 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -6,9 +6,8 @@ LL | union EmptyUnion {} error: layout_of(E) = Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: layout_of(E) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -67,9 +65,8 @@ error: layout_of(E) = Layout { }, Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -108,9 +105,8 @@ LL | enum E { Foo, Bar(!, i32, i32) } error: layout_of(S) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -156,9 +152,8 @@ LL | struct S { f1: i32, f2: (), f3: i32 } error: layout_of(U) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -182,9 +177,8 @@ LL | union U { f1: (i32, i32), f3: i32 } error: layout_of(Result) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -234,9 +228,8 @@ error: layout_of(Result) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -273,9 +266,8 @@ error: layout_of(Result) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -323,9 +315,8 @@ LL | type Test = Result; error: layout_of(i32) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -353,9 +344,8 @@ LL | type T = impl std::fmt::Debug; error: layout_of(V) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -379,9 +369,8 @@ LL | pub union V { error: layout_of(W) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -405,9 +394,8 @@ LL | pub union W { error: layout_of(Y) = Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -431,9 +419,8 @@ LL | pub union Y { error: layout_of(P1) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -457,9 +444,8 @@ LL | union P1 { x: u32 } error: layout_of(P2) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -483,9 +469,8 @@ LL | union P2 { x: (u32, u32) } error: layout_of(P3) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -509,9 +494,8 @@ LL | union P3 { x: F32x4 } error: layout_of(P4) = Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -535,9 +519,8 @@ LL | union P4 { x: E } error: layout_of(P5) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Union { @@ -566,9 +549,8 @@ LL | union P5 { zst: [u16; 0], byte: u8 } error: layout_of(MaybeUninit) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Union { diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr index 7f0b38d0a07..f95b577bfc9 100644 --- a/tests/ui/layout/enum.stderr +++ b/tests/ui/layout/enum.stderr @@ -1,4 +1,4 @@ -error: align: AbiAndPrefAlign { abi: Align(2 bytes), pref: $PREF_ALIGN } +error: align: AbiAlign { abi: Align(2 bytes) } --> $DIR/enum.rs:9:1 | LL | enum UninhabitedVariantAlign { diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 9c3a8662d4f..d910456c0e6 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(A) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(A) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Memory { sized: true, @@ -78,9 +76,8 @@ LL | enum A { Apple } error: layout_of(B) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Scalar( Initialized { @@ -123,9 +120,8 @@ error: layout_of(B) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Memory { sized: true, @@ -156,9 +152,8 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(2 bytes), }, backend_repr: Scalar( Initialized { @@ -201,9 +196,8 @@ error: layout_of(C) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(2 bytes), }, backend_repr: Memory { sized: true, @@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -279,9 +272,8 @@ error: layout_of(P) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -357,9 +348,8 @@ error: layout_of(T) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index ef7f0cd2d1c..2087fedeb19 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -1,8 +1,7 @@ error: layout_of(MissingPayloadField) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -51,9 +50,8 @@ error: layout_of(MissingPayloadField) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -89,9 +87,8 @@ error: layout_of(MissingPayloadField) = Layout { }, Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -122,9 +119,8 @@ LL | pub enum MissingPayloadField { error: layout_of(CommonPayloadField) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -174,9 +170,8 @@ error: layout_of(CommonPayloadField) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -213,9 +208,8 @@ error: layout_of(CommonPayloadField) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -263,9 +257,8 @@ LL | pub enum CommonPayloadField { error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -314,9 +307,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -352,9 +344,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -401,9 +392,8 @@ LL | pub enum CommonPayloadFieldIsMaybeUninit { error: layout_of(NicheFirst) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -456,9 +446,8 @@ error: layout_of(NicheFirst) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -506,9 +495,8 @@ error: layout_of(NicheFirst) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -528,9 +516,8 @@ error: layout_of(NicheFirst) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -561,9 +548,8 @@ LL | pub enum NicheFirst { error: layout_of(NicheSecond) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -616,9 +602,8 @@ error: layout_of(NicheSecond) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -666,9 +651,8 @@ error: layout_of(NicheSecond) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -688,9 +672,8 @@ error: layout_of(NicheSecond) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index a9081afc509..6bcc5b4906b 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(Aligned1) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -39,9 +38,8 @@ error: layout_of(Aligned1) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -63,9 +61,8 @@ error: layout_of(Aligned1) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -100,9 +97,8 @@ LL | pub enum Aligned1 { error: layout_of(Aligned2) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Scalar( Initialized { @@ -145,9 +141,8 @@ error: layout_of(Aligned2) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -169,9 +164,8 @@ error: layout_of(Aligned2) = Layout { }, Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index b635d1a45bb..9bd8ced0c02 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(A) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(A) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -78,9 +76,8 @@ LL | enum A { Apple } error: layout_of(B) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -123,9 +120,8 @@ error: layout_of(B) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -156,9 +152,8 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -201,9 +196,8 @@ error: layout_of(C) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -279,9 +272,8 @@ error: layout_of(P) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -357,9 +348,8 @@ error: layout_of(T) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 1ba184bdace..1707b8aff81 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -1,8 +1,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -39,9 +38,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -65,9 +63,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -111,9 +108,8 @@ LL | type AlignedResult = Result<[u32; 0], bool>; error: layout_of(MultipleAlignments) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -150,9 +146,8 @@ error: layout_of(MultipleAlignments) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -176,9 +171,8 @@ error: layout_of(MultipleAlignments) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -202,9 +196,8 @@ error: layout_of(MultipleAlignments) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -248,9 +241,8 @@ LL | enum MultipleAlignments { error: layout_of(Result<[u32; 0], Packed>>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -287,9 +279,8 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -313,9 +304,8 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, Layout { size: Size(3 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -359,9 +349,8 @@ LL | type NicheLosesToTagged = Result<[u32; 0], Packed>>; error: layout_of(Result<[u32; 0], Packed>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -402,9 +391,8 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -428,9 +416,8 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index c11acc98637..63d685951d9 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index a7888155dea..555471be027 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index c11acc98637..63d685951d9 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index c11acc98637..63d685951d9 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index f63574182c2..d88a842f884 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -1,8 +1,7 @@ error: layout_of(UnivariantU8) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(UnivariantU8) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum UnivariantU8 { error: layout_of(TwoVariantsU8) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariantsU8) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariantsU8) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariantsU8 { error: layout_of(DeadBranchHasOtherFieldU8) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index 58ca585f4a9..a417e502e35 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -41,9 +41,8 @@ LL | let _: NonNegOneI8 = -128; error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -80,9 +79,8 @@ LL | type NonNullI8 = pattern_type!(i8 is ..0 | 1..); error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index bcb602a70dd..a9c674632cb 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -1,8 +1,7 @@ error: layout_of(NonZero) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -46,9 +45,8 @@ LL | type X = std::num::NonZeroU32; error: layout_of((u32) is 1..) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -85,9 +83,8 @@ LL | type Y = pattern_type!(u32 is 1..); error: layout_of(Option<(u32) is 1..>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -125,9 +122,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -147,9 +143,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -199,9 +194,8 @@ LL | type Z = Option; error: layout_of(Option>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -239,9 +233,8 @@ error: layout_of(Option>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -261,9 +254,8 @@ error: layout_of(Option>) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -313,9 +305,8 @@ LL | type A = Option; error: layout_of(NonZeroU32New) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -387,9 +378,8 @@ LL | type WRAP2 = pattern_type!(u32 is 5..2); error: layout_of((i8) is -10..=10) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -426,9 +416,8 @@ LL | type SIGN = pattern_type!(i8 is -10..=10); error: layout_of((i8) is i8::MIN..=0) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { -- cgit 1.4.1-3-g733a5