Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit dae7ac1

Browse files
committedNov 14, 2024
Auto merge of #133026 - workingjubilee:rollup-q8ig6ah, r=workingjubilee
Rollup of 7 pull requests Successful merges: - #131304 (float types: move copysign, abs, signum to libcore) - #132907 (Change intrinsic declarations to new style) - #132971 (Handle infer vars in anon consts on stable) - #133003 (Make `CloneToUninit` dyn-compatible) - #133004 (btree: simplify the backdoor between set and map) - #133008 (update outdated comment about test-float-parse) - #133012 (Add test cases for #125918) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 22bcb81 + 18136cf commit dae7ac1

File tree

33 files changed

+1910
-1321
lines changed

33 files changed

+1910
-1321
lines changed
 

‎compiler/rustc_middle/src/mir/consts.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ impl<'tcx> Const<'tcx> {
325325

326326
match c.kind() {
327327
ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
328+
ConstKind::Expr(_) => {
329+
bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
330+
}
328331
_ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()),
329332
}
330333
}

‎compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -578,16 +578,28 @@ pub fn try_evaluate_const<'tcx>(
578578
(args, param_env)
579579
}
580580
}
581-
} else {
582-
// FIXME: We don't check anything on stable as the only way we can wind up with
583-
// an unevaluated constant containing generic parameters is through array repeat
584-
// expression counts which have a future compat lint for usage of generic parameters
585-
// instead of a hard error.
581+
} else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
582+
// FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
583+
//
584+
// Diagnostics will sometimes replace the identity args of anon consts in
585+
// array repeat expr counts with inference variables so we have to handle this
586+
// even though it is not something we should ever actually encounter.
586587
//
587-
// This codepath is however also reachable by `generic_const_exprs` and some other
588-
// feature gates which allow constants in the type system to use generic parameters.
589-
// In theory we should be checking for generic parameters here and returning an error
590-
// in such cases.
588+
// Array repeat expr counts are allowed to syntactically use generic parameters
589+
// but must not actually depend on them in order to evalaute succesfully. This means
590+
// that it is actually fine to evalaute them in their own environment rather than with
591+
// the actually provided generic arguments.
592+
tcx.dcx().delayed_bug(
593+
"Encountered anon const with inference variable args but no error reported",
594+
);
595+
596+
let args = GenericArgs::identity_for_item(tcx, uv.def);
597+
let param_env = tcx.param_env(uv.def);
598+
(args, param_env)
599+
} else {
600+
// FIXME: This codepath is reachable under `associated_const_equality` and in the
601+
// future will be reachable by `min_generic_const_args`. We should handle inference
602+
// variables and generic parameters properly instead of doing nothing.
591603
(uv.args, param_env)
592604
};
593605
let uv = ty::UnevaluatedConst::new(uv.def, args);

‎library/alloc/src/boxed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
17351735
// Pre-allocate memory to allow writing the cloned value directly.
17361736
let mut boxed = Self::new_uninit_in(self.1.clone());
17371737
unsafe {
1738-
(**self).clone_to_uninit(boxed.as_mut_ptr());
1738+
(**self).clone_to_uninit(boxed.as_mut_ptr().cast());
17391739
boxed.assume_init()
17401740
}
17411741
}

‎library/alloc/src/collections/btree/map.rs

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -289,40 +289,12 @@ impl<K: Clone, V: Clone, A: Allocator + Clone> Clone for BTreeMap<K, V, A> {
289289
}
290290
}
291291

292-
impl<K, Q: ?Sized, A: Allocator + Clone> super::Recover<Q> for BTreeMap<K, SetValZST, A>
293-
where
294-
K: Borrow<Q> + Ord,
295-
Q: Ord,
296-
{
297-
type Key = K;
298-
299-
fn get(&self, key: &Q) -> Option<&K> {
300-
let root_node = self.root.as_ref()?.reborrow();
301-
match root_node.search_tree(key) {
302-
Found(handle) => Some(handle.into_kv().0),
303-
GoDown(_) => None,
304-
}
305-
}
306-
307-
fn take(&mut self, key: &Q) -> Option<K> {
308-
let (map, dormant_map) = DormantMutRef::new(self);
309-
let root_node = map.root.as_mut()?.borrow_mut();
310-
match root_node.search_tree(key) {
311-
Found(handle) => Some(
312-
OccupiedEntry {
313-
handle,
314-
dormant_map,
315-
alloc: (*map.alloc).clone(),
316-
_marker: PhantomData,
317-
}
318-
.remove_kv()
319-
.0,
320-
),
321-
GoDown(_) => None,
322-
}
323-
}
324-
325-
fn replace(&mut self, key: K) -> Option<K> {
292+
/// Internal functionality for `BTreeSet`.
293+
impl<K, A: Allocator + Clone> BTreeMap<K, SetValZST, A> {
294+
pub(super) fn replace(&mut self, key: K) -> Option<K>
295+
where
296+
K: Ord,
297+
{
326298
let (map, dormant_map) = DormantMutRef::new(self);
327299
let root_node =
328300
map.root.get_or_insert_with(|| Root::new((*map.alloc).clone())).borrow_mut();

‎library/alloc/src/collections/btree/mod.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,3 @@ mod search;
1212
pub mod set;
1313
mod set_val;
1414
mod split;
15-
16-
trait Recover<Q: ?Sized> {
17-
type Key;
18-
19-
fn get(&self, key: &Q) -> Option<&Self::Key>;
20-
fn take(&mut self, key: &Q) -> Option<Self::Key>;
21-
fn replace(&mut self, key: Self::Key) -> Option<Self::Key>;
22-
}

‎library/alloc/src/collections/btree/set.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use core::iter::{FusedIterator, Peekable};
77
use core::mem::ManuallyDrop;
88
use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
99

10-
use super::Recover;
1110
use super::map::{BTreeMap, Keys};
1211
use super::merge_iter::MergeIterInner;
1312
use super::set_val::SetValZST;
@@ -635,7 +634,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
635634
T: Borrow<Q> + Ord,
636635
Q: Ord,
637636
{
638-
Recover::get(&self.map, value)
637+
self.map.get_key_value(value).map(|(k, _)| k)
639638
}
640639

641640
/// Returns `true` if `self` has no elements in common with `other`.
@@ -926,7 +925,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
926925
where
927926
T: Ord,
928927
{
929-
Recover::replace(&mut self.map, value)
928+
self.map.replace(value)
930929
}
931930

932931
/// If the set contains an element equal to the value, removes it from the
@@ -978,7 +977,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
978977
T: Borrow<Q> + Ord,
979978
Q: Ord,
980979
{
981-
Recover::take(&mut self.map, value)
980+
self.map.remove_entry(value).map(|(k, _)| k)
982981
}
983982

984983
/// Retains only the elements specified by the predicate.

‎library/alloc/src/collections/btree/set_val.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
/// * `BTreeMap<T, ()>` (possible user-defined map)
44
/// * `BTreeMap<T, SetValZST>` (internal set representation)
55
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Default)]
6-
pub struct SetValZST;
6+
pub(super) struct SetValZST;
77

88
/// A trait to differentiate between `BTreeMap` and `BTreeSet` values.
99
/// Returns `true` only for type `SetValZST`, `false` for all other types (blanket implementation).
1010
/// `TypeId` requires a `'static` lifetime, use of this trait avoids that restriction.
1111
///
1212
/// [`TypeId`]: std::any::TypeId
13-
pub trait IsSetVal {
13+
pub(super) trait IsSetVal {
1414
fn is_set_val() -> bool;
1515
}
1616

‎library/alloc/src/rc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1876,7 +1876,7 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Rc<T, A> {
18761876
// Initialize with clone of this.
18771877
let initialized_clone = unsafe {
18781878
// Clone. If the clone panics, `in_progress` will be dropped and clean up.
1879-
this_data_ref.clone_to_uninit(in_progress.data_ptr());
1879+
this_data_ref.clone_to_uninit(in_progress.data_ptr().cast());
18801880
// Cast type of pointer, now that it is initialized.
18811881
in_progress.into_rc()
18821882
};

‎library/alloc/src/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2272,7 +2272,7 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {
22722272

22732273
let initialized_clone = unsafe {
22742274
// Clone. If the clone panics, `in_progress` will be dropped and clean up.
2275-
this_data_ref.clone_to_uninit(in_progress.data_ptr());
2275+
this_data_ref.clone_to_uninit(in_progress.data_ptr().cast());
22762276
// Cast type of pointer, now that it is initialized.
22772277
in_progress.into_arc()
22782278
};

‎library/core/src/clone.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,20 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
232232
pub unsafe trait CloneToUninit {
233233
/// Performs copy-assignment from `self` to `dst`.
234234
///
235-
/// This is analogous to `std::ptr::write(dst, self.clone())`,
235+
/// This is analogous to `std::ptr::write(dst.cast(), self.clone())`,
236236
/// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)).
237237
///
238238
/// Before this function is called, `dst` may point to uninitialized memory.
239239
/// After this function is called, `dst` will point to initialized memory; it will be
240-
/// sound to create a `&Self` reference from the pointer.
240+
/// sound to create a `&Self` reference from the pointer with the [pointer metadata]
241+
/// from `self`.
241242
///
242243
/// # Safety
243244
///
244245
/// Behavior is undefined if any of the following conditions are violated:
245246
///
246-
/// * `dst` must be [valid] for writes.
247-
/// * `dst` must be properly aligned.
248-
/// * `dst` must have the same [pointer metadata] (slice length or `dyn` vtable) as `self`.
247+
/// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes.
248+
/// * `dst` must be properly aligned to `std::mem::align_of_val(self)`.
249249
///
250250
/// [valid]: crate::ptr#safety
251251
/// [pointer metadata]: crate::ptr::metadata()
@@ -266,23 +266,24 @@ pub unsafe trait CloneToUninit {
266266
/// that might have already been created. (For example, if a `[Foo]` of length 3 is being
267267
/// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
268268
/// cloned should be dropped.)
269-
unsafe fn clone_to_uninit(&self, dst: *mut Self);
269+
unsafe fn clone_to_uninit(&self, dst: *mut u8);
270270
}
271271

272272
#[unstable(feature = "clone_to_uninit", issue = "126799")]
273273
unsafe impl<T: Clone> CloneToUninit for T {
274274
#[inline]
275-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
275+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
276276
// SAFETY: we're calling a specialization with the same contract
277-
unsafe { <T as self::uninit::CopySpec>::clone_one(self, dst) }
277+
unsafe { <T as self::uninit::CopySpec>::clone_one(self, dst.cast::<T>()) }
278278
}
279279
}
280280

281281
#[unstable(feature = "clone_to_uninit", issue = "126799")]
282282
unsafe impl<T: Clone> CloneToUninit for [T] {
283283
#[inline]
284284
#[cfg_attr(debug_assertions, track_caller)]
285-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
285+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
286+
let dst: *mut [T] = dst.with_metadata_of(self);
286287
// SAFETY: we're calling a specialization with the same contract
287288
unsafe { <T as self::uninit::CopySpec>::clone_slice(self, dst) }
288289
}
@@ -292,21 +293,21 @@ unsafe impl<T: Clone> CloneToUninit for [T] {
292293
unsafe impl CloneToUninit for str {
293294
#[inline]
294295
#[cfg_attr(debug_assertions, track_caller)]
295-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
296+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
296297
// SAFETY: str is just a [u8] with UTF-8 invariant
297-
unsafe { self.as_bytes().clone_to_uninit(dst as *mut [u8]) }
298+
unsafe { self.as_bytes().clone_to_uninit(dst) }
298299
}
299300
}
300301

301302
#[unstable(feature = "clone_to_uninit", issue = "126799")]
302303
unsafe impl CloneToUninit for crate::ffi::CStr {
303304
#[cfg_attr(debug_assertions, track_caller)]
304-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
305+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
305306
// SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
306307
// And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul).
307-
// The pointer metadata properly preserves the length (NUL included).
308+
// The pointer metadata properly preserves the length (so NUL is also copied).
308309
// See: `cstr_metadata_is_length_with_nul` in tests.
309-
unsafe { self.to_bytes_with_nul().clone_to_uninit(dst as *mut [u8]) }
310+
unsafe { self.to_bytes_with_nul().clone_to_uninit(dst) }
310311
}
311312
}
312313

‎library/core/src/fmt/float.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ macro_rules! impl_general_format {
1313
($($t:ident)*) => {
1414
$(impl GeneralFormat for $t {
1515
fn already_rounded_value_should_use_exponential(&self) -> bool {
16-
let abs = $t::abs_private(*self);
16+
let abs = $t::abs(*self);
1717
(abs != 0.0 && abs < 1e-4) || abs >= 1e+16
1818
}
1919
})*

‎library/core/src/intrinsics/mod.rs

Lines changed: 1279 additions & 805 deletions
Large diffs are not rendered by default.

‎library/core/src/num/dec2flt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
//!
5959
//! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover
6060
//! a small percentage of possible errors. Far more extensive tests are located in the directory
61-
//! `src/etc/test-float-parse` as a Python script.
61+
//! `src/etc/test-float-parse` as a Rust program.
6262
//!
6363
//! A note on integer overflow: Many parts of this file perform arithmetic with the decimal
6464
//! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit,

‎library/core/src/num/f128.rs

Lines changed: 100 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,6 @@ impl f128 {
285285
self != self
286286
}
287287

288-
// FIXME(#50145): `abs` is publicly unavailable in core due to
289-
// concerns about portability, so this implementation is for
290-
// private use internally.
291-
#[inline]
292-
pub(crate) const fn abs_private(self) -> f128 {
293-
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
294-
unsafe {
295-
mem::transmute::<u128, f128>(mem::transmute::<f128, u128>(self) & !Self::SIGN_MASK)
296-
}
297-
}
298-
299288
/// Returns `true` if this value is positive infinity or negative infinity, and
300289
/// `false` otherwise.
301290
///
@@ -345,10 +334,11 @@ impl f128 {
345334
#[inline]
346335
#[must_use]
347336
#[unstable(feature = "f128", issue = "116909")]
337+
#[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
348338
pub const fn is_finite(self) -> bool {
349339
// There's no need to handle NaN separately: if self is NaN,
350340
// the comparison is not true, exactly as desired.
351-
self.abs_private() < Self::INFINITY
341+
self.abs() < Self::INFINITY
352342
}
353343

354344
/// Returns `true` if the number is [subnormal].
@@ -836,8 +826,8 @@ impl f128 {
836826
const HI: f128 = f128::MAX / 2.;
837827

838828
let (a, b) = (self, other);
839-
let abs_a = a.abs_private();
840-
let abs_b = b.abs_private();
829+
let abs_a = a.abs();
830+
let abs_b = b.abs();
841831

842832
if abs_a <= HI && abs_b <= HI {
843833
// Overflow is impossible
@@ -1281,4 +1271,100 @@ impl f128 {
12811271
}
12821272
self
12831273
}
1274+
1275+
/// Computes the absolute value of `self`.
1276+
///
1277+
/// This function always returns the precise result.
1278+
///
1279+
/// # Examples
1280+
///
1281+
/// ```
1282+
/// #![feature(f128)]
1283+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1284+
///
1285+
/// let x = 3.5_f128;
1286+
/// let y = -3.5_f128;
1287+
///
1288+
/// assert_eq!(x.abs(), x);
1289+
/// assert_eq!(y.abs(), -y);
1290+
///
1291+
/// assert!(f128::NAN.abs().is_nan());
1292+
/// # }
1293+
/// ```
1294+
#[inline]
1295+
#[unstable(feature = "f128", issue = "116909")]
1296+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1297+
#[must_use = "method returns a new number and does not mutate the original value"]
1298+
pub const fn abs(self) -> Self {
1299+
// FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
1300+
// We don't do this now because LLVM has lowering bugs for f128 math.
1301+
Self::from_bits(self.to_bits() & !(1 << 127))
1302+
}
1303+
1304+
/// Returns a number that represents the sign of `self`.
1305+
///
1306+
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
1307+
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
1308+
/// - NaN if the number is NaN
1309+
///
1310+
/// # Examples
1311+
///
1312+
/// ```
1313+
/// #![feature(f128)]
1314+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1315+
///
1316+
/// let f = 3.5_f128;
1317+
///
1318+
/// assert_eq!(f.signum(), 1.0);
1319+
/// assert_eq!(f128::NEG_INFINITY.signum(), -1.0);
1320+
///
1321+
/// assert!(f128::NAN.signum().is_nan());
1322+
/// # }
1323+
/// ```
1324+
#[inline]
1325+
#[unstable(feature = "f128", issue = "116909")]
1326+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1327+
#[must_use = "method returns a new number and does not mutate the original value"]
1328+
pub const fn signum(self) -> f128 {
1329+
if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
1330+
}
1331+
1332+
/// Returns a number composed of the magnitude of `self` and the sign of
1333+
/// `sign`.
1334+
///
1335+
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
1336+
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
1337+
/// returned.
1338+
///
1339+
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
1340+
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
1341+
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
1342+
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
1343+
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
1344+
/// info.
1345+
///
1346+
/// # Examples
1347+
///
1348+
/// ```
1349+
/// #![feature(f128)]
1350+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1351+
///
1352+
/// let f = 3.5_f128;
1353+
///
1354+
/// assert_eq!(f.copysign(0.42), 3.5_f128);
1355+
/// assert_eq!(f.copysign(-0.42), -3.5_f128);
1356+
/// assert_eq!((-f).copysign(0.42), 3.5_f128);
1357+
/// assert_eq!((-f).copysign(-0.42), -3.5_f128);
1358+
///
1359+
/// assert!(f128::NAN.copysign(1.0).is_nan());
1360+
/// # }
1361+
/// ```
1362+
#[inline]
1363+
#[unstable(feature = "f128", issue = "116909")]
1364+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1365+
#[must_use = "method returns a new number and does not mutate the original value"]
1366+
pub const fn copysign(self, sign: f128) -> f128 {
1367+
// SAFETY: this is actually a safe intrinsic
1368+
unsafe { intrinsics::copysignf128(self, sign) }
1369+
}
12841370
}

‎library/core/src/num/f16.rs

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,6 @@ impl f16 {
279279
self != self
280280
}
281281

282-
// FIXMxE(#50145): `abs` is publicly unavailable in core due to
283-
// concerns about portability, so this implementation is for
284-
// private use internally.
285-
#[inline]
286-
pub(crate) const fn abs_private(self) -> f16 {
287-
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
288-
unsafe { mem::transmute::<u16, f16>(mem::transmute::<f16, u16>(self) & !Self::SIGN_MASK) }
289-
}
290-
291282
/// Returns `true` if this value is positive infinity or negative infinity, and
292283
/// `false` otherwise.
293284
///
@@ -335,10 +326,11 @@ impl f16 {
335326
#[inline]
336327
#[must_use]
337328
#[unstable(feature = "f16", issue = "116909")]
329+
#[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
338330
pub const fn is_finite(self) -> bool {
339331
// There's no need to handle NaN separately: if self is NaN,
340332
// the comparison is not true, exactly as desired.
341-
self.abs_private() < Self::INFINITY
333+
self.abs() < Self::INFINITY
342334
}
343335

344336
/// Returns `true` if the number is [subnormal].
@@ -821,8 +813,8 @@ impl f16 {
821813
const HI: f16 = f16::MAX / 2.;
822814

823815
let (a, b) = (self, other);
824-
let abs_a = a.abs_private();
825-
let abs_b = b.abs_private();
816+
let abs_a = a.abs();
817+
let abs_b = b.abs();
826818

827819
if abs_a <= HI && abs_b <= HI {
828820
// Overflow is impossible
@@ -1256,4 +1248,99 @@ impl f16 {
12561248
}
12571249
self
12581250
}
1251+
1252+
/// Computes the absolute value of `self`.
1253+
///
1254+
/// This function always returns the precise result.
1255+
///
1256+
/// # Examples
1257+
///
1258+
/// ```
1259+
/// #![feature(f16)]
1260+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1261+
///
1262+
/// let x = 3.5_f16;
1263+
/// let y = -3.5_f16;
1264+
///
1265+
/// assert_eq!(x.abs(), x);
1266+
/// assert_eq!(y.abs(), -y);
1267+
///
1268+
/// assert!(f16::NAN.abs().is_nan());
1269+
/// # }
1270+
/// ```
1271+
#[inline]
1272+
#[unstable(feature = "f16", issue = "116909")]
1273+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1274+
#[must_use = "method returns a new number and does not mutate the original value"]
1275+
pub const fn abs(self) -> Self {
1276+
// FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
1277+
Self::from_bits(self.to_bits() & !(1 << 15))
1278+
}
1279+
1280+
/// Returns a number that represents the sign of `self`.
1281+
///
1282+
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
1283+
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
1284+
/// - NaN if the number is NaN
1285+
///
1286+
/// # Examples
1287+
///
1288+
/// ```
1289+
/// #![feature(f16)]
1290+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1291+
///
1292+
/// let f = 3.5_f16;
1293+
///
1294+
/// assert_eq!(f.signum(), 1.0);
1295+
/// assert_eq!(f16::NEG_INFINITY.signum(), -1.0);
1296+
///
1297+
/// assert!(f16::NAN.signum().is_nan());
1298+
/// # }
1299+
/// ```
1300+
#[inline]
1301+
#[unstable(feature = "f16", issue = "116909")]
1302+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1303+
#[must_use = "method returns a new number and does not mutate the original value"]
1304+
pub const fn signum(self) -> f16 {
1305+
if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
1306+
}
1307+
1308+
/// Returns a number composed of the magnitude of `self` and the sign of
1309+
/// `sign`.
1310+
///
1311+
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
1312+
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
1313+
/// returned.
1314+
///
1315+
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
1316+
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
1317+
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
1318+
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
1319+
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
1320+
/// info.
1321+
///
1322+
/// # Examples
1323+
///
1324+
/// ```
1325+
/// #![feature(f16)]
1326+
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
1327+
///
1328+
/// let f = 3.5_f16;
1329+
///
1330+
/// assert_eq!(f.copysign(0.42), 3.5_f16);
1331+
/// assert_eq!(f.copysign(-0.42), -3.5_f16);
1332+
/// assert_eq!((-f).copysign(0.42), 3.5_f16);
1333+
/// assert_eq!((-f).copysign(-0.42), -3.5_f16);
1334+
///
1335+
/// assert!(f16::NAN.copysign(1.0).is_nan());
1336+
/// # }
1337+
/// ```
1338+
#[inline]
1339+
#[unstable(feature = "f16", issue = "116909")]
1340+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1341+
#[must_use = "method returns a new number and does not mutate the original value"]
1342+
pub const fn copysign(self, sign: f16) -> f16 {
1343+
// SAFETY: this is actually a safe intrinsic
1344+
unsafe { intrinsics::copysignf16(self, sign) }
1345+
}
12591346
}

‎library/core/src/num/f32.rs

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -525,15 +525,6 @@ impl f32 {
525525
self != self
526526
}
527527

528-
// FIXME(#50145): `abs` is publicly unavailable in core due to
529-
// concerns about portability, so this implementation is for
530-
// private use internally.
531-
#[inline]
532-
pub(crate) const fn abs_private(self) -> f32 {
533-
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
534-
unsafe { mem::transmute::<u32, f32>(mem::transmute::<f32, u32>(self) & !Self::SIGN_MASK) }
535-
}
536-
537528
/// Returns `true` if this value is positive infinity or negative infinity, and
538529
/// `false` otherwise.
539530
///
@@ -578,10 +569,11 @@ impl f32 {
578569
#[stable(feature = "rust1", since = "1.0.0")]
579570
#[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
580571
#[inline]
572+
#[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
581573
pub const fn is_finite(self) -> bool {
582574
// There's no need to handle NaN separately: if self is NaN,
583575
// the comparison is not true, exactly as desired.
584-
self.abs_private() < Self::INFINITY
576+
self.abs() < Self::INFINITY
585577
}
586578

587579
/// Returns `true` if the number is [subnormal].
@@ -1019,8 +1011,8 @@ impl f32 {
10191011
const HI: f32 = f32::MAX / 2.;
10201012

10211013
let (a, b) = (self, other);
1022-
let abs_a = a.abs_private();
1023-
let abs_b = b.abs_private();
1014+
let abs_a = a.abs();
1015+
let abs_b = b.abs();
10241016

10251017
if abs_a <= HI && abs_b <= HI {
10261018
// Overflow is impossible
@@ -1424,4 +1416,87 @@ impl f32 {
14241416
}
14251417
self
14261418
}
1419+
1420+
/// Computes the absolute value of `self`.
1421+
///
1422+
/// This function always returns the precise result.
1423+
///
1424+
/// # Examples
1425+
///
1426+
/// ```
1427+
/// let x = 3.5_f32;
1428+
/// let y = -3.5_f32;
1429+
///
1430+
/// assert_eq!(x.abs(), x);
1431+
/// assert_eq!(y.abs(), -y);
1432+
///
1433+
/// assert!(f32::NAN.abs().is_nan());
1434+
/// ```
1435+
#[must_use = "method returns a new number and does not mutate the original value"]
1436+
#[stable(feature = "rust1", since = "1.0.0")]
1437+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1438+
#[inline]
1439+
pub const fn abs(self) -> f32 {
1440+
// SAFETY: this is actually a safe intrinsic
1441+
unsafe { intrinsics::fabsf32(self) }
1442+
}
1443+
1444+
/// Returns a number that represents the sign of `self`.
1445+
///
1446+
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
1447+
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
1448+
/// - NaN if the number is NaN
1449+
///
1450+
/// # Examples
1451+
///
1452+
/// ```
1453+
/// let f = 3.5_f32;
1454+
///
1455+
/// assert_eq!(f.signum(), 1.0);
1456+
/// assert_eq!(f32::NEG_INFINITY.signum(), -1.0);
1457+
///
1458+
/// assert!(f32::NAN.signum().is_nan());
1459+
/// ```
1460+
#[must_use = "method returns a new number and does not mutate the original value"]
1461+
#[stable(feature = "rust1", since = "1.0.0")]
1462+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1463+
#[inline]
1464+
pub const fn signum(self) -> f32 {
1465+
if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
1466+
}
1467+
1468+
/// Returns a number composed of the magnitude of `self` and the sign of
1469+
/// `sign`.
1470+
///
1471+
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
1472+
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
1473+
/// returned.
1474+
///
1475+
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
1476+
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
1477+
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
1478+
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
1479+
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
1480+
/// info.
1481+
///
1482+
/// # Examples
1483+
///
1484+
/// ```
1485+
/// let f = 3.5_f32;
1486+
///
1487+
/// assert_eq!(f.copysign(0.42), 3.5_f32);
1488+
/// assert_eq!(f.copysign(-0.42), -3.5_f32);
1489+
/// assert_eq!((-f).copysign(0.42), 3.5_f32);
1490+
/// assert_eq!((-f).copysign(-0.42), -3.5_f32);
1491+
///
1492+
/// assert!(f32::NAN.copysign(1.0).is_nan());
1493+
/// ```
1494+
#[must_use = "method returns a new number and does not mutate the original value"]
1495+
#[inline]
1496+
#[stable(feature = "copysign", since = "1.35.0")]
1497+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1498+
pub const fn copysign(self, sign: f32) -> f32 {
1499+
// SAFETY: this is actually a safe intrinsic
1500+
unsafe { intrinsics::copysignf32(self, sign) }
1501+
}
14271502
}

‎library/core/src/num/f64.rs

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -524,15 +524,6 @@ impl f64 {
524524
self != self
525525
}
526526

527-
// FIXME(#50145): `abs` is publicly unavailable in core due to
528-
// concerns about portability, so this implementation is for
529-
// private use internally.
530-
#[inline]
531-
pub(crate) const fn abs_private(self) -> f64 {
532-
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
533-
unsafe { mem::transmute::<u64, f64>(mem::transmute::<f64, u64>(self) & !Self::SIGN_MASK) }
534-
}
535-
536527
/// Returns `true` if this value is positive infinity or negative infinity, and
537528
/// `false` otherwise.
538529
///
@@ -577,10 +568,11 @@ impl f64 {
577568
#[stable(feature = "rust1", since = "1.0.0")]
578569
#[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
579570
#[inline]
571+
#[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
580572
pub const fn is_finite(self) -> bool {
581573
// There's no need to handle NaN separately: if self is NaN,
582574
// the comparison is not true, exactly as desired.
583-
self.abs_private() < Self::INFINITY
575+
self.abs() < Self::INFINITY
584576
}
585577

586578
/// Returns `true` if the number is [subnormal].
@@ -1022,8 +1014,8 @@ impl f64 {
10221014
const HI: f64 = f64::MAX / 2.;
10231015

10241016
let (a, b) = (self, other);
1025-
let abs_a = a.abs_private();
1026-
let abs_b = b.abs_private();
1017+
let abs_a = a.abs();
1018+
let abs_b = b.abs();
10271019

10281020
if abs_a <= HI && abs_b <= HI {
10291021
// Overflow is impossible
@@ -1424,4 +1416,87 @@ impl f64 {
14241416
}
14251417
self
14261418
}
1419+
1420+
/// Computes the absolute value of `self`.
1421+
///
1422+
/// This function always returns the precise result.
1423+
///
1424+
/// # Examples
1425+
///
1426+
/// ```
1427+
/// let x = 3.5_f64;
1428+
/// let y = -3.5_f64;
1429+
///
1430+
/// assert_eq!(x.abs(), x);
1431+
/// assert_eq!(y.abs(), -y);
1432+
///
1433+
/// assert!(f64::NAN.abs().is_nan());
1434+
/// ```
1435+
#[must_use = "method returns a new number and does not mutate the original value"]
1436+
#[stable(feature = "rust1", since = "1.0.0")]
1437+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1438+
#[inline]
1439+
pub const fn abs(self) -> f64 {
1440+
// SAFETY: this is actually a safe intrinsic
1441+
unsafe { intrinsics::fabsf64(self) }
1442+
}
1443+
1444+
/// Returns a number that represents the sign of `self`.
1445+
///
1446+
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
1447+
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
1448+
/// - NaN if the number is NaN
1449+
///
1450+
/// # Examples
1451+
///
1452+
/// ```
1453+
/// let f = 3.5_f64;
1454+
///
1455+
/// assert_eq!(f.signum(), 1.0);
1456+
/// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
1457+
///
1458+
/// assert!(f64::NAN.signum().is_nan());
1459+
/// ```
1460+
#[must_use = "method returns a new number and does not mutate the original value"]
1461+
#[stable(feature = "rust1", since = "1.0.0")]
1462+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1463+
#[inline]
1464+
pub const fn signum(self) -> f64 {
1465+
if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
1466+
}
1467+
1468+
/// Returns a number composed of the magnitude of `self` and the sign of
1469+
/// `sign`.
1470+
///
1471+
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
1472+
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
1473+
/// returned.
1474+
///
1475+
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
1476+
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
1477+
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
1478+
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
1479+
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
1480+
/// info.
1481+
///
1482+
/// # Examples
1483+
///
1484+
/// ```
1485+
/// let f = 3.5_f64;
1486+
///
1487+
/// assert_eq!(f.copysign(0.42), 3.5_f64);
1488+
/// assert_eq!(f.copysign(-0.42), -3.5_f64);
1489+
/// assert_eq!((-f).copysign(0.42), 3.5_f64);
1490+
/// assert_eq!((-f).copysign(-0.42), -3.5_f64);
1491+
///
1492+
/// assert!(f64::NAN.copysign(1.0).is_nan());
1493+
/// ```
1494+
#[must_use = "method returns a new number and does not mutate the original value"]
1495+
#[stable(feature = "copysign", since = "1.35.0")]
1496+
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
1497+
#[inline]
1498+
pub const fn copysign(self, sign: f64) -> f64 {
1499+
// SAFETY: this is actually a safe intrinsic
1500+
unsafe { intrinsics::copysignf64(self, sign) }
1501+
}
14271502
}

‎library/core/tests/clone.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn test_clone_to_uninit_slice_success() {
2828

2929
let mut storage: MaybeUninit<[String; 3]> = MaybeUninit::uninit();
3030
let b: [String; 3] = unsafe {
31-
a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [String]);
31+
a[..].clone_to_uninit(storage.as_mut_ptr().cast());
3232
storage.assume_init()
3333
};
3434

@@ -70,7 +70,7 @@ fn test_clone_to_uninit_slice_drops_on_panic() {
7070
let mut storage: MaybeUninit<[CountsDropsAndPanics; 3]> = MaybeUninit::uninit();
7171
// This should panic halfway through
7272
unsafe {
73-
a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [CountsDropsAndPanics]);
73+
a[..].clone_to_uninit(storage.as_mut_ptr().cast());
7474
}
7575
})
7676
.unwrap_err();
@@ -89,13 +89,13 @@ fn test_clone_to_uninit_str() {
8989
let a = "hello";
9090

9191
let mut storage: MaybeUninit<[u8; 5]> = MaybeUninit::uninit();
92-
unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut str) };
92+
unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) };
9393
assert_eq!(a.as_bytes(), unsafe { storage.assume_init() }.as_slice());
9494

9595
let mut b: Box<str> = "world".into();
9696
assert_eq!(a.len(), b.len());
9797
assert_ne!(a, &*b);
98-
unsafe { a.clone_to_uninit(ptr::from_mut::<str>(&mut b)) };
98+
unsafe { a.clone_to_uninit(ptr::from_mut::<str>(&mut b).cast()) };
9999
assert_eq!(a, &*b);
100100
}
101101

@@ -104,13 +104,13 @@ fn test_clone_to_uninit_cstr() {
104104
let a = c"hello";
105105

106106
let mut storage: MaybeUninit<[u8; 6]> = MaybeUninit::uninit();
107-
unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut CStr) };
107+
unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) };
108108
assert_eq!(a.to_bytes_with_nul(), unsafe { storage.assume_init() }.as_slice());
109109

110110
let mut b: Box<CStr> = c"world".into();
111111
assert_eq!(a.count_bytes(), b.count_bytes());
112112
assert_ne!(a, &*b);
113-
unsafe { a.clone_to_uninit(ptr::from_mut::<CStr>(&mut b)) };
113+
unsafe { a.clone_to_uninit(ptr::from_mut::<CStr>(&mut b).cast()) };
114114
assert_eq!(a, &*b);
115115
}
116116

‎library/std/src/f128.rs

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -188,104 +188,6 @@ impl f128 {
188188
self - self.trunc()
189189
}
190190

191-
/// Computes the absolute value of `self`.
192-
///
193-
/// This function always returns the precise result.
194-
///
195-
/// # Examples
196-
///
197-
/// ```
198-
/// #![feature(f128)]
199-
/// # #[cfg(reliable_f128)] {
200-
///
201-
/// let x = 3.5_f128;
202-
/// let y = -3.5_f128;
203-
///
204-
/// assert_eq!(x.abs(), x);
205-
/// assert_eq!(y.abs(), -y);
206-
///
207-
/// assert!(f128::NAN.abs().is_nan());
208-
/// # }
209-
/// ```
210-
#[inline]
211-
#[rustc_allow_incoherent_impl]
212-
#[unstable(feature = "f128", issue = "116909")]
213-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
214-
#[must_use = "method returns a new number and does not mutate the original value"]
215-
pub const fn abs(self) -> Self {
216-
// FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
217-
// We don't do this now because LLVM has lowering bugs for f128 math.
218-
Self::from_bits(self.to_bits() & !(1 << 127))
219-
}
220-
221-
/// Returns a number that represents the sign of `self`.
222-
///
223-
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
224-
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
225-
/// - NaN if the number is NaN
226-
///
227-
/// # Examples
228-
///
229-
/// ```
230-
/// #![feature(f128)]
231-
/// # #[cfg(reliable_f128_math)] {
232-
///
233-
/// let f = 3.5_f128;
234-
///
235-
/// assert_eq!(f.signum(), 1.0);
236-
/// assert_eq!(f128::NEG_INFINITY.signum(), -1.0);
237-
///
238-
/// assert!(f128::NAN.signum().is_nan());
239-
/// # }
240-
/// ```
241-
#[inline]
242-
#[rustc_allow_incoherent_impl]
243-
#[unstable(feature = "f128", issue = "116909")]
244-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
245-
#[must_use = "method returns a new number and does not mutate the original value"]
246-
pub const fn signum(self) -> f128 {
247-
if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
248-
}
249-
250-
/// Returns a number composed of the magnitude of `self` and the sign of
251-
/// `sign`.
252-
///
253-
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
254-
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
255-
/// returned.
256-
///
257-
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
258-
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
259-
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
260-
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
261-
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
262-
/// info.
263-
///
264-
/// # Examples
265-
///
266-
/// ```
267-
/// #![feature(f128)]
268-
/// # #[cfg(reliable_f128_math)] {
269-
///
270-
/// let f = 3.5_f128;
271-
///
272-
/// assert_eq!(f.copysign(0.42), 3.5_f128);
273-
/// assert_eq!(f.copysign(-0.42), -3.5_f128);
274-
/// assert_eq!((-f).copysign(0.42), 3.5_f128);
275-
/// assert_eq!((-f).copysign(-0.42), -3.5_f128);
276-
///
277-
/// assert!(f128::NAN.copysign(1.0).is_nan());
278-
/// # }
279-
/// ```
280-
#[inline]
281-
#[rustc_allow_incoherent_impl]
282-
#[unstable(feature = "f128", issue = "116909")]
283-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
284-
#[must_use = "method returns a new number and does not mutate the original value"]
285-
pub const fn copysign(self, sign: f128) -> f128 {
286-
unsafe { intrinsics::copysignf128(self, sign) }
287-
}
288-
289191
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
290192
/// error, yielding a more accurate result than an unfused multiply-add.
291193
///

‎library/std/src/f16.rs

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -188,103 +188,6 @@ impl f16 {
188188
self - self.trunc()
189189
}
190190

191-
/// Computes the absolute value of `self`.
192-
///
193-
/// This function always returns the precise result.
194-
///
195-
/// # Examples
196-
///
197-
/// ```
198-
/// #![feature(f16)]
199-
/// # #[cfg(reliable_f16)] {
200-
///
201-
/// let x = 3.5_f16;
202-
/// let y = -3.5_f16;
203-
///
204-
/// assert_eq!(x.abs(), x);
205-
/// assert_eq!(y.abs(), -y);
206-
///
207-
/// assert!(f16::NAN.abs().is_nan());
208-
/// # }
209-
/// ```
210-
#[inline]
211-
#[rustc_allow_incoherent_impl]
212-
#[unstable(feature = "f16", issue = "116909")]
213-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
214-
#[must_use = "method returns a new number and does not mutate the original value"]
215-
pub const fn abs(self) -> Self {
216-
// FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
217-
Self::from_bits(self.to_bits() & !(1 << 15))
218-
}
219-
220-
/// Returns a number that represents the sign of `self`.
221-
///
222-
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
223-
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
224-
/// - NaN if the number is NaN
225-
///
226-
/// # Examples
227-
///
228-
/// ```
229-
/// #![feature(f16)]
230-
/// # #[cfg(reliable_f16_math)] {
231-
///
232-
/// let f = 3.5_f16;
233-
///
234-
/// assert_eq!(f.signum(), 1.0);
235-
/// assert_eq!(f16::NEG_INFINITY.signum(), -1.0);
236-
///
237-
/// assert!(f16::NAN.signum().is_nan());
238-
/// # }
239-
/// ```
240-
#[inline]
241-
#[rustc_allow_incoherent_impl]
242-
#[unstable(feature = "f16", issue = "116909")]
243-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
244-
#[must_use = "method returns a new number and does not mutate the original value"]
245-
pub const fn signum(self) -> f16 {
246-
if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
247-
}
248-
249-
/// Returns a number composed of the magnitude of `self` and the sign of
250-
/// `sign`.
251-
///
252-
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
253-
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
254-
/// returned.
255-
///
256-
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
257-
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
258-
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
259-
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
260-
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
261-
/// info.
262-
///
263-
/// # Examples
264-
///
265-
/// ```
266-
/// #![feature(f16)]
267-
/// # #[cfg(reliable_f16_math)] {
268-
///
269-
/// let f = 3.5_f16;
270-
///
271-
/// assert_eq!(f.copysign(0.42), 3.5_f16);
272-
/// assert_eq!(f.copysign(-0.42), -3.5_f16);
273-
/// assert_eq!((-f).copysign(0.42), 3.5_f16);
274-
/// assert_eq!((-f).copysign(-0.42), -3.5_f16);
275-
///
276-
/// assert!(f16::NAN.copysign(1.0).is_nan());
277-
/// # }
278-
/// ```
279-
#[inline]
280-
#[rustc_allow_incoherent_impl]
281-
#[unstable(feature = "f16", issue = "116909")]
282-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
283-
#[must_use = "method returns a new number and does not mutate the original value"]
284-
pub const fn copysign(self, sign: f16) -> f16 {
285-
unsafe { intrinsics::copysignf16(self, sign) }
286-
}
287-
288191
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
289192
/// error, yielding a more accurate result than an unfused multiply-add.
290193
///

‎library/std/src/f32.rs

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -176,90 +176,6 @@ impl f32 {
176176
self - self.trunc()
177177
}
178178

179-
/// Computes the absolute value of `self`.
180-
///
181-
/// This function always returns the precise result.
182-
///
183-
/// # Examples
184-
///
185-
/// ```
186-
/// let x = 3.5_f32;
187-
/// let y = -3.5_f32;
188-
///
189-
/// assert_eq!(x.abs(), x);
190-
/// assert_eq!(y.abs(), -y);
191-
///
192-
/// assert!(f32::NAN.abs().is_nan());
193-
/// ```
194-
#[rustc_allow_incoherent_impl]
195-
#[must_use = "method returns a new number and does not mutate the original value"]
196-
#[stable(feature = "rust1", since = "1.0.0")]
197-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
198-
#[inline]
199-
pub const fn abs(self) -> f32 {
200-
unsafe { intrinsics::fabsf32(self) }
201-
}
202-
203-
/// Returns a number that represents the sign of `self`.
204-
///
205-
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
206-
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
207-
/// - NaN if the number is NaN
208-
///
209-
/// # Examples
210-
///
211-
/// ```
212-
/// let f = 3.5_f32;
213-
///
214-
/// assert_eq!(f.signum(), 1.0);
215-
/// assert_eq!(f32::NEG_INFINITY.signum(), -1.0);
216-
///
217-
/// assert!(f32::NAN.signum().is_nan());
218-
/// ```
219-
#[rustc_allow_incoherent_impl]
220-
#[must_use = "method returns a new number and does not mutate the original value"]
221-
#[stable(feature = "rust1", since = "1.0.0")]
222-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
223-
#[inline]
224-
pub const fn signum(self) -> f32 {
225-
if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
226-
}
227-
228-
/// Returns a number composed of the magnitude of `self` and the sign of
229-
/// `sign`.
230-
///
231-
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
232-
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
233-
/// returned.
234-
///
235-
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
236-
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
237-
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
238-
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
239-
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
240-
/// info.
241-
///
242-
/// # Examples
243-
///
244-
/// ```
245-
/// let f = 3.5_f32;
246-
///
247-
/// assert_eq!(f.copysign(0.42), 3.5_f32);
248-
/// assert_eq!(f.copysign(-0.42), -3.5_f32);
249-
/// assert_eq!((-f).copysign(0.42), 3.5_f32);
250-
/// assert_eq!((-f).copysign(-0.42), -3.5_f32);
251-
///
252-
/// assert!(f32::NAN.copysign(1.0).is_nan());
253-
/// ```
254-
#[rustc_allow_incoherent_impl]
255-
#[must_use = "method returns a new number and does not mutate the original value"]
256-
#[inline]
257-
#[stable(feature = "copysign", since = "1.35.0")]
258-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
259-
pub const fn copysign(self, sign: f32) -> f32 {
260-
unsafe { intrinsics::copysignf32(self, sign) }
261-
}
262-
263179
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
264180
/// error, yielding a more accurate result than an unfused multiply-add.
265181
///

‎library/std/src/f64.rs

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -176,90 +176,6 @@ impl f64 {
176176
self - self.trunc()
177177
}
178178

179-
/// Computes the absolute value of `self`.
180-
///
181-
/// This function always returns the precise result.
182-
///
183-
/// # Examples
184-
///
185-
/// ```
186-
/// let x = 3.5_f64;
187-
/// let y = -3.5_f64;
188-
///
189-
/// assert_eq!(x.abs(), x);
190-
/// assert_eq!(y.abs(), -y);
191-
///
192-
/// assert!(f64::NAN.abs().is_nan());
193-
/// ```
194-
#[rustc_allow_incoherent_impl]
195-
#[must_use = "method returns a new number and does not mutate the original value"]
196-
#[stable(feature = "rust1", since = "1.0.0")]
197-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
198-
#[inline]
199-
pub const fn abs(self) -> f64 {
200-
unsafe { intrinsics::fabsf64(self) }
201-
}
202-
203-
/// Returns a number that represents the sign of `self`.
204-
///
205-
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
206-
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
207-
/// - NaN if the number is NaN
208-
///
209-
/// # Examples
210-
///
211-
/// ```
212-
/// let f = 3.5_f64;
213-
///
214-
/// assert_eq!(f.signum(), 1.0);
215-
/// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
216-
///
217-
/// assert!(f64::NAN.signum().is_nan());
218-
/// ```
219-
#[rustc_allow_incoherent_impl]
220-
#[must_use = "method returns a new number and does not mutate the original value"]
221-
#[stable(feature = "rust1", since = "1.0.0")]
222-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
223-
#[inline]
224-
pub const fn signum(self) -> f64 {
225-
if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
226-
}
227-
228-
/// Returns a number composed of the magnitude of `self` and the sign of
229-
/// `sign`.
230-
///
231-
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
232-
/// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
233-
/// returned.
234-
///
235-
/// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
236-
/// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
237-
/// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
238-
/// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
239-
/// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
240-
/// info.
241-
///
242-
/// # Examples
243-
///
244-
/// ```
245-
/// let f = 3.5_f64;
246-
///
247-
/// assert_eq!(f.copysign(0.42), 3.5_f64);
248-
/// assert_eq!(f.copysign(-0.42), -3.5_f64);
249-
/// assert_eq!((-f).copysign(0.42), 3.5_f64);
250-
/// assert_eq!((-f).copysign(-0.42), -3.5_f64);
251-
///
252-
/// assert!(f64::NAN.copysign(1.0).is_nan());
253-
/// ```
254-
#[rustc_allow_incoherent_impl]
255-
#[must_use = "method returns a new number and does not mutate the original value"]
256-
#[stable(feature = "copysign", since = "1.35.0")]
257-
#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
258-
#[inline]
259-
pub const fn copysign(self, sign: f64) -> f64 {
260-
unsafe { intrinsics::copysignf64(self, sign) }
261-
}
262-
263179
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
264180
/// error, yielding a more accurate result than an unfused multiply-add.
265181
///

‎library/std/src/ffi/os_str.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl crate::sealed::Sealed for OsString {}
112112
/// [conversions]: super#conversions
113113
#[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
114114
#[stable(feature = "rust1", since = "1.0.0")]
115-
// `OsStr::from_inner` current implementation relies
115+
// `OsStr::from_inner` and `impl CloneToUninit for OsStr` current implementation relies
116116
// on `OsStr` being layout-compatible with `Slice`.
117117
// However, `OsStr` layout is considered an implementation detail and must not be relied upon.
118118
#[repr(transparent)]
@@ -1278,9 +1278,9 @@ impl Clone for Box<OsStr> {
12781278
unsafe impl CloneToUninit for OsStr {
12791279
#[inline]
12801280
#[cfg_attr(debug_assertions, track_caller)]
1281-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
1282-
// SAFETY: we're just a wrapper around a platform-specific Slice
1283-
unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
1281+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
1282+
// SAFETY: we're just a transparent wrapper around a platform-specific Slice
1283+
unsafe { self.inner.clone_to_uninit(dst) }
12841284
}
12851285
}
12861286

‎library/std/src/ffi/os_str/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,12 @@ fn clone_to_uninit() {
294294
let a = OsStr::new("hello.txt");
295295

296296
let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<OsStr>(a)];
297-
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut OsStr) };
297+
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
298298
assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) });
299299

300300
let mut b: Box<OsStr> = OsStr::new("world.exe").into();
301301
assert_eq!(size_of_val::<OsStr>(a), size_of_val::<OsStr>(&b));
302302
assert_ne!(a, &*b);
303-
unsafe { a.clone_to_uninit(ptr::from_mut::<OsStr>(&mut b)) };
303+
unsafe { a.clone_to_uninit(ptr::from_mut::<OsStr>(&mut b).cast()) };
304304
assert_eq!(a, &*b);
305305
}

‎library/std/src/path.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,7 @@ impl AsRef<OsStr> for PathBuf {
21282128
/// ```
21292129
#[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
21302130
#[stable(feature = "rust1", since = "1.0.0")]
2131-
// `Path::new` current implementation relies
2131+
// `Path::new` and `impl CloneToUninit for Path` current implementation relies
21322132
// on `Path` being layout-compatible with `OsStr`.
21332133
// However, `Path` layout is considered an implementation detail and must not be relied upon.
21342134
#[repr(transparent)]
@@ -3170,9 +3170,9 @@ impl Path {
31703170
unsafe impl CloneToUninit for Path {
31713171
#[inline]
31723172
#[cfg_attr(debug_assertions, track_caller)]
3173-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
3174-
// SAFETY: Path is just a wrapper around OsStr
3175-
unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
3173+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
3174+
// SAFETY: Path is just a transparent wrapper around OsStr
3175+
unsafe { self.inner.clone_to_uninit(dst) }
31763176
}
31773177
}
31783178

‎library/std/src/path/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,14 +2068,14 @@ fn clone_to_uninit() {
20682068
let a = Path::new("hello.txt");
20692069

20702070
let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<Path>(a)];
2071-
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut Path) };
2071+
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
20722072
assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe {
20732073
MaybeUninit::slice_assume_init_ref(&storage)
20742074
});
20752075

20762076
let mut b: Box<Path> = Path::new("world.exe").into();
20772077
assert_eq!(size_of_val::<Path>(a), size_of_val::<Path>(&b));
20782078
assert_ne!(a, &*b);
2079-
unsafe { a.clone_to_uninit(ptr::from_mut::<Path>(&mut b)) };
2079+
unsafe { a.clone_to_uninit(ptr::from_mut::<Path>(&mut b).cast()) };
20802080
assert_eq!(a, &*b);
20812081
}

‎library/std/src/sys/os_str/bytes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ impl Slice {
352352
unsafe impl CloneToUninit for Slice {
353353
#[inline]
354354
#[cfg_attr(debug_assertions, track_caller)]
355-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
356-
// SAFETY: we're just a wrapper around [u8]
357-
unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
355+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
356+
// SAFETY: we're just a transparent wrapper around [u8]
357+
unsafe { self.inner.clone_to_uninit(dst) }
358358
}
359359
}

‎library/std/src/sys/os_str/wtf8.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ impl Slice {
275275
unsafe impl CloneToUninit for Slice {
276276
#[inline]
277277
#[cfg_attr(debug_assertions, track_caller)]
278-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
279-
// SAFETY: we're just a wrapper around Wtf8
280-
unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
278+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
279+
// SAFETY: we're just a transparent wrapper around Wtf8
280+
unsafe { self.inner.clone_to_uninit(dst) }
281281
}
282282
}

‎library/std/src/sys_common/wtf8.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,8 +1052,8 @@ impl Hash for Wtf8 {
10521052
unsafe impl CloneToUninit for Wtf8 {
10531053
#[inline]
10541054
#[cfg_attr(debug_assertions, track_caller)]
1055-
unsafe fn clone_to_uninit(&self, dst: *mut Self) {
1056-
// SAFETY: we're just a wrapper around [u8]
1057-
unsafe { self.bytes.clone_to_uninit(&raw mut (*dst).bytes) }
1055+
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
1056+
// SAFETY: we're just a transparent wrapper around [u8]
1057+
unsafe { self.bytes.clone_to_uninit(dst) }
10581058
}
10591059
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Regression test for #132955 checking that we handle anon consts with
2+
// inference variables in their generic arguments correctly.
3+
//
4+
// This arose via diagnostics where we would have some failing goal such
5+
// as `[u8; AnonConst<Self>]: PartialEq<Self::A>`, then as part of diagnostics
6+
// we would replace all generic parameters with inference vars which would yield
7+
// a self type of `[u8; AnonConst<?x>]` and then attempt to normalize `AnonConst<?x>`.
8+
9+
pub trait T {
10+
type A;
11+
const P: Self::A;
12+
13+
fn a() {
14+
[0u8; std::mem::size_of::<Self::A>()] == Self::P;
15+
//~^ ERROR: can't compare
16+
//~| ERROR: constant expression depends on a generic parameter
17+
//~| ERROR: constant expression depends on a generic parameter
18+
}
19+
}
20+
21+
fn main() {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: constant expression depends on a generic parameter
2+
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:15
3+
|
4+
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this may fail depending on what value the parameter takes
8+
9+
error: constant expression depends on a generic parameter
10+
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
11+
|
12+
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
13+
| ^^
14+
|
15+
= note: this may fail depending on what value the parameter takes
16+
17+
error[E0277]: can't compare `[u8; std::mem::size_of::<Self::A>()]` with `<Self as T>::A`
18+
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
19+
|
20+
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
21+
| ^^ no implementation for `[u8; std::mem::size_of::<Self::A>()] == <Self as T>::A`
22+
|
23+
= help: the trait `PartialEq<<Self as T>::A>` is not implemented for `[u8; std::mem::size_of::<Self::A>()]`
24+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
25+
|
26+
LL | pub trait T where [u8; std::mem::size_of::<Self::A>()]: PartialEq<<Self as T>::A> {
27+
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28+
29+
error: aborting due to 3 previous errors
30+
31+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//@edition:2021
2+
3+
fn foo() {
4+
const { return }
5+
//~^ ERROR: return statement outside of function body
6+
}
7+
8+
fn labelled_block_break() {
9+
'a: { const { break 'a } }
10+
//~^ ERROR: `break` outside of a loop or labeled block
11+
//~| ERROR: use of unreachable label
12+
}
13+
14+
fn loop_break() {
15+
loop {
16+
const { break }
17+
//~^ ERROR: `break` outside of a loop or labeled block
18+
}
19+
}
20+
21+
fn continue_to_labelled_block() {
22+
'a: { const { continue 'a } }
23+
//~^ ERROR: `continue` outside of a loop
24+
//~| ERROR: use of unreachable label
25+
}
26+
27+
fn loop_continue() {
28+
loop {
29+
const { continue }
30+
//~^ ERROR: `continue` outside of a loop
31+
}
32+
}
33+
34+
async fn await_across_const_block() {
35+
const { async {}.await }
36+
//~^ ERROR: `await` is only allowed inside `async` functions and blocks
37+
}
38+
39+
fn reference_to_non_constant_in_const_block() {
40+
let x = 1;
41+
const { &x };
42+
//~^ ERROR: attempt to use a non-constant value in a constant
43+
}
44+
45+
46+
fn main() {}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
error[E0767]: use of unreachable label `'a`
2+
--> $DIR/cross_const_control_flow.rs:9:25
3+
|
4+
LL | 'a: { const { break 'a } }
5+
| -- ^^ unreachable label `'a`
6+
| |
7+
| unreachable label defined here
8+
|
9+
= note: labels are unreachable through functions, closures, async blocks and modules
10+
11+
error[E0767]: use of unreachable label `'a`
12+
--> $DIR/cross_const_control_flow.rs:22:28
13+
|
14+
LL | 'a: { const { continue 'a } }
15+
| -- ^^ unreachable label `'a`
16+
| |
17+
| unreachable label defined here
18+
|
19+
= note: labels are unreachable through functions, closures, async blocks and modules
20+
21+
error[E0435]: attempt to use a non-constant value in a constant
22+
--> $DIR/cross_const_control_flow.rs:41:14
23+
|
24+
LL | const { &x };
25+
| ^ non-constant value
26+
|
27+
help: consider using `const` instead of `let`
28+
|
29+
LL | const x: /* Type */ = 1;
30+
| ~~~~~ ++++++++++++
31+
32+
error[E0728]: `await` is only allowed inside `async` functions and blocks
33+
--> $DIR/cross_const_control_flow.rs:35:22
34+
|
35+
LL | const { async {}.await }
36+
| -----------^^^^^--
37+
| | |
38+
| | only allowed inside `async` functions and blocks
39+
| this is not `async`
40+
41+
error[E0268]: `break` outside of a loop or labeled block
42+
--> $DIR/cross_const_control_flow.rs:9:19
43+
|
44+
LL | 'a: { const { break 'a } }
45+
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
46+
47+
error[E0268]: `break` outside of a loop or labeled block
48+
--> $DIR/cross_const_control_flow.rs:16:17
49+
|
50+
LL | const { break }
51+
| ^^^^^ cannot `break` outside of a loop or labeled block
52+
53+
error[E0268]: `continue` outside of a loop
54+
--> $DIR/cross_const_control_flow.rs:22:19
55+
|
56+
LL | 'a: { const { continue 'a } }
57+
| ^^^^^^^^^^^ cannot `continue` outside of a loop
58+
59+
error[E0268]: `continue` outside of a loop
60+
--> $DIR/cross_const_control_flow.rs:29:17
61+
|
62+
LL | const { continue }
63+
| ^^^^^^^^ cannot `continue` outside of a loop
64+
65+
error[E0572]: return statement outside of function body
66+
--> $DIR/cross_const_control_flow.rs:4:13
67+
|
68+
LL | / fn foo() {
69+
LL | | const { return }
70+
| | --^^^^^^-- the return is part of this body...
71+
LL | |
72+
LL | | }
73+
| |_- ...not the enclosing function body
74+
75+
error: aborting due to 9 previous errors
76+
77+
Some errors have detailed explanations: E0268, E0435, E0572, E0728, E0767.
78+
For more information about an error, try `rustc --explain E0268`.

0 commit comments

Comments
 (0)
Please sign in to comment.