From 129b5e48f029779c57b46c72add9db03678d7cb5 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Fri, 15 Mar 2024 15:53:49 -0400 Subject: [PATCH 01/12] avoid naming LLVM basic blocks when fewer_names is true --- compiler/rustc_codegen_gcc/src/builder.rs | 9 +++++---- compiler/rustc_codegen_llvm/src/builder.rs | 19 +++++++++++++++---- compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_ssa/src/mir/block.rs | 12 +++++++----- .../rustc_codegen_ssa/src/traits/builder.rs | 10 ++++++++-- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index f5cda81f6ab86..c12fa1a58fff8 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::convert::TryFrom; +use std::fmt::Display; use std::ops::Deref; use gccjit::{ @@ -526,14 +527,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block } - fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> { + fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: impl Display) -> Block<'gcc> { let func = cx.rvalue_as_function(func); - func.new_block(name) + func.new_block(name.to_string()) } - fn append_sibling_block(&mut self, name: &str) -> Block<'gcc> { + fn append_sibling_block(&mut self, name: impl Display) -> Block<'gcc> { let func = self.current_func(); - func.new_block(name) + func.new_block(name.to_string()) } fn switch_to_block(&mut self, block: Self::BasicBlock) { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 63e59ea13fc35..b244ed959f9e8 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -26,6 +26,7 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; use smallvec::SmallVec; use std::borrow::Cow; +use std::fmt::Display; use std::iter; use std::ops::Deref; use std::ptr; @@ -153,14 +154,24 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn set_span(&mut self, _span: Span) {} - fn append_block(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &str) -> &'ll BasicBlock { + fn append_block( + cx: &'a CodegenCx<'ll, 'tcx>, + llfn: &'ll Value, + name: impl Display, + ) -> &'ll BasicBlock { unsafe { - let name = SmallCStr::new(name); - llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr()) + let c_str_name; + let name_ptr = if cx.tcx.sess.fewer_names() { + const { c"".as_ptr().cast() } + } else { + c_str_name = SmallCStr::new(&name.to_string()); + c_str_name.as_ptr() + }; + llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name_ptr) } } - fn append_sibling_block(&mut self, name: &str) -> &'ll BasicBlock { + fn append_sibling_block(&mut self, name: impl Display) -> &'ll BasicBlock { Self::append_block(self.cx, self.llfn(), name) } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c84461e53eb1b..72e5e2b042ee9 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -11,6 +11,7 @@ #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(hash_raw_entry)] +#![feature(inline_const)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(impl_trait_in_assoc_type)] diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 9bb2a52826585..3db6bc5b42643 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -83,8 +83,11 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // Cross-funclet jump - need a trampoline debug_assert!(base::wants_new_eh_instructions(fx.cx.tcx().sess)); debug!("llbb_with_cleanup: creating cleanup trampoline for {:?}", target); - let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target); - let trampoline_llbb = Bx::append_block(fx.cx, fx.llfn, name); + let trampoline_llbb = Bx::append_block( + fx.cx, + fx.llfn, + format_args!("{:?}_cleanup_trampoline_{:?}", self.bb, target), + ); let mut trampoline_bx = Bx::build(fx.cx, trampoline_llbb); trampoline_bx.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget)); trampoline_llbb @@ -1565,7 +1568,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn landing_pad_for_uncached(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock { let llbb = self.llbb(bb); if base::wants_new_eh_instructions(self.cx.sess()) { - let cleanup_bb = Bx::append_block(self.cx, self.llfn, &format!("funclet_{bb:?}")); + let cleanup_bb = Bx::append_block(self.cx, self.llfn, format_args!("funclet_{bb:?}")); let mut cleanup_bx = Bx::build(self.cx, cleanup_bb); let funclet = cleanup_bx.cleanup_pad(None, &[]); cleanup_bx.br(llbb); @@ -1688,8 +1691,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option { match self.cached_llbbs[bb] { CachedLlbb::None => { - // FIXME(eddyb) only name the block if `fewer_names` is `false`. - let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}")); + let llbb = Bx::append_block(self.cx, self.llfn, format_args!("{bb:?}")); self.cached_llbbs[bb] = CachedLlbb::Some(llbb); Some(llbb) } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 36f37e3791bc5..49c3101bc5e51 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -22,6 +22,8 @@ use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange}; use rustc_target::spec::HasTargetSpec; +use std::fmt::Display; + #[derive(Copy, Clone)] pub enum OverflowOp { Add, @@ -49,9 +51,13 @@ pub trait BuilderMethods<'a, 'tcx>: fn set_span(&mut self, span: Span); // FIXME(eddyb) replace uses of this with `append_sibling_block`. - fn append_block(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &str) -> Self::BasicBlock; + fn append_block( + cx: &'a Self::CodegenCx, + llfn: Self::Function, + name: impl Display, + ) -> Self::BasicBlock; - fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock; + fn append_sibling_block(&mut self, name: impl Display) -> Self::BasicBlock; fn switch_to_block(&mut self, llbb: Self::BasicBlock); From 4bfc48585d27c3723b28b749886f74da27081a0f Mon Sep 17 00:00:00 2001 From: klensy Date: Sat, 16 Mar 2024 12:31:57 +0300 Subject: [PATCH 02/12] less useless array builds in imported_source_file --- compiler/rustc_metadata/src/rmeta/decoder.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 0467cf2969fc5..03783fa97987a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1590,17 +1590,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } - // Translate the virtual `/rustc/$hash` prefix back to a real directory - // that should hold actual sources, where possible. - // - // NOTE: if you update this, you might need to also update bootstrap's code for generating - // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`. - let virtual_rust_source_base_dir = [ - filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)), - filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()), - ]; - let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| { + // Translate the virtual `/rustc/$hash` prefix back to a real directory + // that should hold actual sources, where possible. + // + // NOTE: if you update this, you might need to also update bootstrap's code for generating + // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`. + let virtual_rust_source_base_dir = [ + filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)), + filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()), + ]; + debug!( "try_to_translate_virtual_to_real(name={:?}): \ virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}", From a7d4258e00543a9a62fcfabbed4f27121f8f48ce Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sat, 16 Mar 2024 11:11:53 -0400 Subject: [PATCH 03/12] revert changes and just delete the fixme Avoiding the naming didn't have any meaningful perf impact. --- compiler/rustc_codegen_gcc/src/builder.rs | 9 ++++----- compiler/rustc_codegen_llvm/src/builder.rs | 19 ++++--------------- compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_ssa/src/mir/block.rs | 11 ++++------- .../rustc_codegen_ssa/src/traits/builder.rs | 10 ++-------- 5 files changed, 14 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index c12fa1a58fff8..f5cda81f6ab86 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1,7 +1,6 @@ use std::borrow::Cow; use std::cell::Cell; use std::convert::TryFrom; -use std::fmt::Display; use std::ops::Deref; use gccjit::{ @@ -527,14 +526,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block } - fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: impl Display) -> Block<'gcc> { + fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> { let func = cx.rvalue_as_function(func); - func.new_block(name.to_string()) + func.new_block(name) } - fn append_sibling_block(&mut self, name: impl Display) -> Block<'gcc> { + fn append_sibling_block(&mut self, name: &str) -> Block<'gcc> { let func = self.current_func(); - func.new_block(name.to_string()) + func.new_block(name) } fn switch_to_block(&mut self, block: Self::BasicBlock) { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index b244ed959f9e8..63e59ea13fc35 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -26,7 +26,6 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; use smallvec::SmallVec; use std::borrow::Cow; -use std::fmt::Display; use std::iter; use std::ops::Deref; use std::ptr; @@ -154,24 +153,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn set_span(&mut self, _span: Span) {} - fn append_block( - cx: &'a CodegenCx<'ll, 'tcx>, - llfn: &'ll Value, - name: impl Display, - ) -> &'ll BasicBlock { + fn append_block(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &str) -> &'ll BasicBlock { unsafe { - let c_str_name; - let name_ptr = if cx.tcx.sess.fewer_names() { - const { c"".as_ptr().cast() } - } else { - c_str_name = SmallCStr::new(&name.to_string()); - c_str_name.as_ptr() - }; - llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name_ptr) + let name = SmallCStr::new(name); + llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr()) } } - fn append_sibling_block(&mut self, name: impl Display) -> &'ll BasicBlock { + fn append_sibling_block(&mut self, name: &str) -> &'ll BasicBlock { Self::append_block(self.cx, self.llfn(), name) } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 72e5e2b042ee9..c84461e53eb1b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -11,7 +11,6 @@ #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(hash_raw_entry)] -#![feature(inline_const)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(impl_trait_in_assoc_type)] diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 3db6bc5b42643..02e7bb05b7709 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -83,11 +83,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // Cross-funclet jump - need a trampoline debug_assert!(base::wants_new_eh_instructions(fx.cx.tcx().sess)); debug!("llbb_with_cleanup: creating cleanup trampoline for {:?}", target); - let trampoline_llbb = Bx::append_block( - fx.cx, - fx.llfn, - format_args!("{:?}_cleanup_trampoline_{:?}", self.bb, target), - ); + let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target); + let trampoline_llbb = Bx::append_block(fx.cx, fx.llfn, name); let mut trampoline_bx = Bx::build(fx.cx, trampoline_llbb); trampoline_bx.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget)); trampoline_llbb @@ -1568,7 +1565,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn landing_pad_for_uncached(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock { let llbb = self.llbb(bb); if base::wants_new_eh_instructions(self.cx.sess()) { - let cleanup_bb = Bx::append_block(self.cx, self.llfn, format_args!("funclet_{bb:?}")); + let cleanup_bb = Bx::append_block(self.cx, self.llfn, &format!("funclet_{bb:?}")); let mut cleanup_bx = Bx::build(self.cx, cleanup_bb); let funclet = cleanup_bx.cleanup_pad(None, &[]); cleanup_bx.br(llbb); @@ -1691,7 +1688,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option { match self.cached_llbbs[bb] { CachedLlbb::None => { - let llbb = Bx::append_block(self.cx, self.llfn, format_args!("{bb:?}")); + let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}")); self.cached_llbbs[bb] = CachedLlbb::Some(llbb); Some(llbb) } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 49c3101bc5e51..36f37e3791bc5 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -22,8 +22,6 @@ use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange}; use rustc_target::spec::HasTargetSpec; -use std::fmt::Display; - #[derive(Copy, Clone)] pub enum OverflowOp { Add, @@ -51,13 +49,9 @@ pub trait BuilderMethods<'a, 'tcx>: fn set_span(&mut self, span: Span); // FIXME(eddyb) replace uses of this with `append_sibling_block`. - fn append_block( - cx: &'a Self::CodegenCx, - llfn: Self::Function, - name: impl Display, - ) -> Self::BasicBlock; + fn append_block(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &str) -> Self::BasicBlock; - fn append_sibling_block(&mut self, name: impl Display) -> Self::BasicBlock; + fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock; fn switch_to_block(&mut self, llbb: Self::BasicBlock); From 29430554f65619007f004e7941b7c2efb6465dbf Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 15 Mar 2024 18:43:19 -0700 Subject: [PATCH 04/12] Update the minimum external LLVM to 17 --- .github/workflows/ci.yml | 6 +- compiler/rustc_codegen_llvm/src/context.rs | 11 --- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 40 ++--------- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 16 ----- src/bootstrap/src/core/build_steps/llvm.rs | 4 +- .../host-x86_64/x86_64-gnu-llvm-16/Dockerfile | 67 ------------------- .../host-x86_64/x86_64-gnu-llvm-17/Dockerfile | 3 +- .../host-x86_64/x86_64-gnu-llvm-18/Dockerfile | 15 +++-- .../script.sh => scripts/x86_64-gnu-llvm.sh} | 0 src/ci/github-actions/ci.yml | 7 +- tests/codegen/issues/issue-114312.rs | 1 - .../codegen/move-before-nocapture-ref-arg.rs | 1 - tests/codegen/trailing_zeros.rs | 1 - tests/codegen/vec-shrink-panik.rs | 14 ---- tests/run-make/lto-linkage-used-attr/Makefile | 1 - tests/ui/codegen/target-cpus.rs | 1 - 16 files changed, 20 insertions(+), 168 deletions(-) delete mode 100644 src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile rename src/ci/docker/{host-x86_64/x86_64-gnu-llvm-16/script.sh => scripts/x86_64-gnu-llvm.sh} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f436c236dc958..767ea29d6369b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: - name: mingw-check-tidy os: ubuntu-20.04-4core-16gb env: {} - - name: x86_64-gnu-llvm-16 + - name: x86_64-gnu-llvm-17 env: ENABLE_GCC_CODEGEN: "1" os: ubuntu-20.04-16core-64gb @@ -323,10 +323,6 @@ jobs: env: RUST_BACKTRACE: 1 os: ubuntu-20.04-8core-32gb - - name: x86_64-gnu-llvm-16 - env: - RUST_BACKTRACE: 1 - os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-nopt os: ubuntu-20.04-4core-16gb env: {} diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index f89c8c9f836bf..c3f17563b0a61 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -126,17 +126,6 @@ pub unsafe fn create_module<'ll>( let mut target_data_layout = sess.target.data_layout.to_string(); let llvm_version = llvm_util::get_version(); - if llvm_version < (17, 0, 0) { - if sess.target.arch.starts_with("powerpc") { - // LLVM 17 specifies function pointer alignment for ppc: - // https://reviews.llvm.org/D147016 - target_data_layout = target_data_layout - .replace("-Fn32", "") - .replace("-Fi32", "") - .replace("-Fn64", "") - .replace("-Fi64", ""); - } - } if llvm_version < (18, 0, 0) { if sess.target.arch == "x86" || sess.target.arch == "x86_64" { // LLVM 18 adjusts i128 to be 128-bit aligned on x86 variants. diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index f6253068eaa63..067374c026107 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -24,9 +24,7 @@ #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/FileSystem.h" -#if LLVM_VERSION_GE(17, 0) #include "llvm/Support/VirtualFileSystem.h" -#endif #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" @@ -334,14 +332,8 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, std::ostringstream Buf; -#if LLVM_VERSION_GE(17, 0) const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef CPUTable = MCInfo->getAllProcessorDescriptions(); -#else - Buf << "Full target CPU help is not supported by this LLVM version.\n\n"; - SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} }; - const ArrayRef CPUTable = TargetCPUKV; -#endif unsigned MaxCPULen = getLongestEntryLength(CPUTable); Buf << "Available CPUs for this target:\n"; @@ -476,10 +468,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.RelaxELFRelocations = RelaxELFRelocations; #endif Options.UseInitArray = UseInitArray; - -#if LLVM_VERSION_LT(17, 0) - Options.ExplicitEmulatedTLS = true; -#endif Options.EmulatedTLS = UseEmulatedTls; if (TrapUnreachable) { @@ -761,16 +749,10 @@ LLVMRustOptimize( } std::optional PGOOpt; -#if LLVM_VERSION_GE(17, 0) auto FS = vfs::getRealFileSystem(); -#endif if (PGOGenPath) { assert(!PGOUsePath && !PGOSampleUsePath); - PGOOpt = PGOOptions(PGOGenPath, "", "", -#if LLVM_VERSION_GE(17, 0) - "", - FS, -#endif + PGOOpt = PGOOptions(PGOGenPath, "", "", "", FS, PGOOptions::IRInstr, PGOOptions::NoCSAction, #if LLVM_VERSION_GE(19, 0) PGOOptions::ColdFuncOpt::Default, @@ -778,33 +760,21 @@ LLVMRustOptimize( DebugInfoForProfiling); } else if (PGOUsePath) { assert(!PGOSampleUsePath); - PGOOpt = PGOOptions(PGOUsePath, "", "", -#if LLVM_VERSION_GE(17, 0) - "", - FS, -#endif + PGOOpt = PGOOptions(PGOUsePath, "", "", "", FS, PGOOptions::IRUse, PGOOptions::NoCSAction, #if LLVM_VERSION_GE(19, 0) PGOOptions::ColdFuncOpt::Default, #endif DebugInfoForProfiling); } else if (PGOSampleUsePath) { - PGOOpt = PGOOptions(PGOSampleUsePath, "", "", -#if LLVM_VERSION_GE(17, 0) - "", - FS, -#endif + PGOOpt = PGOOptions(PGOSampleUsePath, "", "", "", FS, PGOOptions::SampleUse, PGOOptions::NoCSAction, #if LLVM_VERSION_GE(19, 0) PGOOptions::ColdFuncOpt::Default, #endif DebugInfoForProfiling); } else if (DebugInfoForProfiling) { - PGOOpt = PGOOptions("", "", "", -#if LLVM_VERSION_GE(17, 0) - "", - FS, -#endif + PGOOpt = PGOOptions("", "", "", "", FS, PGOOptions::NoAction, PGOOptions::NoCSAction, #if LLVM_VERSION_GE(19, 0) PGOOptions::ColdFuncOpt::Default, @@ -1353,9 +1323,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, ComputeCrossModuleImport( Ret->Index, Ret->ModuleToDefinedGVSummaries, -#if LLVM_VERSION_GE(17, 0) isPrevailing, -#endif Ret->ImportLists, Ret->ExportLists ); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 91f54da5c12f7..f6ec410bfac21 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -2152,19 +2152,3 @@ extern "C" LLVMValueRef LLVMConstStringInContext2(LLVMContextRef C, return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), !DontNullTerminate)); } #endif - -// FIXME: Remove when Rust's minimum supported LLVM version reaches 17. -// https://github.com/llvm/llvm-project/commit/35276f16e5a2cae0dfb49c0fbf874d4d2f177acc -#if LLVM_VERSION_LT(17, 0) -extern "C" LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy, - LLVMValueRef *ConstantVals, - uint64_t Length) { - ArrayRef V(unwrap(ConstantVals, Length), Length); - return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); -} - -extern "C" LLVMTypeRef LLVMArrayType2(LLVMTypeRef ElementTy, - uint64_t ElementCount) { - return wrap(ArrayType::get(unwrap(ElementTy), ElementCount)); -} -#endif diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 701bd585eee76..3da927b5fa0fa 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -564,11 +564,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { let version = output(cmd.arg("--version")); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { - if major >= 16 { + if major >= 17 { return; } } - panic!("\n\nbad LLVM version: {version}, need >=16.0\n\n") + panic!("\n\nbad LLVM version: {version}, need >=17.0\n\n") } fn configure_cmake( diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile deleted file mode 100644 index 4fc2b2e507e0d..0000000000000 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile +++ /dev/null @@ -1,67 +0,0 @@ -FROM ubuntu:23.04 - -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - gcc-multilib \ - make \ - ninja-build \ - file \ - curl \ - ca-certificates \ - python3 \ - git \ - cmake \ - sudo \ - gdb \ - llvm-16-tools \ - llvm-16-dev \ - libedit-dev \ - libssl-dev \ - pkg-config \ - zlib1g-dev \ - xz-utils \ - nodejs \ - mingw-w64 \ - # libgccjit dependencies - flex \ - libmpfr-dev \ - libgmp-dev \ - libmpc3 \ - libmpc-dev \ - && rm -rf /var/lib/apt/lists/* - -# Note: libgccjit needs to match the default gcc version for the linker to find it. - -# Install powershell (universal package) so we can test x.ps1 on Linux -RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ - dpkg -i powershell.deb && \ - rm -f powershell.deb - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -# We are disabling CI LLVM since this builder is intentionally using a host -# LLVM, rather than the typical src/llvm-project LLVM. -ENV NO_DOWNLOAD_CI_LLVM 1 - -# This is not the latest LLVM version, so some components required by tests may -# be missing. -ENV IS_NOT_LATEST_LLVM 1 - -# Using llvm-link-shared due to libffi issues -- see #34486 -ENV RUST_CONFIGURE_ARGS \ - --build=x86_64-unknown-linux-gnu \ - --llvm-root=/usr/lib/llvm-16 \ - --enable-llvm-link-shared \ - --set rust.thin-lto-import-instr-limit=10 - -COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/ - -COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/ -COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ - -RUN /scripts/build-gccjit.sh /scripts - -ENV SCRIPT /tmp/script.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile index 7c2ecd198e234..538962802c96f 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile @@ -56,11 +56,10 @@ ENV RUST_CONFIGURE_ARGS \ --enable-llvm-link-shared \ --set rust.thin-lto-import-instr-limit=10 -COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/ - COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/ COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ RUN /scripts/build-gccjit.sh /scripts +COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh ENV SCRIPT /tmp/script.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile index e8383500dfc94..3476b10a3addc 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile @@ -24,11 +24,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ xz-utils \ nodejs \ mingw-w64 \ - libgccjit-13-dev \ + # libgccjit dependencies + flex \ + libmpfr-dev \ + libgmp-dev \ + libmpc3 \ + libmpc-dev \ && rm -rf /var/lib/apt/lists/* -# Note: libgccjit needs to match the default gcc version for the linker to find it. - # Install powershell (universal package) so we can test x.ps1 on Linux # FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ @@ -50,6 +53,10 @@ ENV RUST_CONFIGURE_ARGS \ --enable-llvm-link-shared \ --set rust.thin-lto-import-instr-limit=10 -COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/ +COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/ +COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/ + +RUN /scripts/build-gccjit.sh /scripts +COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh ENV SCRIPT /tmp/script.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/script.sh b/src/ci/docker/scripts/x86_64-gnu-llvm.sh similarity index 100% rename from src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/script.sh rename to src/ci/docker/scripts/x86_64-gnu-llvm.sh diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index bc81b1e04a764..972ef35933749 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -357,7 +357,7 @@ jobs: - name: mingw-check-tidy <<: *job-linux-4c - - name: x86_64-gnu-llvm-16 + - name: x86_64-gnu-llvm-17 env: ENABLE_GCC_CODEGEN: "1" <<: *job-linux-16c @@ -520,11 +520,6 @@ jobs: RUST_BACKTRACE: 1 <<: *job-linux-8c - - name: x86_64-gnu-llvm-16 - env: - RUST_BACKTRACE: 1 - <<: *job-linux-8c - - name: x86_64-gnu-nopt <<: *job-linux-4c diff --git a/tests/codegen/issues/issue-114312.rs b/tests/codegen/issues/issue-114312.rs index 54fa40dcf0d49..be5b999afd0b0 100644 --- a/tests/codegen/issues/issue-114312.rs +++ b/tests/codegen/issues/issue-114312.rs @@ -1,5 +1,4 @@ //@ compile-flags: -O -//@ min-llvm-version: 17 //@ only-x86_64-unknown-linux-gnu // We want to check that this function does not mis-optimize to loop jumping. diff --git a/tests/codegen/move-before-nocapture-ref-arg.rs b/tests/codegen/move-before-nocapture-ref-arg.rs index a530bc266729a..c3448192ea173 100644 --- a/tests/codegen/move-before-nocapture-ref-arg.rs +++ b/tests/codegen/move-before-nocapture-ref-arg.rs @@ -1,7 +1,6 @@ // Verify that move before the call of the function with noalias, nocapture, readonly. // #107436 //@ compile-flags: -O -//@ min-llvm-version: 17 #![crate_type = "lib"] diff --git a/tests/codegen/trailing_zeros.rs b/tests/codegen/trailing_zeros.rs index 66560c0d4fc47..b659e061821ea 100644 --- a/tests/codegen/trailing_zeros.rs +++ b/tests/codegen/trailing_zeros.rs @@ -1,5 +1,4 @@ //@ compile-flags: -O -//@ min-llvm-version: 17 #![crate_type = "lib"] diff --git a/tests/codegen/vec-shrink-panik.rs b/tests/codegen/vec-shrink-panik.rs index 4e996b234f98d..4b798fe6c9cba 100644 --- a/tests/codegen/vec-shrink-panik.rs +++ b/tests/codegen/vec-shrink-panik.rs @@ -1,8 +1,5 @@ -//@ revisions: old new // LLVM 17 realizes double panic is not possible and doesn't generate calls // to panic_cannot_unwind. -//@ [old]ignore-llvm-version: 17 - 99 -//@ [new]min-llvm-version: 17 //@ compile-flags: -O //@ ignore-debug: plain old debug assertions //@ needs-unwind @@ -22,14 +19,6 @@ pub fn shrink_to_fit(vec: &mut Vec) { // CHECK-LABEL: @issue71861 #[no_mangle] pub fn issue71861(vec: Vec) -> Box<[u32]> { - // CHECK-NOT: panic - - // Call to panic_cannot_unwind in case of double-panic is expected - // on LLVM 16 and older, but other panics are not. - // old: filter - // old-NEXT: ; call core::panicking::panic_cannot_unwind - // old-NEXT: panic_cannot_unwind - // CHECK-NOT: panic vec.into_boxed_slice() } @@ -40,6 +29,3 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> { // CHECK-NOT: panic iter.iter().copied().collect() } - -// old: ; core::panicking::panic_cannot_unwind -// old: declare void @{{.*}}panic_cannot_unwind diff --git a/tests/run-make/lto-linkage-used-attr/Makefile b/tests/run-make/lto-linkage-used-attr/Makefile index e78b83890ed3b..fed41a00f84b3 100644 --- a/tests/run-make/lto-linkage-used-attr/Makefile +++ b/tests/run-make/lto-linkage-used-attr/Makefile @@ -2,7 +2,6 @@ include ../tools.mk # Verify that the impl_* symbols are preserved. #108030 # only-x86_64-unknown-linux-gnu -# min-llvm-version: 17 all: $(RUSTC) -Cdebuginfo=0 -Copt-level=3 lib.rs diff --git a/tests/ui/codegen/target-cpus.rs b/tests/ui/codegen/target-cpus.rs index 85a940f9f74a0..2d46e00f8034e 100644 --- a/tests/ui/codegen/target-cpus.rs +++ b/tests/ui/codegen/target-cpus.rs @@ -1,4 +1,3 @@ //@ needs-llvm-components: webassembly -//@ min-llvm-version: 17 //@ compile-flags: --print=target-cpus --target=wasm32-unknown-unknown //@ check-pass From d9132de4ab020f43fa1893ab91f49dbc94afc60f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sun, 17 Mar 2024 10:52:00 -0700 Subject: [PATCH 05/12] Remove an obsolete `ignore-llvm-version` --- tests/codegen/option-as-slice.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/codegen/option-as-slice.rs b/tests/codegen/option-as-slice.rs index 14a3924360786..c5b1eafaccb74 100644 --- a/tests/codegen/option-as-slice.rs +++ b/tests/codegen/option-as-slice.rs @@ -1,7 +1,5 @@ //@ compile-flags: -O -Z randomize-layout=no //@ only-x86_64 -//@ ignore-llvm-version: 16.0.0 -// ^-- needs https://reviews.llvm.org/D146149 in 16.0.1 #![crate_type = "lib"] #![feature(generic_nonzero)] From 8beec62315538da7449fe869fd366181f7923b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 18 Mar 2024 09:27:47 +0000 Subject: [PATCH 06/12] do not eat nested exprs result in format args visitor --- compiler/rustc_ast_lowering/src/format.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 3f84e6b100d11..d2c3b8b2d5652 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -604,8 +604,7 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool { if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind { ControlFlow::Break(()) } else { - visit::walk_expr(self, e); - ControlFlow::Continue(()) + visit::walk_expr(self, e) } } From c96fa5e14345ca334073b32465e0ff3ef4b92ac5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 17 Mar 2024 17:02:38 +0100 Subject: [PATCH 07/12] add_retag: ensure box-to-raw-ptr casts are preserved for Miri --- .../src/transform/validate.rs | 4 +-- compiler/rustc_mir_transform/src/add_retag.rs | 36 +++++++++++++++---- compiler/rustc_mir_transform/src/lib.rs | 4 +-- library/alloc/src/boxed.rs | 17 ++++----- .../src/borrow_tracker/stacked_borrows/mod.rs | 20 +++++------ .../newtype_pair_retagging.stack.stderr | 2 +- .../newtype_retagging.stack.stderr | 2 +- ...fg-pre-optimizations.after.panic-abort.mir | 17 +++++++++ ...g-pre-optimizations.after.panic-unwind.mir | 17 +++++++++ tests/mir-opt/retag.rs | 5 +++ 10 files changed, 91 insertions(+), 33 deletions(-) create mode 100644 tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir create mode 100644 tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index f26c8f8592dea..68270dab28443 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -341,7 +341,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { // FIXME(JakobDegen) The validator should check that `self.mir_phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which // seem to fail to set their `MirPhase` correctly. - if matches!(kind, RetagKind::Raw | RetagKind::TwoPhase) { + if matches!(kind, RetagKind::TwoPhase) { self.fail(location, format!("explicit `{kind:?}` is forbidden")); } } @@ -1272,7 +1272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // FIXME(JakobDegen) The validator should check that `self.mir_phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which // seem to fail to set their `MirPhase` correctly. - if matches!(kind, RetagKind::Raw | RetagKind::TwoPhase) { + if matches!(kind, RetagKind::TwoPhase) { self.fail(location, format!("explicit `{kind:?}` is forbidden")); } } diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 6f668aa4ce850..f880476cec2f2 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -24,7 +24,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b | ty::Str | ty::FnDef(..) | ty::Never => false, - // References + // References and Boxes (`noalias` sources) ty::Ref(..) => true, ty::Adt(..) if ty.is_box() => true, ty::Adt(adt, _) if Some(adt.did()) == tcx.lang_items().ptr_unique() => true, @@ -125,15 +125,39 @@ impl<'tcx> MirPass<'tcx> for AddRetag { for i in (0..block_data.statements.len()).rev() { let (retag_kind, place) = match block_data.statements[i].kind { // Retag after assignments of reference type. - StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => { + StatementKind::Assign(box (ref place, ref rvalue)) => { let add_retag = match rvalue { // Ptr-creating operations already do their own internal retagging, no // need to also add a retag statement. - Rvalue::Ref(..) | Rvalue::AddressOf(..) => false, - _ => true, + // *Except* if we are deref'ing a Box, because those get desugared to directly working + // with the inner raw pointer! That's relevant for `AddressOf` as Miri otherwise makes it + // a NOP when the original pointer is already raw. + Rvalue::AddressOf(_mutbl, place) => { + // Using `is_box_global` here is a bit sketchy: if this code is + // generic over the allocator, we'll not add a retag! This is a hack + // to make Stacked Borrows compatible with custom allocator code. + // Long-term, we'll want to move to an aliasing model where "cast to + // raw pointer" is a complete NOP, and then this will no longer be + // an issue. + if place.is_indirect_first_projection() + && body.local_decls[place.local].ty.is_box_global(tcx) + { + Some(RetagKind::Raw) + } else { + None + } + } + Rvalue::Ref(..) => None, + _ => { + if needs_retag(place) { + Some(RetagKind::Default) + } else { + None + } + } }; - if add_retag { - (RetagKind::Default, *place) + if let Some(kind) = add_retag { + (kind, *place) } else { continue; } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 3e5ec323d2746..afe228be12797 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -529,11 +529,11 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // AddMovesForPackedDrops needs to run after drop // elaboration. &add_moves_for_packed_drops::AddMovesForPackedDrops, - // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, + // `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`. Otherwise it should run fairly late, // but before optimizations begin. + &add_retag::AddRetag, &elaborate_box_derefs::ElaborateBoxDerefs, &coroutine::StateTransform, - &add_retag::AddRetag, &Lint(known_panics_lint::KnownPanicsLint), ]; pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial))); diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 304f607000b01..f47fe560b07a2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -155,7 +155,6 @@ use core::error::Error; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -use core::intrinsics::retag_box_to_raw; use core::iter::FusedIterator; use core::marker::Tuple; use core::marker::Unsize; @@ -165,7 +164,7 @@ use core::ops::{ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver, }; use core::pin::Pin; -use core::ptr::{self, NonNull, Unique}; +use core::ptr::{self, addr_of_mut, NonNull, Unique}; use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))] @@ -1111,16 +1110,12 @@ impl Box { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { - // This is the transition point from `Box` to raw pointers. For Stacked Borrows, these casts - // are relevant -- if this is a global allocator Box and we just get the pointer from `b.0`, - // it will have `Unique` permission, which is not what we want from a raw pointer. We could - // fix that by going through `&mut`, but then if this is *not* a global allocator Box, we'd - // be adding uniqueness assertions that we do not want. So for Miri's sake we pass this - // pointer through an intrinsic for box-to-raw casts, which can do the right thing wrt the - // aliasing model. - let b = mem::ManuallyDrop::new(b); + let mut b = mem::ManuallyDrop::new(b); + // We carefully get the raw pointer out in a way that Miri's aliasing model understands what + // is happening: using the primitive "deref" of `Box`. + let ptr = addr_of_mut!(**b); let alloc = unsafe { ptr::read(&b.1) }; - (unsafe { retag_box_to_raw::(b.0.as_ptr()) }, alloc) + (ptr, alloc) } #[unstable( diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 9130601bbddb9..613a245c06f1d 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -891,9 +891,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields; let retag_cause = match kind { - RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(), // these can only happen in `retag_ptr_value` + RetagKind::TwoPhase { .. } => unreachable!(), // can only happen in `retag_ptr_value` RetagKind::FnEntry => RetagCause::FnEntry, - RetagKind::Default => RetagCause::Normal, + RetagKind::Default | RetagKind::Raw => RetagCause::Normal, }; let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields, in_field: false }; @@ -959,14 +959,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Check the type of this value to see what to do with it (retag, or recurse). match place.layout.ty.kind() { - ty::Ref(..) => { - let new_perm = - NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx); - self.retag_ptr_inplace(place, new_perm)?; - } - ty::RawPtr(..) => { - // We do *not* want to recurse into raw pointers -- wide raw pointers have - // fields, and for dyn Trait pointees those can have reference type! + ty::Ref(..) | ty::RawPtr(..) => { + if matches!(place.layout.ty.kind(), ty::Ref(..)) + || self.kind == RetagKind::Raw + { + let new_perm = + NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx); + self.retag_ptr_inplace(place, new_perm)?; + } } ty::Adt(adt, _) if adt.is_box() => { // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above. diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr index c26c7f397b09f..867907e98e66f 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: was created by a SharedReadWrite retag at offsets [0x0..0x4] +help: was created by a Unique retag at offsets [0x0..0x4] --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr index ae54da70fe2d8..56715938e9788 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: was created by a SharedReadWrite retag at offsets [0x0..0x4] +help: was created by a Unique retag at offsets [0x0..0x4] --> $DIR/newtype_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir new file mode 100644 index 0000000000000..0e568f6a5685f --- /dev/null +++ b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -0,0 +1,17 @@ +// MIR for `box_to_raw_mut` after SimplifyCfg-pre-optimizations + +fn box_to_raw_mut(_1: &mut Box) -> *mut i32 { + debug x => _1; + let mut _0: *mut i32; + let mut _2: std::boxed::Box; + let mut _3: *const i32; + + bb0: { + Retag([fn entry] _1); + _2 = deref_copy (*_1); + _3 = (((_2.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); + _0 = &raw mut (*_3); + Retag([raw] _0); + return; + } +} diff --git a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir new file mode 100644 index 0000000000000..0e568f6a5685f --- /dev/null +++ b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -0,0 +1,17 @@ +// MIR for `box_to_raw_mut` after SimplifyCfg-pre-optimizations + +fn box_to_raw_mut(_1: &mut Box) -> *mut i32 { + debug x => _1; + let mut _0: *mut i32; + let mut _2: std::boxed::Box; + let mut _3: *const i32; + + bb0: { + Retag([fn entry] _1); + _2 = deref_copy (*_1); + _3 = (((_2.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); + _0 = &raw mut (*_3); + Retag([raw] _0); + return; + } +} diff --git a/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs index 9cee96e429498..17b3c10abeb18 100644 --- a/tests/mir-opt/retag.rs +++ b/tests/mir-opt/retag.rs @@ -65,3 +65,8 @@ fn array_casts() { let p = &x as *const usize; assert_eq!(unsafe { *p.add(1) }, 1); } + +// EMIT_MIR retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.mir +fn box_to_raw_mut(x: &mut Box) -> *mut i32 { + std::ptr::addr_of_mut!(**x) +} From bcf8015177683efb407cbab2b05f98322da9dab3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 17 Mar 2024 17:03:45 +0100 Subject: [PATCH 08/12] remove retag_box_to_raw, it is no longer needed --- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 ---- compiler/rustc_span/src/symbol.rs | 1 - library/core/src/intrinsics.rs | 13 ------------- src/tools/miri/src/borrow_tracker/mod.rs | 15 +-------------- .../src/borrow_tracker/stacked_borrows/mod.rs | 18 ------------------ .../src/borrow_tracker/tree_borrows/mod.rs | 9 --------- src/tools/miri/src/shims/intrinsics/mod.rs | 12 ------------ 7 files changed, 1 insertion(+), 71 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index bf5838143d945..35755a46df3a4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -658,10 +658,6 @@ pub fn check_intrinsic_type( sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)), - sym::retag_box_to_raw => { - (2, 0, vec![Ty::new_mut_ptr(tcx, param(0))], Ty::new_mut_ptr(tcx, param(0))) - } - other => { tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other }); return; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e43c9533382e1..63b950a2803c4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1463,7 +1463,6 @@ symbols! { residual, result, resume, - retag_box_to_raw, return_position_impl_trait_in_trait, return_type_notation, rhs, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 86b9a39d68a67..f939720287fd4 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2709,19 +2709,6 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize { unreachable!() } -/// Retag a box pointer as part of casting it to a raw pointer. This is the `Box` equivalent of -/// `(x: &mut T) as *mut T`. The input pointer must be the pointer of a `Box` (passed as raw pointer -/// to avoid all questions around move semantics and custom allocators), and `A` must be the `Box`'s -/// allocator. -#[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_nounwind] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] -#[cfg_attr(bootstrap, inline)] -pub unsafe fn retag_box_to_raw(ptr: *mut T) -> *mut T { - // Miri needs to adjust the provenance, but for regular codegen this is not needed - ptr -} - // Some functions are defined here because they accidentally got made // available in this module on stable. See . // (`transmute` also falls into this category, but it cannot be wrapped due to the diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 0f7200fb4074a..8d76a488269fc 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -5,7 +5,7 @@ use std::num::NonZero; use smallvec::SmallVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_middle::{mir::RetagKind, ty::Ty}; +use rustc_middle::mir::RetagKind; use rustc_target::abi::Size; use crate::*; @@ -291,19 +291,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } - fn retag_box_to_raw( - &mut self, - val: &ImmTy<'tcx, Provenance>, - alloc_ty: Ty<'tcx>, - ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { - let this = self.eval_context_mut(); - let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; - match method { - BorrowTrackerMethod::StackedBorrows => this.sb_retag_box_to_raw(val, alloc_ty), - BorrowTrackerMethod::TreeBorrows => this.tb_retag_box_to_raw(val, alloc_ty), - } - } - fn retag_place_contents( &mut self, kind: RetagKind, diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 613a245c06f1d..7a6a85a2f7905 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -865,24 +865,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.sb_retag_reference(val, new_perm, RetagInfo { cause, in_field: false }) } - fn sb_retag_box_to_raw( - &mut self, - val: &ImmTy<'tcx, Provenance>, - alloc_ty: Ty<'tcx>, - ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { - let this = self.eval_context_mut(); - let is_global_alloc = alloc_ty.ty_adt_def().is_some_and(|adt| { - let global_alloc = this.tcx.require_lang_item(rustc_hir::LangItem::GlobalAlloc, None); - adt.did() == global_alloc - }); - if is_global_alloc { - // Retag this as-if it was a mutable reference. - this.sb_retag_ptr_value(RetagKind::Raw, val) - } else { - Ok(val.clone()) - } - } - fn sb_retag_place_contents( &mut self, kind: RetagKind, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 9eb78b08ef77d..80bdcbb7559f2 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -392,15 +392,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } - fn tb_retag_box_to_raw( - &mut self, - val: &ImmTy<'tcx, Provenance>, - _alloc_ty: Ty<'tcx>, - ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { - // Casts to raw pointers are NOPs in Tree Borrows. - Ok(val.clone()) - } - /// Retag all pointers that are stored in this place. fn tb_retag_place_contents( &mut self, diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index 976d4b4de55cb..d16d5d99e9c01 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -140,18 +140,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?; } - "retag_box_to_raw" => { - let [ptr] = check_arg_count(args)?; - let alloc_ty = generic_args[1].expect_ty(); - - let val = this.read_immediate(ptr)?; - let new_val = if this.machine.borrow_tracker.is_some() { - this.retag_box_to_raw(&val, alloc_ty)? - } else { - val - }; - this.write_immediate(*new_val, dest)?; - } // We want to return either `true` or `false` at random, or else something like // ``` From adda9da604a7f384d2714ec055d9c70018b163d1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 14 Mar 2024 09:10:28 +0000 Subject: [PATCH 09/12] Avoid various uses of `Option` in favor of using `DUMMY_SP` in the few cases that used `None` --- compiler/rustc_codegen_cranelift/src/constant.rs | 2 +- .../src/intrinsics/mod.rs | 6 ++++-- .../src/intrinsics/simd.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- .../src/debuginfo/type_names.rs | 3 ++- compiler/rustc_codegen_ssa/src/mir/constant.rs | 8 ++------ compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 2 +- .../src/interpret/eval_context.rs | 4 ++-- .../rustc_const_eval/src/interpret/intrinsics.rs | 5 ++--- .../rustc_const_eval/src/interpret/machine.rs | 4 ++-- .../rustc_const_eval/src/interpret/operand.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 11 ++++------- compiler/rustc_middle/src/mir/consts.rs | 10 +++++----- .../rustc_middle/src/mir/interpret/queries.rs | 16 ++++++++-------- compiler/rustc_middle/src/ty/consts.rs | 10 +++++----- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 9 ++++----- .../src/dataflow_const_prop.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 2 +- .../rustc_mir_transform/src/jump_threading.rs | 2 +- .../rustc_mir_transform/src/known_panics_lint.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_smir/src/rustc_smir/builder.rs | 2 +- compiler/rustc_smir/src/rustc_smir/context.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 2 +- .../src/traits/auto_trait.rs | 2 +- .../src/traits/const_evaluatable.rs | 4 ++-- .../rustc_trait_selection/src/traits/fulfill.rs | 2 +- .../src/traits/select/mod.rs | 2 +- compiler/rustc_transmute/src/lib.rs | 3 ++- .../clippy/clippy_lints/src/non_copy_const.rs | 10 +++++----- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/miri/src/machine.rs | 4 ++-- src/tools/miri/src/shims/intrinsics/simd.rs | 2 +- 34 files changed, 70 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 39fa277fedc55..fc9b0f6ef024f 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -74,7 +74,7 @@ pub(crate) fn eval_mir_constant<'tcx>( let cv = fx.monomorphize(constant.const_); // This cannot fail because we checked all required_consts in advance. let val = cv - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span) .expect("erroneous constant missed by mono item collection"); (val, cv.ty()) } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 8b86a116df1fd..c802d9bbefbed 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -728,8 +728,10 @@ fn codegen_regular_intrinsic_call<'tcx>( | sym::variant_count => { intrinsic_args!(fx, args => (); intrinsic); - let const_val = - fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap(); + let const_val = fx + .tcx + .const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span) + .unwrap(); let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); ret.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 79da970a58efe..4d55a95aa9db7 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -131,7 +131,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx = generic_args[2] .expect_const() - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() .unwrap_branch(); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 467e02d55e332..71b69a94e99e7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1129,7 +1129,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_shuffle_generic { let idx = fn_args[2] .expect_const() - .eval(tcx, ty::ParamEnv::reveal_all(), Some(span)) + .eval(tcx, ty::ParamEnv::reveal_all(), span) .unwrap() .unwrap_branch(); let n = idx.len() as u64; diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 5bd7442822a21..fcd7fa9247b0e 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -19,6 +19,7 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability} use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_span::DUMMY_SP; use rustc_target::abi::Integer; use smallvec::SmallVec; @@ -704,7 +705,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S // avoiding collisions and will make the emitted type names shorter. let hash_short = tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); - let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), None).unwrap(); + let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap(); hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher)); hasher.finish::() }); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index ff899c50b3de6..c6260d3591618 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -24,7 +24,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // `MirUsedCollector` visited all required_consts before codegen began, so if we got here // there can be no more constants that fail to evaluate. self.monomorphize(constant.const_) - .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span)) + .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), constant.span) .expect("erroneous constant missed by mono item collection") } @@ -56,11 +56,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { other => span_bug!(constant.span, "{other:#?}"), }; let uv = self.monomorphize(uv); - self.cx.tcx().const_eval_resolve_for_typeck( - ty::ParamEnv::reveal_all(), - uv, - Some(constant.span), - ) + self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span) } /// process constant containing SIMD shuffle indices diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 1d1826d984474..ba023f96107a4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -130,7 +130,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | sym::variant_count => { let value = bx .tcx() - .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) + .const_eval_instance(ty::ParamEnv::reveal_all(), instance, span) .unwrap(); OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx) } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 09e9cc4b35d31..730e8977803cd 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -826,7 +826,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { for &const_ in &body.required_consts { let c = self .instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?; - c.eval(*self.tcx, self.param_env, Some(const_.span)).map_err(|err| { + c.eval(*self.tcx, self.param_env, const_.span).map_err(|err| { err.emit_note(*self.tcx); err })?; @@ -1174,7 +1174,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn eval_mir_constant( &self, val: &mir::Const<'tcx>, - span: Option, + span: Span, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index b68bfb4211d1e..748c7dce5a3ab 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -153,9 +153,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::type_name => Ty::new_static_str(self.tcx.tcx), _ => bug!(), }; - let val = self.ctfe_query(|tcx| { - tcx.const_eval_global_id(self.param_env, gid, Some(tcx.span)) - })?; + let val = + self.ctfe_query(|tcx| tcx.const_eval_global_id(self.param_env, gid, tcx.span))?; let val = self.const_val_to_op(val, ty, Some(dest.layout))?; self.copy_op(&val, dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index afc4a80c283f4..827d8fd9417ce 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -525,7 +525,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { fn eval_mir_constant( ecx: &InterpCx<'mir, 'tcx, Self>, val: mir::Const<'tcx>, - span: Option, + span: Span, layout: Option>, eval: F, ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> @@ -533,7 +533,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { F: Fn( &InterpCx<'mir, 'tcx, Self>, mir::Const<'tcx>, - Option, + Span, Option>, ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>, { diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index e49067a2f0063..dbc6a317640c1 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -741,7 +741,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all // checked yet. // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. - self.eval_mir_constant(&c, Some(constant.span), layout)? + self.eval_mir_constant(&c, constant.span, layout)? } }; trace!("{:?}: {:?}", mir_op, op); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 553729503688c..491da7eb2c2a9 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2178,7 +2178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { len: ty::Const<'tcx>, min_len: u64, ) -> (Option>, Ty<'tcx>) { - let len = match len.eval(self.tcx, self.param_env, None) { + let len = match len.eval(self.tcx, self.param_env, span) { Ok(val) => val .try_to_scalar() .and_then(|scalar| scalar.try_to_int().ok()) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 89e4e88b3df24..44e14387c5c8b 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1475,7 +1475,7 @@ impl<'tcx> InferCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, unevaluated: ty::UnevaluatedConst<'tcx>, ty: Ty<'tcx>, - span: Option, + span: Span, ) -> Result, ErrorHandled> { match self.const_eval_resolve(param_env, unevaluated, span) { Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)), @@ -1509,7 +1509,7 @@ impl<'tcx> InferCtxt<'tcx> { &self, mut param_env: ty::ParamEnv<'tcx>, unevaluated: ty::UnevaluatedConst<'tcx>, - span: Option, + span: Span, ) -> EvalToValTreeResult<'tcx> { let mut args = self.resolve_vars_if_possible(unevaluated.args); debug!(?args); @@ -1521,12 +1521,9 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args)); if let Err(e) = ct.error_reported() { - return Err(ErrorHandled::Reported( - e.into(), - span.unwrap_or(rustc_span::DUMMY_SP), - )); + return Err(ErrorHandled::Reported(e.into(), span)); } else if ct.has_non_region_infer() || ct.has_non_region_param() { - return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))); + return Err(ErrorHandled::TooGeneric(span)); } else { args = replace_param_and_infer_args_with_placeholder(tcx, args); } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 5feee3c3ba10f..214297b98695f 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use rustc_hir::def_id::DefId; use rustc_session::RemapFileNameExt; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{HasDataLayout, Size}; use crate::mir::interpret::{alloc_range, AllocId, ConstAllocation, ErrorHandled, Scalar}; @@ -273,7 +273,7 @@ impl<'tcx> Const<'tcx> { self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - span: Option, + span: Span, ) -> Result, ErrorHandled> { match self { Const::Ty(c) => { @@ -293,7 +293,7 @@ impl<'tcx> Const<'tcx> { /// Normalizes the constant to a value or an error if possible. #[inline] pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { - match self.eval(tcx, param_env, None) { + match self.eval(tcx, param_env, DUMMY_SP) { Ok(val) => Self::Val(val, self.ty()), Err(ErrorHandled::Reported(guar, _span)) => { Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty())) @@ -313,10 +313,10 @@ impl<'tcx> Const<'tcx> { // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that // are valtree leaves, and *not* on references. (References should return the // pointer here, which valtrees don't represent.) - let val = c.eval(tcx, param_env, None).ok()?; + let val = c.eval(tcx, param_env, DUMMY_SP).ok()?; Some(val.unwrap_leaf().into()) } - _ => self.eval(tcx, param_env, None).ok()?.try_to_scalar(), + _ => self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar(), } } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 643b61c1de3d7..04d6301116eea 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -24,7 +24,7 @@ impl<'tcx> TyCtxt<'tcx> { let instance = ty::Instance::new(def_id, args); let cid = GlobalId { instance, promoted: None }; let param_env = self.param_env(def_id).with_reveal_all_normalized(self); - self.const_eval_global_id(param_env, cid, None) + self.const_eval_global_id(param_env, cid, DUMMY_SP) } /// Resolves and evaluates a constant. /// @@ -40,7 +40,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, ct: mir::UnevaluatedConst<'tcx>, - span: Option, + span: Span, ) -> EvalToConstValueResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference // variables. We reject those here since `resolve` @@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, ct: ty::UnevaluatedConst<'tcx>, - span: Option, + span: Span, ) -> EvalToValTreeResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference // variables. We reject those here since `resolve` @@ -130,7 +130,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, - span: Option, + span: Span, ) -> EvalToConstValueResult<'tcx> { self.const_eval_global_id(param_env, GlobalId { instance, promoted: None }, span) } @@ -141,12 +141,12 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, cid: GlobalId<'tcx>, - span: Option, + span: Span, ) -> EvalToConstValueResult<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid)); - if let Some(span) = span { + if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span)) } else { @@ -160,13 +160,13 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, cid: GlobalId<'tcx>, - span: Option, + span: Span, ) -> EvalToValTreeResult<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid)); debug!(?inputs); - if let Some(span) = span { + if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. self.at(span).eval_to_valtree(inputs).map_err(|e| e.with_span(span)) } else { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 5b62c0bf931af..0d621cd1cfd9b 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -335,7 +335,7 @@ impl<'tcx> Const<'tcx> { self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, - span: Option, + span: Span, ) -> Result, ErrorHandled> { assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}"); match self.kind() { @@ -349,7 +349,7 @@ impl<'tcx> Const<'tcx> { else { // This can happen when we run on ill-typed code. let e = tcx.dcx().span_delayed_bug( - span.unwrap_or(DUMMY_SP), + span, "`ty::Const::eval` called on a non-valtree-compatible type", ); return Err(e.into()); @@ -362,14 +362,14 @@ impl<'tcx> Const<'tcx> { | ConstKind::Infer(_) | ConstKind::Bound(_, _) | ConstKind::Placeholder(_) - | ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))), + | ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span)), } } /// Normalizes the constant to a value or an error if possible. #[inline] pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { - match self.eval(tcx, param_env, None) { + match self.eval(tcx, param_env, DUMMY_SP) { Ok(val) => Self::new_value(tcx, val, self.ty()), Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()), Err(ErrorHandled::TooGeneric(_span)) => self, @@ -382,7 +382,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.eval(tcx, param_env, None).ok()?.try_to_scalar() + self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar() } #[inline] diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index ac3043afcff08..03eda9a932223 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -524,12 +524,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // Prefer valtrees over opaque constants. let const_value = self .tcx - .const_eval_global_id_for_typeck(param_env_reveal_all, cid, Some(span)) + .const_eval_global_id_for_typeck(param_env_reveal_all, cid, span) .map(|val| match val { Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), None => mir::Const::Val( self.tcx - .const_eval_global_id(param_env_reveal_all, cid, Some(span)) + .const_eval_global_id(param_env_reveal_all, cid, span) .expect("const_eval_global_id_for_typeck should have already failed"), ty, ), @@ -627,15 +627,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // First try using a valtree in order to destructure the constant into a pattern. // FIXME: replace "try to do a thing, then fall back to another thing" // but something more principled, like a trait query checking whether this can be turned into a valtree. - if let Ok(Some(valtree)) = - self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span)) + if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span) { let subpattern = self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span); PatKind::InlineConstant { subpattern, def: def_id } } else { // If that fails, convert it to an opaque constant pattern. - match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) { + match tcx.const_eval_resolve(self.param_env, uneval, span) { Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span).kind, Err(ErrorHandled::TooGeneric(_)) => { // If we land here it means the const can't be evaluated because it's `TooGeneric`. diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index f456196b2822d..3389305e7eee7 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -394,7 +394,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } Operand::Constant(box constant) => { if let Ok(constant) = - self.ecx.eval_mir_constant(&constant.const_, Some(constant.span), None) + self.ecx.eval_mir_constant(&constant.const_, constant.span, None) { self.assign_constant(state, place, constant, &[]); } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index a3a2108787a73..87dff49e0be65 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -367,7 +367,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Repeat(..) => return None, Constant { ref value, disambiguator: _ } => { - self.ecx.eval_mir_constant(value, None, None).ok()? + self.ecx.eval_mir_constant(value, DUMMY_SP, None).ok()? } Aggregate(kind, variant, ref fields) => { let fields = fields diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 6629face94041..116d6f4845660 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -417,7 +417,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`. Operand::Constant(constant) => { let constant = - self.ecx.eval_mir_constant(&constant.const_, Some(constant.span), None).ok()?; + self.ecx.eval_mir_constant(&constant.const_, constant.span, None).ok()?; self.process_constant(bb, lhs, constant, state); } // Transfer the conditions on the copied rhs. diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 4bca437ea6f27..f19b78a3a5cd2 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -261,7 +261,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // manually normalized. let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.const_).ok()?; - self.use_ecx(|this| this.ecx.eval_mir_constant(&val, Some(c.span), None))? + self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))? .as_mplace_or_imm() .right() } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index dd8cb6127be96..d8bdbd8c442b0 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -828,7 +828,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // a codegen-time error). rustc stops after collection if there was an error, so this // ensures codegen never has to worry about failing consts. // (codegen relies on this and ICEs will happen if this is violated.) - let val = match const_.eval(self.tcx, param_env, Some(constant.span)) { + let val = match const_.eval(self.tcx, param_env, constant.span) { Ok(v) => v, Err(ErrorHandled::TooGeneric(..)) => span_bug!( self.body.source_info(location).span, diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index a13262cdcc494..0762016ef75b3 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -56,7 +56,7 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> { fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) { let const_ = self.monomorphize(constant.const_); - let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) { + let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), constant.span) { Ok(v) => v, Err(mir::interpret::ErrorHandled::Reported(..)) => return, Err(mir::interpret::ErrorHandled::TooGeneric(..)) => { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 509f0def2568e..d427e5fb88d61 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -566,7 +566,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let result = tcx.const_eval_instance( ParamEnv::reveal_all(), instance, - Some(tcx.def_span(instance.def_id())), + tcx.def_span(instance.def_id()), ); result .map(|const_val| { diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 3b858cb449fa1..a4ee0e03e6556 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -968,7 +968,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ty: Ty<'tcx>, ) -> Option> { use rustc_middle::mir::interpret::ErrorHandled; - match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, None) { + match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, DUMMY_SP) { Ok(ct) => Some(ct), Err(ErrorHandled::Reported(e, _)) => { Some(ty::Const::new_error(self.tcx(), e.into(), ty)) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index fbf96833187d8..0796ffcbc45a0 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -786,7 +786,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { match selcx.infcx.const_eval_resolve( obligation.param_env, unevaluated, - Some(obligation.cause.span), + obligation.cause.span, ) { Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, c.ty())), Ok(None) => { diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 7f0f9a12d6a05..9ca1dd4557dc8 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -68,7 +68,7 @@ pub fn is_const_evaluatable<'tcx>( tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported"); } ty::ConstKind::Unevaluated(uv) => { - let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, span); match concrete { Err(ErrorHandled::TooGeneric(_)) => { Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug( @@ -99,7 +99,7 @@ pub fn is_const_evaluatable<'tcx>( // and hopefully soon change this to an error. // // See #74595 for more details about this. - let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, span); match concrete { // If we're evaluating a generic foreign constant, under a nightly compiler while // the current crate does not enable `feature(generic_const_exprs)`, abort diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2fd64f474d5ad..34c891d400e45 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -600,7 +600,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { obligation.param_env, unevaluated, c.ty(), - Some(obligation.cause.span), + obligation.cause.span, ) { Ok(val) => Ok(val), Err(e) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d10fe6a949013..be71eac6948a6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -949,7 +949,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, unevaluated, c.ty(), - Some(obligation.cause.span), + obligation.cause.span, ) { Ok(val) => Ok(val), Err(e) => Err(e), diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index e871c4659b4b9..b6f937ebe472b 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -89,6 +89,7 @@ mod rustc { use rustc_middle::ty::Ty; use rustc_middle::ty::TyCtxt; use rustc_middle::ty::ValTree; + use rustc_span::DUMMY_SP; /// The source and destination types of a transmutation. #[derive(TypeVisitable, Debug, Clone, Copy)] @@ -135,7 +136,7 @@ mod rustc { use rustc_middle::ty::ScalarInt; use rustc_span::symbol::sym; - let Ok(cv) = c.eval(tcx, param_env, None) else { + let Ok(cv) = c.eval(tcx, param_env, DUMMY_SP) else { return Some(Self { alignment: true, lifetimes: true, diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index ea73d9afa2ea0..cebd23856565d 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -290,14 +290,14 @@ impl NonCopyConst { promoted: None, }; let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); - let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None); + let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, rustc_span::DUMMY_SP); self.is_value_unfrozen_raw(cx, result, ty) } fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let args = cx.typeck_results().node_args(hir_id); - let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), None); + let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), rustc_span::DUMMY_SP); self.is_value_unfrozen_raw(cx, result, ty) } @@ -305,7 +305,7 @@ impl NonCopyConst { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ct: ty::UnevaluatedConst<'tcx>, - span: Option, + span: Span, ) -> EvalToValTreeResult<'tcx> { match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) { Ok(Some(instance)) => { @@ -315,8 +315,8 @@ impl NonCopyConst { }; tcx.const_eval_global_id_for_typeck(param_env, cid, span) }, - Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))), - Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))), + Ok(None) => Err(ErrorHandled::TooGeneric(span)), + Err(err) => Err(ErrorHandled::Reported(err.into(), span)), } } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 07ed4fbbf8e9e..e75d5953faefd 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -550,7 +550,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { let result = self .lcx .tcx - .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None) + .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span()) .ok() .map(|val| rustc_middle::mir::Const::from_value(val, ty))?; let result = mir_to_const(self.lcx, result)?; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 7e5518392d8a7..3a4ab32e4ab8a 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1503,7 +1503,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { fn eval_mir_constant( ecx: &InterpCx<'mir, 'tcx, Self>, val: mir::Const<'tcx>, - span: Option, + span: Span, layout: Option>, eval: F, ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> @@ -1511,7 +1511,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { F: Fn( &InterpCx<'mir, 'tcx, Self>, mir::Const<'tcx>, - Option, + Span, Option>, ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>, { diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index ddddcdcebd2af..c97a052f51715 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -549,7 +549,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let index = generic_args[2] .expect_const() - .eval(*this.tcx, this.param_env(), Some(this.tcx.span)) + .eval(*this.tcx, this.param_env(), this.tcx.span) .unwrap() .unwrap_branch(); let index_len = index.len(); From f3e9dfaed6c4d44fc0a5182221c31e5b0ff038fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 18 Mar 2024 09:33:16 +0000 Subject: [PATCH 10/12] add non-regression test for issue 122674 --- tests/ui/fmt/nested-awaits-issue-122674.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/ui/fmt/nested-awaits-issue-122674.rs diff --git a/tests/ui/fmt/nested-awaits-issue-122674.rs b/tests/ui/fmt/nested-awaits-issue-122674.rs new file mode 100644 index 0000000000000..f250933dadb48 --- /dev/null +++ b/tests/ui/fmt/nested-awaits-issue-122674.rs @@ -0,0 +1,22 @@ +// Non-regression test for issue #122674: a change in the format args visitor missed nested awaits. + +//@ edition: 2021 +//@ check-pass + +pub fn f1() -> impl std::future::Future> + Send { + async { + should_work().await?; + Ok(()) + } +} + +async fn should_work() -> Result { + let x = 1; + Err(format!("test: {}: {}", x, inner().await?)) +} + +async fn inner() -> Result { + Ok("test".to_string()) +} + +fn main() {} From 0550afd97e7d93e52249e83152d53f1facb3b823 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 18 Mar 2024 14:25:50 +0200 Subject: [PATCH 11/12] add missing test: expected paren or brace in macro --- tests/ui/macros/paren-or-brace-expected.rs | 9 +++++++++ tests/ui/macros/paren-or-brace-expected.stderr | 14 ++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/macros/paren-or-brace-expected.rs create mode 100644 tests/ui/macros/paren-or-brace-expected.stderr diff --git a/tests/ui/macros/paren-or-brace-expected.rs b/tests/ui/macros/paren-or-brace-expected.rs new file mode 100644 index 0000000000000..1776fa788847d --- /dev/null +++ b/tests/ui/macros/paren-or-brace-expected.rs @@ -0,0 +1,9 @@ +macro_rules! foo { + ( $( $i:ident ),* ) => { + $[count($i)] + //~^ ERROR expected `(` or `{`, found `[` + //~| ERROR + }; +} + +fn main() {} diff --git a/tests/ui/macros/paren-or-brace-expected.stderr b/tests/ui/macros/paren-or-brace-expected.stderr new file mode 100644 index 0000000000000..4d1dda9775133 --- /dev/null +++ b/tests/ui/macros/paren-or-brace-expected.stderr @@ -0,0 +1,14 @@ +error: expected `(` or `{`, found `[` + --> $DIR/paren-or-brace-expected.rs:3:10 + | +LL | $[count($i)] + | ^^^^^^^^^^^ + +error: expected one of: `*`, `+`, or `?` + --> $DIR/paren-or-brace-expected.rs:3:10 + | +LL | $[count($i)] + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 407b58cb77449653df9c5a2678e7d404f8f6b460 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 18 Mar 2024 11:21:06 -0400 Subject: [PATCH 12/12] Add missing `try_visit` calls in visitors. --- compiler/rustc_ast/src/visit.rs | 4 ++-- compiler/rustc_hir/src/intravisit.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d75ff4565e6f0..825f8dad8e480 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -755,7 +755,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>( } AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => { if let Some(qself) = qself { - visitor.visit_ty(&qself.ty); + try_visit!(visitor.visit_ty(&qself.ty)); } try_visit!(visitor.visit_path(path, *id)); visit_opt!(visitor, visit_block, body); @@ -994,7 +994,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), ExprKind::OffsetOf(container, fields) => { - visitor.visit_ty(container); + try_visit!(visitor.visit_ty(container)); walk_list!(visitor, visit_ident, fields.iter().copied()); } ExprKind::Yield(optional_expression) => { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index fbbad38d17f10..186bb234a450b 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -899,7 +899,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( GenericParamKind::Const { ref ty, ref default, is_host_effect: _ } => { try_visit!(visitor.visit_ty(ty)); if let Some(ref default) = default { - visitor.visit_const_param_default(param.hir_id, default); + try_visit!(visitor.visit_const_param_default(param.hir_id, default)); } } }