diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 961b643fa2510..216b89fd4f150 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -505,7 +505,6 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { } pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let _indenter = indenter(); match tcx.def_kind(def_id) { DefKind::Static { .. } => { tcx.ensure().typeck(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 938c0a19e338f..024a0433b8cf6 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -103,7 +103,6 @@ use rustc_trait_selection::traits::ObligationCtxt; use crate::errors; use crate::require_c_abi_if_c_variadic; -use crate::util::common::indenter; use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys; use self::region::region_scope_tree; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 5a374fa5e04c0..c374f9762d69b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -103,7 +103,6 @@ use rustc_middle::middle; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::util; use rustc_session::parse::feature_err; use rustc_span::{symbol::sym, Span}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index da46ed076900d..2580179ce5bf3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -561,9 +561,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unify `interior` with `witness` and collect all the resulting obligations. let span = self.tcx.hir().body(body_id).value.span; + let ty::Infer(ty::InferTy::TyVar(_)) = interior.kind() else { + span_bug!(span, "coroutine interior witness not infer: {:?}", interior.kind()) + }; let ok = self .at(&self.misc(span), self.param_env) - .eq(DefineOpaqueTypes::No, interior, witness) + // Will never define opaque types, as all we do is instantiate a type variable. + .eq(DefineOpaqueTypes::Yes, interior, witness) .expect("Failed to unify coroutine interior type"); let mut obligations = ok.obligations; diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs index dd3a36c7bf853..2038d3f84484e 100644 --- a/compiler/rustc_middle/src/util/common.rs +++ b/compiler/rustc_middle/src/util/common.rs @@ -1,8 +1,3 @@ -use rustc_data_structures::sync::Lock; - -use std::fmt::Debug; -use std::time::{Duration, Instant}; - #[cfg(test)] mod tests; @@ -26,46 +21,6 @@ pub fn to_readable_str(mut val: usize) -> String { groups.join("_") } -pub fn record_time(accu: &Lock, f: F) -> T -where - F: FnOnce() -> T, -{ - let start = Instant::now(); - let rv = f(); - let duration = start.elapsed(); - let mut accu = accu.lock(); - *accu += duration; - rv -} - -pub fn indent(op: F) -> R -where - R: Debug, - F: FnOnce() -> R, -{ - // Use in conjunction with the log post-processor like `src/etc/indenter` - // to make debug output more readable. - debug!(">>"); - let r = op(); - debug!("<< (Result = {:?})", r); - r -} - -pub struct Indenter { - _cannot_construct_outside_of_this_module: (), -} - -impl Drop for Indenter { - fn drop(&mut self) { - debug!("<<"); - } -} - -pub fn indenter() -> Indenter { - debug!(">>"); - Indenter { _cannot_construct_outside_of_this_module: () } -} - // const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }` pub const fn c_name(name: &'static str) -> &'static str { // FIXME Simplify the implementation once more `str` methods get const-stable. diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 56ae7ad9f741a..397e104512fd7 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -181,9 +181,9 @@ pub enum TyKind { /// Looking at the following example, the witness for this coroutine /// may end up as something like `for<'a> [Vec, &'a Vec]`: /// - /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?) + /// ``` /// #![feature(coroutines)] - /// |a| { + /// static |a| { /// let x = &vec![3]; /// yield a; /// yield x[0]; diff --git a/config.example.toml b/config.example.toml index 0e8fda9a69c57..0d4b4e9e7e026 100644 --- a/config.example.toml +++ b/config.example.toml @@ -50,7 +50,7 @@ # # Note that many of the LLVM options are not currently supported for # downloading. Currently only the "assertions" option can be toggled. -#download-ci-llvm = if rust.channel == "dev" { "if-unchanged" } else { false } +#download-ci-llvm = if rust.channel == "dev" || rust.download-rustc != false { "if-unchanged" } else { false } # Indicates whether the LLVM build is a Release or Debug build #optimize = true diff --git a/library/backtrace b/library/backtrace index 6fa4b85b9962c..e15130618237e 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 6fa4b85b9962c3e1be8c2e5cc605cd078134152b +Subproject commit e15130618237eb3e2d4b622549f9647b4c1d9ca3 diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 56ea51226f9d5..5f43d63bf8484 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2143,10 +2143,10 @@ impl Path { /// # Examples /// /// ``` - /// use std::path::Path; + /// use std::path::{Path, PathBuf}; /// /// let path_buf = Path::new("foo.txt").to_path_buf(); - /// assert_eq!(path_buf, std::path::PathBuf::from("foo.txt")); + /// assert_eq!(path_buf, PathBuf::from("foo.txt")); /// ``` #[rustc_conversion_suggestion] #[must_use = "this returns the result of the operation, \ @@ -2278,10 +2278,9 @@ impl Path { /// Produces an iterator over `Path` and its ancestors. /// /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero - /// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`, - /// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns - /// [`None`], the iterator will do likewise. The iterator will always yield at least one value, - /// namely `&self`. + /// or more times. If the [`parent`] method returns [`None`], the iterator will do likewise. + /// The iterator will always yield at least one value, namely `Some(&self)`. Next it will yield + /// `&self.parent()`, `&self.parent().and_then(Path::parent)` and so on. /// /// # Examples /// diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 96dec97525048..c84eb8a684f63 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2483,9 +2483,20 @@ impl Config { llvm::is_ci_llvm_available(self, asserts) } }; + match download_ci_llvm { - None => self.channel == "dev" && if_unchanged(), - Some(StringOrBool::Bool(b)) => b, + None => { + (self.channel == "dev" || self.download_rustc_commit.is_some()) && if_unchanged() + } + Some(StringOrBool::Bool(b)) => { + if !b && self.download_rustc_commit.is_some() { + panic!( + "`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`." + ); + } + + b + } // FIXME: "if-available" is deprecated. Remove this block later (around mid 2024) // to not break builds between the recent-to-old checkouts. Some(StringOrBool::String(s)) if s == "if-available" => { diff --git a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile index 09fbbac466c72..5c459e5cd180b 100644 --- a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile @@ -99,6 +99,7 @@ ENV TARGETS=$TARGETS,thumbv8m.base-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabihf ENV TARGETS=$TARGETS,riscv32i-unknown-none-elf +ENV TARGETS=$TARGETS,riscv32im-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imafc-unknown-none-elf @@ -130,6 +131,8 @@ ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft CFLAGS_aarch64_unknown_none=-mstrict-align -march=armv8-a+fp+simd \ CC_riscv32i_unknown_none_elf=riscv32-unknown-elf-gcc \ CFLAGS_riscv32i_unknown_none_elf=-march=rv32i -mabi=ilp32 \ + CC_riscv32im_unknown_none_elf=riscv32-unknown-elf-gcc \ + CFLAGS_riscv32im_unknown_none_elf=-march=rv32im -mabi=ilp32 \ CC_riscv32imc_unknown_none_elf=riscv32-unknown-elf-gcc \ CFLAGS_riscv32imc_unknown_none_elf=-march=rv32imc -mabi=ilp32 \ CC_riscv32imac_unknown_none_elf=riscv32-unknown-elf-gcc \ diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 3f6c484a057d5..04f3b2918b55a 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -454,15 +454,10 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { continue; } // If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a - // `lib.miri.rs` file exists, then build that instead. We only consider relative paths - // as cargo uses those for files in the workspace; dependencies from crates.io get - // absolute paths. + // `lib.miri.rs` file exists, then build that instead. if replace_librs { let path = Path::new(&arg); - if path.is_relative() - && path.file_name().is_some_and(|f| f == "lib.rs") - && path.is_file() - { + if path.file_name().is_some_and(|f| f == "lib.rs") && path.is_file() { let miri_rs = Path::new(&arg).with_extension("miri.rs"); if miri_rs.is_file() { if verbose > 0 { diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 7b7921219e616..2a663d300a736 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -468,6 +468,86 @@ fn unary_op_ps<'tcx>( Ok(()) } +enum ShiftOp { + /// Shift left, logically (shift in zeros) -- same as shift left, arithmetically + Left, + /// Shift right, logically (shift in zeros) + RightLogic, + /// Shift right, arithmetically (shift in sign) + RightArith, +} + +/// Shifts each element of `left` by a scalar amount. The shift amount +/// is determined by the lowest 64 bits of `right` (which is a 128-bit vector). +/// +/// For logic shifts, when right is larger than BITS - 1, zero is produced. +/// For arithmetic right-shifts, when right is larger than BITS - 1, the sign +/// bit is copied to remaining bits. +fn shift_simd_by_scalar<'tcx>( + this: &mut crate::MiriInterpCx<'_, 'tcx>, + left: &OpTy<'tcx, Provenance>, + right: &OpTy<'tcx, Provenance>, + which: ShiftOp, + dest: &MPlaceTy<'tcx, Provenance>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = this.operand_to_simd(left)?; + let (dest, dest_len) = this.mplace_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + // `right` may have a different length, and we only care about its + // lowest 64bit anyway. + + // Get the 64-bit shift operand and convert it to the type expected + // by checked_{shl,shr} (u32). + // It is ok to saturate the value to u32::MAX because any value + // above BITS - 1 will produce the same result. + let shift = u32::try_from(extract_first_u64(this, right)?).unwrap_or(u32::MAX); + + for i in 0..dest_len { + let left = this.read_scalar(&this.project_index(&left, i)?)?; + let dest = this.project_index(&dest, i)?; + + let res = match which { + ShiftOp::Left => { + let left = left.to_uint(dest.layout.size)?; + let res = left.checked_shl(shift).unwrap_or(0); + // `truncate` is needed as left-shift can make the absolute value larger. + Scalar::from_uint(dest.layout.size.truncate(res), dest.layout.size) + } + ShiftOp::RightLogic => { + let left = left.to_uint(dest.layout.size)?; + let res = left.checked_shr(shift).unwrap_or(0); + // No `truncate` needed as right-shift can only make the absolute value smaller. + Scalar::from_uint(res, dest.layout.size) + } + ShiftOp::RightArith => { + let left = left.to_int(dest.layout.size)?; + // On overflow, copy the sign bit to the remaining bits + let res = left.checked_shr(shift).unwrap_or(left >> 127); + // No `truncate` needed as right-shift can only make the absolute value smaller. + Scalar::from_int(res, dest.layout.size) + } + }; + this.write_scalar(res, &dest)?; + } + + Ok(()) +} + +/// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts +/// the first value. +fn extract_first_u64<'tcx>( + this: &crate::MiriInterpCx<'_, 'tcx>, + op: &OpTy<'tcx, Provenance>, +) -> InterpResult<'tcx, u64> { + // Transmute vector to `[u64; 2]` + let array_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u64, 2))?; + let op = op.transmute(array_layout, this)?; + + // Get the first u64 from the array + this.read_scalar(&this.project_index(&op, 0)?)?.to_u64() +} + // Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. fn round_first<'tcx, F: rustc_apfloat::Float>( diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index eb2cc9d37c826..9db30d7ddca21 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,10 +1,11 @@ use rustc_apfloat::ieee::Double; -use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::spec::abi::Abi; -use super::{bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, FloatBinOp}; +use super::{ + bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, shift_simd_by_scalar, + FloatBinOp, ShiftOp, +}; use crate::*; use shims::foreign_items::EmulateForeignItemResult; @@ -109,156 +110,27 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.write_scalar(Scalar::from_u64(res.into()), &dest)?; } } - // Used to implement the _mm_{sll,srl,sra}_epi16 functions. - // Shifts 16-bit packed integers in left by the amount in right. - // Both operands are vectors of 16-bit integers. However, right is - // interpreted as a single 64-bit integer (remaining bits are ignored). - // For logic shifts, when right is larger than 15, zero is produced. - // For arithmetic shifts, when right is larger than 15, the sign bit + // Used to implement the _mm_{sll,srl,sra}_epi{16,32,64} functions + // (except _mm_sra_epi64, which is not available in SSE2). + // Shifts N-bit packed integers in left by the amount in right. + // Both operands are 128-bit vectors. However, right is interpreted as + // a single 64-bit integer (remaining bits are ignored). + // For logic shifts, when right is larger than N - 1, zero is produced. + // For arithmetic shifts, when right is larger than N - 1, the sign bit // is copied to remaining bits. - "psll.w" | "psrl.w" | "psra.w" => { + "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" + | "psrl.q" => { let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.mplace_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - enum ShiftOp { - Sll, - Srl, - Sra, - } let which = match unprefixed_name { - "psll.w" => ShiftOp::Sll, - "psrl.w" => ShiftOp::Srl, - "psra.w" => ShiftOp::Sra, + "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, + "psrl.w" | "psrl.d" | "psrl.q" => ShiftOp::RightLogic, + "psra.w" | "psra.d" => ShiftOp::RightArith, _ => unreachable!(), }; - // Get the 64-bit shift operand and convert it to the type expected - // by checked_{shl,shr} (u32). - // It is ok to saturate the value to u32::MAX because any value - // above 15 will produce the same result. - let shift = extract_first_u64(this, &right)?.try_into().unwrap_or(u32::MAX); - - for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u16()?; - let dest = this.project_index(&dest, i)?; - - let res = match which { - ShiftOp::Sll => left.checked_shl(shift).unwrap_or(0), - ShiftOp::Srl => left.checked_shr(shift).unwrap_or(0), - #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] - ShiftOp::Sra => { - // Convert u16 to i16 to use arithmetic shift - let left = left as i16; - // Copy the sign bit to the remaining bits - left.checked_shr(shift).unwrap_or(left >> 15) as u16 - } - }; - - this.write_scalar(Scalar::from_u16(res), &dest)?; - } - } - // Used to implement the _mm_{sll,srl,sra}_epi32 functions. - // 32-bit equivalent to the shift functions above. - "psll.d" | "psrl.d" | "psra.d" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.mplace_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - enum ShiftOp { - Sll, - Srl, - Sra, - } - let which = match unprefixed_name { - "psll.d" => ShiftOp::Sll, - "psrl.d" => ShiftOp::Srl, - "psra.d" => ShiftOp::Sra, - _ => unreachable!(), - }; - - // Get the 64-bit shift operand and convert it to the type expected - // by checked_{shl,shr} (u32). - // It is ok to saturate the value to u32::MAX because any value - // above 31 will produce the same result. - let shift = extract_first_u64(this, &right)?.try_into().unwrap_or(u32::MAX); - - for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u32()?; - let dest = this.project_index(&dest, i)?; - - let res = match which { - ShiftOp::Sll => left.checked_shl(shift).unwrap_or(0), - ShiftOp::Srl => left.checked_shr(shift).unwrap_or(0), - #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] - ShiftOp::Sra => { - // Convert u32 to i32 to use arithmetic shift - let left = left as i32; - // Copy the sign bit to the remaining bits - left.checked_shr(shift).unwrap_or(left >> 31) as u32 - } - }; - - this.write_scalar(Scalar::from_u32(res), &dest)?; - } - } - // Used to implement the _mm_{sll,srl}_epi64 functions. - // 64-bit equivalent to the shift functions above, except _mm_sra_epi64, - // which is not available in SSE2. - "psll.q" | "psrl.q" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.mplace_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - enum ShiftOp { - Sll, - Srl, - } - let which = match unprefixed_name { - "psll.q" => ShiftOp::Sll, - "psrl.q" => ShiftOp::Srl, - _ => unreachable!(), - }; - - // Get the 64-bit shift operand and convert it to the type expected - // by checked_{shl,shr} (u32). - // It is ok to saturate the value to u32::MAX because any value - // above 63 will produce the same result. - let shift = this - .read_scalar(&this.project_index(&right, 0)?)? - .to_u64()? - .try_into() - .unwrap_or(u32::MAX); - - for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u64()?; - let dest = this.project_index(&dest, i)?; - - let res = match which { - ShiftOp::Sll => left.checked_shl(shift).unwrap_or(0), - ShiftOp::Srl => left.checked_shr(shift).unwrap_or(0), - }; - - this.write_scalar(Scalar::from_u64(res), &dest)?; - } + shift_simd_by_scalar(this, left, right, which, dest)?; } // Used to implement the _mm_cvtps_epi32, _mm_cvttps_epi32, _mm_cvtpd_epi32 // and _mm_cvttpd_epi32 functions. @@ -585,17 +457,3 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: Ok(EmulateForeignItemResult::NeedsJumping) } } - -/// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts -/// the first value. -fn extract_first_u64<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, - op: &MPlaceTy<'tcx, Provenance>, -) -> InterpResult<'tcx, u64> { - // Transmute vector to `[u64; 2]` - let u64_array_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u64, 2))?; - let op = op.transmute(u64_array_layout, this)?; - - // Get the first u64 from the array - this.read_scalar(&this.project_index(&op, 0)?)?.to_u64() -}