diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index bf4152d4b8cd5..64467a9013696 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -518,6 +518,103 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + sym::floorf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + + sym::ceilf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + + sym::truncf16 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf32 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf64 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf128 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + + sym::roundf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + + sym::round_ties_even_f16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), } @@ -900,4 +997,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(x.abs(), dest)?; interp_ok(()) } + + fn float_round_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + mode: rustc_apfloat::Round, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = self.read_scalar(&args[0])?.to_float()?; + let res = x.round_to_integral(mode).value; + let res = self.adjust_nan(res, &[x]); + self.write_scalar(res, dest)?; + interp_ok(()) + } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 056c476d5e120..54a331a490444 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -12,7 +12,6 @@ #![feature(decl_macro)] #![feature(panic_backtrace_config)] #![feature(panic_update_hook)] -#![feature(result_flattening)] #![feature(rustdoc_internals)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 43b662ca453d1..1c3bc338d85b2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2713,6 +2713,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } + // Don't try to suggest ref/deref on an `if` expression, because: + // - The `if` could be part of a desugared `if else` statement, + // which would create impossible suggestions such as `if ... { ... } else &if { ... } else { ... }`. + // - In general the suggestions it creates such as `&if ... { ... } else { ... }` are not very helpful. + // We try to generate a suggestion such as `if ... { &... } else { &... }` instead. + if let hir::ExprKind::If(_c, then, els) = expr.kind { + // The `then` of a `Expr::If` always contains a block, and that block may have a final expression that we can borrow + // If the block does not have a final expression, it will return () and we do not make a suggestion to borrow that. + let ExprKind::Block(then, _) = then.kind else { return None }; + let Some(then) = then.expr else { return None }; + let (mut suggs, help, app, verbose, mutref) = + self.suggest_deref_or_ref(then, checked_ty, expected)?; + + // If there is no `else`, the return type of this `if` will be (), so suggesting to change the `then` block is useless + let els_expr = match els?.kind { + ExprKind::Block(block, _) => block.expr?, + _ => els?, + }; + let (else_suggs, ..) = + self.suggest_deref_or_ref(els_expr, checked_ty, expected)?; + suggs.extend(else_suggs); + + return Some((suggs, help, app, verbose, mutref)); + } + if let Some((sugg, msg)) = self.can_use_as_ref(expr) { return Some(( sugg, diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index c237ac84cf407..2c0662c96290a 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -38,7 +38,16 @@ mod uninit; -/// A common trait for the ability to explicitly duplicate an object. +/// A common trait that allows explicit creation of a duplicate value. +/// +/// Calling [`clone`] always produces a new value. +/// However, for types that are references to other data (such as smart pointers or references), +/// the new value may still point to the same underlying data, rather than duplicating it. +/// See [`Clone::clone`] for more details. +/// +/// This distinction is especially important when using `#[derive(Clone)]` on structs containing +/// smart pointers like `Arc>` - the cloned struct will share mutable state with the +/// original. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while /// `Clone` is always explicit and may or may not be expensive. In order to enforce @@ -147,7 +156,16 @@ mod uninit; #[rustc_diagnostic_item = "Clone"] #[rustc_trivial_field_reads] pub trait Clone: Sized { - /// Returns a copy of the value. + /// Returns a duplicate of the value. + /// + /// Note that what "duplicate" means varies by type: + /// - For most types, this creates a deep, independent copy + /// - For reference types like `&T`, this creates another reference to the same value + /// - For smart pointers like [`Arc`] or [`Rc`], this increments the reference count + /// but still points to the same underlying data + /// + /// [`Arc`]: ../../std/sync/struct.Arc.html + /// [`Rc`]: ../../std/rc/struct.Rc.html /// /// # Examples /// @@ -157,6 +175,23 @@ pub trait Clone: Sized { /// /// assert_eq!("Hello", hello.clone()); /// ``` + /// + /// Example with a reference-counted type: + /// + /// ``` + /// use std::sync::{Arc, Mutex}; + /// + /// let data = Arc::new(Mutex::new(vec![1, 2, 3])); + /// let data_clone = data.clone(); // Creates another Arc pointing to the same Mutex + /// + /// { + /// let mut lock = data.lock().unwrap(); + /// lock.push(4); + /// } + /// + /// // Changes are visible through the clone because they share the same underlying data + /// assert_eq!(*data_clone.lock().unwrap(), vec![1, 2, 3, 4]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "cloning is often expensive and is not expected to have side effects"] // Clone::clone is special because the compiler generates MIR to implement it for some types. diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index f89baef76f093..bb3e870389c70 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2212,28 +2212,28 @@ pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// [`f16::floor`](../../std/primitive.f16.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf16(x: f16) -> f16; +pub const unsafe fn floorf16(x: f16) -> f16; /// Returns the largest integer less than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::floor`](../../std/primitive.f32.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf32(x: f32) -> f32; +pub const unsafe fn floorf32(x: f32) -> f32; /// Returns the largest integer less than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::floor`](../../std/primitive.f64.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf64(x: f64) -> f64; +pub const unsafe fn floorf64(x: f64) -> f64; /// Returns the largest integer less than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::floor`](../../std/primitive.f128.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf128(x: f128) -> f128; +pub const unsafe fn floorf128(x: f128) -> f128; /// Returns the smallest integer greater than or equal to an `f16`. /// @@ -2241,28 +2241,28 @@ pub unsafe fn floorf128(x: f128) -> f128; /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf16(x: f16) -> f16; +pub const unsafe fn ceilf16(x: f16) -> f16; /// Returns the smallest integer greater than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf32(x: f32) -> f32; +pub const unsafe fn ceilf32(x: f32) -> f32; /// Returns the smallest integer greater than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf64(x: f64) -> f64; +pub const unsafe fn ceilf64(x: f64) -> f64; /// Returns the smallest integer greater than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf128(x: f128) -> f128; +pub const unsafe fn ceilf128(x: f128) -> f128; /// Returns the integer part of an `f16`. /// @@ -2270,28 +2270,28 @@ pub unsafe fn ceilf128(x: f128) -> f128; /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf16(x: f16) -> f16; +pub const unsafe fn truncf16(x: f16) -> f16; /// Returns the integer part of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf32(x: f32) -> f32; +pub const unsafe fn truncf32(x: f32) -> f32; /// Returns the integer part of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf64(x: f64) -> f64; +pub const unsafe fn truncf64(x: f64) -> f64; /// Returns the integer part of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf128(x: f128) -> f128; +pub const unsafe fn truncf128(x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2300,7 +2300,7 @@ pub unsafe fn truncf128(x: f128) -> f128; /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f16(x: f16) -> f16; +pub const fn round_ties_even_f16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2309,7 +2309,7 @@ pub fn round_ties_even_f16(x: f16) -> f16; /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f32(x: f32) -> f32; +pub const fn round_ties_even_f32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2318,7 +2318,7 @@ pub fn round_ties_even_f32(x: f32) -> f32; /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f64(x: f64) -> f64; +pub const fn round_ties_even_f64(x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2327,7 +2327,7 @@ pub fn round_ties_even_f64(x: f64) -> f64; /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f128(x: f128) -> f128; +pub const fn round_ties_even_f128(x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. /// @@ -2335,28 +2335,28 @@ pub fn round_ties_even_f128(x: f128) -> f128; /// [`f16::round`](../../std/primitive.f16.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf16(x: f16) -> f16; +pub const unsafe fn roundf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f32::round`](../../std/primitive.f32.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf32(x: f32) -> f32; +pub const unsafe fn roundf32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f64::round`](../../std/primitive.f64.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf64(x: f64) -> f64; +pub const unsafe fn roundf64(x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f128::round`](../../std/primitive.f128.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf128(x: f128) -> f128; +pub const unsafe fn roundf128(x: f128) -> f128; /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 0c2c4155d66ce..6b9b2ba868911 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1447,8 +1447,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(self) -> f128 { + pub const fn floor(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf128(self) } } @@ -1477,8 +1479,10 @@ impl f128 { #[doc(alias = "ceiling")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(self) -> f128 { + pub const fn ceil(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf128(self) } } @@ -1513,8 +1517,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(self) -> f128 { + pub const fn round(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf128(self) } } @@ -1547,8 +1553,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(self) -> f128 { + pub const fn round_ties_even(self) -> f128 { intrinsics::round_ties_even_f128(self) } @@ -1579,8 +1587,10 @@ impl f128 { #[doc(alias = "truncate")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(self) -> f128 { + pub const fn trunc(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf128(self) } } @@ -1610,8 +1620,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(self) -> f128 { + pub const fn fract(self) -> f128 { self - self.trunc() } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 1a859f2277ff3..eb7af993c60a0 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1423,8 +1423,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(self) -> f16 { + pub const fn floor(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf16(self) } } @@ -1453,8 +1455,10 @@ impl f16 { #[doc(alias = "ceiling")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(self) -> f16 { + pub const fn ceil(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf16(self) } } @@ -1489,8 +1493,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(self) -> f16 { + pub const fn round(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf16(self) } } @@ -1523,8 +1529,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(self) -> f16 { + pub const fn round_ties_even(self) -> f16 { intrinsics::round_ties_even_f16(self) } @@ -1555,8 +1563,10 @@ impl f16 { #[doc(alias = "truncate")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(self) -> f16 { + pub const fn trunc(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf16(self) } } @@ -1586,8 +1596,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(self) -> f16 { + pub const fn fract(self) -> f16 { self - self.trunc() } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 6636054a659b5..bf923d4070ad7 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1591,8 +1591,9 @@ pub mod math { /// [`f32::floor`]: ../../../std/primitive.f32.html#method.floor #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(x: f32) -> f32 { + pub const fn floor(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf32(x) } } @@ -1621,7 +1622,8 @@ pub mod math { #[doc(alias = "ceiling")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - pub fn ceil(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn ceil(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf32(x) } } @@ -1655,7 +1657,8 @@ pub mod math { #[inline] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn round(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf32(x) } } @@ -1688,7 +1691,8 @@ pub mod math { #[inline] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn round_ties_even(x: f32) -> f32 { intrinsics::round_ties_even_f32(x) } @@ -1718,7 +1722,8 @@ pub mod math { #[doc(alias = "truncate")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - pub fn trunc(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn trunc(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf32(x) } } @@ -1747,8 +1752,9 @@ pub mod math { /// [`f32::fract`]: ../../../std/primitive.f32.html#method.fract #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(x: f32) -> f32 { + pub const fn fract(x: f32) -> f32 { x - trunc(x) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 8fbf2cffbaf4e..0a63ed828aedf 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1589,8 +1589,9 @@ pub mod math { /// [`f64::floor`]: ../../../std/primitive.f64.html#method.floor #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(x: f64) -> f64 { + pub const fn floor(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf64(x) } } @@ -1618,8 +1619,9 @@ pub mod math { #[inline] #[doc(alias = "ceiling")] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(x: f64) -> f64 { + pub const fn ceil(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf64(x) } } @@ -1652,8 +1654,9 @@ pub mod math { /// [`f64::round`]: ../../../std/primitive.f64.html#method.round #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(x: f64) -> f64 { + pub const fn round(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf64(x) } } @@ -1685,8 +1688,9 @@ pub mod math { /// [`f64::round_ties_even`]: ../../../std/primitive.f64.html#method.round_ties_even #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(x: f64) -> f64 { + pub const fn round_ties_even(x: f64) -> f64 { intrinsics::round_ties_even_f64(x) } @@ -1715,8 +1719,9 @@ pub mod math { #[inline] #[doc(alias = "truncate")] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(x: f64) -> f64 { + pub const fn trunc(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf64(x) } } @@ -1745,8 +1750,9 @@ pub mod math { /// [`f64::fract`]: ../../../std/primitive.f64.html#method.fract #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(x: f64) -> f64 { + pub const fn fract(x: f64) -> f64 { x - trunc(x) } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index ef2da5e8fbf41..23e32c2e0f01d 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1722,7 +1722,6 @@ impl Result, E> { /// # Examples /// /// ``` - /// #![feature(result_flattening)] /// let x: Result, u32> = Ok(Ok("hello")); /// assert_eq!(Ok("hello"), x.flatten()); /// @@ -1736,14 +1735,14 @@ impl Result, E> { /// Flattening only removes one level of nesting at a time: /// /// ``` - /// #![feature(result_flattening)] /// let x: Result, u32>, u32> = Ok(Ok(Ok("hello"))); /// assert_eq!(Ok(Ok("hello")), x.flatten()); /// assert_eq!(Ok("hello"), x.flatten().flatten()); /// ``` #[inline] - #[unstable(feature = "result_flattening", issue = "70142")] - #[rustc_const_unstable(feature = "result_flattening", issue = "70142")] + #[stable(feature = "result_flattening", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_precise_live_drops)] + #[rustc_const_stable(feature = "result_flattening", since = "CURRENT_RUSTC_VERSION")] pub const fn flatten(self) -> Result { // FIXME(const-hack): could be written with `and_then` match self { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 693b14ef76209..dd7cdd79c0d60 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -16,6 +16,7 @@ #![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(const_eval_select)] +#![feature(const_float_round_methods)] #![feature(const_trait_impl)] #![feature(core_float_math)] #![feature(core_intrinsics)] diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index 1212d36a1b15c..fa05bbdd9b774 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -731,6 +731,9 @@ assume_usize_width! { } } +// FIXME(141726): there is a lot of duplication between the following tests and +// the tests in `coretests/tests/floats/f*.rs` +// See issue https://github.com/rust-lang/rust/issues/141726 for more details. macro_rules! test_float { ($modname: ident, $fassert: ident, $fty: ty) => { mod $modname { @@ -947,6 +950,117 @@ macro_rules! test_float { assert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan()); assert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan()); } + #[test] + #[cfg(not(bootstrap))] + fn floor() { + $fassert!((0.0 as $fty).floor(), 0.0); + $fassert!((0.0 as $fty).floor().is_sign_positive()); + $fassert!((-0.0 as $fty).floor(), -0.0); + $fassert!((-0.0 as $fty).floor().is_sign_negative()); + $fassert!((0.5 as $fty).floor(), 0.0); + $fassert!((-0.5 as $fty).floor(), -1.0); + $fassert!((1.5 as $fty).floor(), 1.0); + $fassert!(<$fty>::MAX.floor(), <$fty>::MAX); + $fassert!(<$fty>::MIN.floor(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.floor(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).floor(), -1.0); + $fassert!(<$fty>::NAN.floor().is_nan()); + $fassert!(<$fty>::INFINITY.floor(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.floor(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn ceil() { + $fassert!((0.0 as $fty).ceil(), 0.0); + $fassert!((0.0 as $fty).ceil().is_sign_positive()); + $fassert!((-0.0 as $fty).ceil(), 0.0); + $fassert!((-0.0 as $fty).ceil().is_sign_negative()); + $fassert!((0.5 as $fty).ceil(), 1.0); + $fassert!((-0.5 as $fty).ceil(), 0.0); + $fassert!(<$fty>::MAX.ceil(), <$fty>::MAX); + $fassert!(<$fty>::MIN.ceil(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.ceil(), 1.0); + $fassert!((-<$fty>::MIN_POSITIVE).ceil(), 0.0); + $fassert!(<$fty>::NAN.ceil().is_nan()); + $fassert!(<$fty>::INFINITY.ceil(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.ceil(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round() { + $fassert!((0.0 as $fty).round(), 0.0); + $fassert!((0.0 as $fty).round().is_sign_positive()); + $fassert!((-0.0 as $fty).round(), -0.0); + $fassert!((-0.0 as $fty).round().is_sign_negative()); + $fassert!((0.5 as $fty).round(), 1.0); + $fassert!((-0.5 as $fty).round(), -1.0); + $fassert!(<$fty>::MAX.round(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round(), 0.0); + $fassert!(<$fty>::NAN.round().is_nan()); + $fassert!(<$fty>::INFINITY.round(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round_ties_even() { + $fassert!((0.0 as $fty).round_ties_even(), 0.0); + $fassert!((0.0 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.0 as $fty).round_ties_even(), -0.0); + $fassert!((-0.0 as $fty).round_ties_even().is_sign_negative()); + $fassert!((0.5 as $fty).round_ties_even(), 0.0); + $fassert!((0.5 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.5 as $fty).round_ties_even(), -0.0); + $fassert!((-0.5 as $fty).round_ties_even().is_sign_negative()); + $fassert!(<$fty>::MAX.round_ties_even(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round_ties_even(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round_ties_even(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round_ties_even(), 0.0); + $fassert!(<$fty>::NAN.round_ties_even().is_nan()); + $fassert!(<$fty>::INFINITY.round_ties_even(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round_ties_even(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn trunc() { + $fassert!((0.0 as $fty).trunc(), 0.0); + $fassert!((0.0 as $fty).trunc().is_sign_positive()); + $fassert!((-0.0 as $fty).trunc(), -0.0); + $fassert!((-0.0 as $fty).trunc().is_sign_negative()); + $fassert!((0.5 as $fty).trunc(), 0.0); + $fassert!((0.5 as $fty).trunc().is_sign_positive()); + $fassert!((-0.5 as $fty).trunc(), -0.0); + $fassert!((-0.5 as $fty).trunc().is_sign_negative()); + $fassert!(<$fty>::MAX.trunc(), <$fty>::MAX); + $fassert!(<$fty>::MIN.trunc(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.trunc(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).trunc(), 0.0); + $fassert!(<$fty>::NAN.trunc().is_nan()); + $fassert!(<$fty>::INFINITY.trunc(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.trunc(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn fract() { + $fassert!((0.0 as $fty).fract(), 0.0); + $fassert!((0.0 as $fty).fract().is_sign_positive()); + $fassert!((-0.0 as $fty).fract(), 0.0); + $fassert!((-0.0 as $fty).fract().is_sign_positive()); + $fassert!((0.5 as $fty).fract(), 0.5); + $fassert!((0.5 as $fty).fract().is_sign_positive()); + $fassert!((-0.5 as $fty).fract(), -0.5); + $fassert!((-0.5 as $fty).fract().is_sign_negative()); + $fassert!(<$fty>::MAX.fract(), 0.0); + $fassert!(<$fty>::MIN.fract(), 0.0); + $fassert!(<$fty>::MIN_POSITIVE.fract(), <$fty>::MIN_POSITIVE); + $fassert!(<$fty>::MIN_POSITIVE.fract().is_sign_positive()); + $fassert!((-<$fty>::MIN_POSITIVE).fract(), -<$fty>::MIN_POSITIVE); + $fassert!((-<$fty>::MIN_POSITIVE).fract().is_sign_negative()); + $fassert!(<$fty>::NAN.fract().is_nan()); + $fassert!(<$fty>::INFINITY.fract().is_nan()); + $fassert!(<$fty>::NEG_INFINITY.fract().is_nan()); + } } }; } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8ed5800e9d06b..711efc7d011c1 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2915,17 +2915,28 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// # Platform-specific behavior /// -/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions -/// on Unix (except for REDOX) and the `CreateFileW`, `GetFileInformationByHandleEx`, -/// `SetFileInformationByHandle`, and `NtCreateFile` functions on Windows. Note that, this -/// [may change in the future][changes]. +/// These implementation details [may change in the future][changes]. +/// +/// - "Unix-like": By default, this function currently corresponds to +/// `openat`, `fdopendir`, `unlinkat` and `lstat` +/// on Unix-family platforms, except where noted otherwise. +/// - "Windows": This function currently corresponds to `CreateFileW`, +/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile`. +/// +/// ## Time-of-check to time-of-use (TOCTOU) race conditions +/// On a few platforms there is no way to remove a directory's contents without following symlinks +/// unless you perform a check and then operate on paths based on that directory. +/// This allows concurrently-running code to replace the directory with a symlink after the check, +/// causing a removal to instead operate on a path based on the symlink. This is a TOCTOU race. +/// By default, `fs::remove_dir_all` protects against a symlink TOCTOU race on all platforms +/// except the following. It should not be used in security-sensitive contexts on these platforms: +/// - Miri: Even when emulating targets where the underlying implementation will protect against +/// TOCTOU races, Miri will not do so. +/// - Redox OS: This function does not protect against TOCTOU races, as Redox does not implement +/// the required platform support to do so. /// /// [changes]: io#platform-specific-behavior /// -/// On REDOX, as well as when running in Miri for any target, this function is not protected against -/// time-of-check to time-of-use (TOCTOU) race conditions, and should not be used in -/// security-sensitive code on those platforms. All other platforms are protected. -/// /// # Errors /// /// See [`fs::remove_file`] and [`fs::remove_dir`]. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index a3f0f3cc55a19..74a3433986020 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -335,6 +335,7 @@ #![feature(bstr_internals)] #![feature(char_internals)] #![feature(clone_to_uninit)] +#![feature(const_float_round_methods)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(duration_constants)] diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index 5210e75ec4531..b7f6529ac4027 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -44,8 +44,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn floor(self) -> f32 { + pub const fn floor(self) -> f32 { core::f32::math::floor(self) } @@ -66,8 +67,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn ceil(self) -> f32 { + pub const fn ceil(self) -> f32 { core::f32::math::ceil(self) } @@ -94,8 +96,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round(self) -> f32 { + pub const fn round(self) -> f32 { core::f32::math::round(self) } @@ -120,8 +123,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "round_ties_even", since = "1.77.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round_ties_even(self) -> f32 { + pub const fn round_ties_even(self) -> f32 { core::f32::math::round_ties_even(self) } @@ -145,8 +149,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn trunc(self) -> f32 { + pub const fn trunc(self) -> f32 { core::f32::math::trunc(self) } @@ -168,8 +173,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn fract(self) -> f32 { + pub const fn fract(self) -> f32 { core::f32::math::fract(self) } diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index f837800d66342..75e35a8db3354 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -44,8 +44,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn floor(self) -> f64 { + pub const fn floor(self) -> f64 { core::f64::math::floor(self) } @@ -66,8 +67,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn ceil(self) -> f64 { + pub const fn ceil(self) -> f64 { core::f64::math::ceil(self) } @@ -94,8 +96,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round(self) -> f64 { + pub const fn round(self) -> f64 { core::f64::math::round(self) } @@ -120,8 +123,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "round_ties_even", since = "1.77.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round_ties_even(self) -> f64 { + pub const fn round_ties_even(self) -> f64 { core::f64::math::round_ties_even(self) } @@ -145,8 +149,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn trunc(self) -> f64 { + pub const fn trunc(self) -> f64 { core::f64::math::trunc(self) } @@ -168,8 +173,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn fract(self) -> f64 { + pub const fn fract(self) -> f64 { core::f64::math::fract(self) } diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh index 9222710b84376..62e0451814b35 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh @@ -53,8 +53,8 @@ MIRIFLAGS="-Zmiri-force-intrinsic-fallback --cfg force_intrinsic_fallback -O -Zm case $HOST_TARGET in x86_64-unknown-linux-gnu) # Only this branch runs in PR CI. - # Fully test all main OSes, including a 32bit target. - python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target x86_64-apple-darwin + # Fully test all main OSes, and all main architectures. + python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target aarch64-apple-darwin python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target i686-pc-windows-msvc # Only run "pass" tests for the remaining targets, which is quite a bit faster. python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass @@ -69,7 +69,7 @@ case $HOST_TARGET in #FIXME: Re-enable this once CI issues are fixed # See # For now, these tests are moved to `x86_64-msvc-ext2` in `src/ci/github-actions/jobs.yml`. - #python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass + #python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass ;; *) echo "FATAL: unexpected host $HOST_TARGET" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index dc6a0e1ebad86..9eedbd451d86d 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -530,11 +530,13 @@ auto: - name: x86_64-msvc-ext2 env: SCRIPT: > - python x.py test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass && + python x.py test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass && python x.py test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass && python x.py miri --stage 2 library/core --test-args notest && python x.py miri --stage 2 library/alloc --test-args notest && python x.py miri --stage 2 library/std --test-args notest + # The last 3 lines smoke-test `x.py miri`. This doesn't run any actual tests (that would take + # too long), but it ensures that the crates build properly when tested with Miri. RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld <<: *job-windows diff --git a/src/tools/clippy/tests/ui/map_flatten.rs b/src/tools/clippy/tests/ui/map_flatten.rs index d7e9c9d9900d9..0970da8039a48 100644 --- a/src/tools/clippy/tests/ui/map_flatten.rs +++ b/src/tools/clippy/tests/ui/map_flatten.rs @@ -1,5 +1,5 @@ #![warn(clippy::map_flatten)] -#![feature(result_flattening)] + //@no-rustfix // issue #8506, multi-line #[rustfmt::skip] diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed index f8379ed23c5b2..6d8a27d3018dd 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed @@ -1,4 +1,3 @@ -#![feature(result_flattening)] #![allow( clippy::let_underscore_untyped, clippy::missing_docs_in_private_items, diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs index 040a9ca85f647..845e3a79ae2b0 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs @@ -1,4 +1,3 @@ -#![feature(result_flattening)] #![allow( clippy::let_underscore_untyped, clippy::missing_docs_in_private_items, diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr index fe68eb7e4ab44..05d4d9a6ad85c 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr @@ -1,5 +1,5 @@ error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:17:47 + --> tests/ui/map_flatten_fixable.rs:16:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)` @@ -8,43 +8,43 @@ LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().coll = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:19:47 + --> tests/ui/map_flatten_fixable.rs:18:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:21:47 + --> tests/ui/map_flatten_fixable.rs:20:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:23:47 + --> tests/ui/map_flatten_fixable.rs:22:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:27:47 + --> tests/ui/map_flatten_fixable.rs:26:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)` error: called `map(..).flatten()` on `Option` - --> tests/ui/map_flatten_fixable.rs:31:40 + --> tests/ui/map_flatten_fixable.rs:30:40 | LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Result` - --> tests/ui/map_flatten_fixable.rs:35:42 + --> tests/ui/map_flatten_fixable.rs:34:42 | LL | let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:45:10 + --> tests/ui/map_flatten_fixable.rs:44:10 | LL | .map(|n| match n { | __________^ @@ -74,7 +74,7 @@ LL ~ }); | error: called `map(..).flatten()` on `Option` - --> tests/ui/map_flatten_fixable.rs:66:10 + --> tests/ui/map_flatten_fixable.rs:65:10 | LL | .map(|_| { | __________^ diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 581005bc9a1ed..a4882a201481c 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -159,67 +159,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f16()?; - let mode = match intrinsic_name { - "floorf16" => Round::TowardNegative, - "ceilf16" => Round::TowardPositive, - "truncf16" => Round::TowardZero, - "roundf16" => Round::NearestTiesToAway, - "round_ties_even_f16" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f32()?; - let mode = match intrinsic_name { - "floorf32" => Round::TowardNegative, - "ceilf32" => Round::TowardPositive, - "truncf32" => Round::TowardZero, - "roundf32" => Round::NearestTiesToAway, - "round_ties_even_f32" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f64()?; - let mode = match intrinsic_name { - "floorf64" => Round::TowardNegative, - "ceilf64" => Round::TowardPositive, - "truncf64" => Round::TowardZero, - "roundf64" => Round::NearestTiesToAway, - "round_ties_even_f64" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f128()?; - let mode = match intrinsic_name { - "floorf128" => Round::TowardNegative, - "ceilf128" => Round::TowardPositive, - "truncf128" => Round::TowardZero, - "roundf128" => Round::NearestTiesToAway, - "round_ties_even_f128" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "sqrtf32" => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; diff --git a/tests/ui/typeck/consider-borrowing-141810-1.rs b/tests/ui/typeck/consider-borrowing-141810-1.rs new file mode 100644 index 0000000000000..94c2d69091517 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-1.rs @@ -0,0 +1,9 @@ +fn main() { + let x = if true { + &true + } else if false { //~ ERROR `if` and `else` have incompatible types [E0308] + true //~ HELP consider borrowing here + } else { + true + }; +} diff --git a/tests/ui/typeck/consider-borrowing-141810-1.stderr b/tests/ui/typeck/consider-borrowing-141810-1.stderr new file mode 100644 index 0000000000000..9291721ac7123 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-1.stderr @@ -0,0 +1,28 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/consider-borrowing-141810-1.rs:4:12 + | +LL | let x = if true { + | ______________- +LL | | &true + | | ----- expected because of this +LL | | } else if false { + | | ____________^ +LL | || true +LL | || } else { +LL | || true +LL | || }; + | || ^ + | ||_____| + | |_____`if` and `else` have incompatible types + | expected `&bool`, found `bool` + | +help: consider borrowing here + | +LL ~ &true +LL | } else { +LL ~ &true + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/consider-borrowing-141810-2.rs b/tests/ui/typeck/consider-borrowing-141810-2.rs new file mode 100644 index 0000000000000..e32e689efb7e5 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-2.rs @@ -0,0 +1,8 @@ +fn main() { + let x = if true { + &() + } else if false { //~ ERROR `if` and `else` have incompatible types [E0308] + } else { + }; + +} diff --git a/tests/ui/typeck/consider-borrowing-141810-2.stderr b/tests/ui/typeck/consider-borrowing-141810-2.stderr new file mode 100644 index 0000000000000..dd229897283b4 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-2.stderr @@ -0,0 +1,19 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/consider-borrowing-141810-2.rs:4:12 + | +LL | let x = if true { + | ______________- +LL | | &() + | | --- expected because of this +LL | | } else if false { + | | ____________^ +LL | || } else { +LL | || }; + | || ^ + | ||_____| + | |_____`if` and `else` have incompatible types + | expected `&()`, found `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/consider-borrowing-141810-3.rs b/tests/ui/typeck/consider-borrowing-141810-3.rs new file mode 100644 index 0000000000000..d38828de7c172 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-3.rs @@ -0,0 +1,7 @@ +fn main() { + let x = if true { + &() + } else if false { //~ ERROR `if` and `else` have incompatible types [E0308] + + }; +} diff --git a/tests/ui/typeck/consider-borrowing-141810-3.stderr b/tests/ui/typeck/consider-borrowing-141810-3.stderr new file mode 100644 index 0000000000000..0b0c5f191a0d3 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-3.stderr @@ -0,0 +1,22 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/consider-borrowing-141810-3.rs:4:12 + | +LL | let x = if true { + | ______________- +LL | | &() + | | --- expected because of this +LL | | } else if false { + | | ____________^ +LL | || +LL | || }; + | || ^ + | ||_____| + | |_____`if` and `else` have incompatible types + | expected `&()`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = note: consider adding an `else` block that evaluates to the expected type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/consider-borrowing-141810-4.rs b/tests/ui/typeck/consider-borrowing-141810-4.rs new file mode 100644 index 0000000000000..754af7920a855 --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-4.rs @@ -0,0 +1,11 @@ +fn baz(x: &String) {} + +fn bar() { + baz({ + String::from("hi") //~ ERROR mismatched types + }); +} + +fn main() { + bar(); +} diff --git a/tests/ui/typeck/consider-borrowing-141810-4.stderr b/tests/ui/typeck/consider-borrowing-141810-4.stderr new file mode 100644 index 0000000000000..80869d4a5d5cf --- /dev/null +++ b/tests/ui/typeck/consider-borrowing-141810-4.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/consider-borrowing-141810-4.rs:5:9 + | +LL | String::from("hi") + | ^^^^^^^^^^^^^^^^^^ expected `&String`, found `String` + | +help: consider borrowing here + | +LL | &String::from("hi") + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.