Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make more From impls const (libcore) #90009

Merged
merged 1 commit into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ impl TryFromSliceError {
}

#[stable(feature = "try_from_slice_error", since = "1.36.0")]
impl From<Infallible> for TryFromSliceError {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<Infallible> for TryFromSliceError {
fn from(x: Infallible) -> TryFromSliceError {
match x {}
}
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ impl<T: Ord + Copy> Ord for Cell<T> {
}

#[stable(feature = "cell_from", since = "1.12.0")]
impl<T> From<T> for Cell<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for Cell<T> {
fn from(t: T) -> Cell<T> {
Cell::new(t)
}
Expand Down Expand Up @@ -1236,7 +1237,8 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> {
}

#[stable(feature = "cell_from", since = "1.12.0")]
impl<T> From<T> for RefCell<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for RefCell<T> {
fn from(t: T) -> RefCell<T> {
RefCell::new(t)
}
Expand Down Expand Up @@ -1976,7 +1978,8 @@ impl<T: Default> Default for UnsafeCell<T> {
}

#[stable(feature = "cell_from", since = "1.12.0")]
impl<T> From<T> for UnsafeCell<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for UnsafeCell<T> {
fn from(t: T) -> UnsafeCell<T> {
UnsafeCell::new(t)
}
Expand Down
12 changes: 8 additions & 4 deletions library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ pub unsafe fn from_u32_unchecked(i: u32) -> char {
}

#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<char> for u32 {
/// Converts a [`char`] into a [`u32`].
///
/// # Examples
Expand All @@ -116,7 +117,8 @@ impl From<char> for u32 {
}

#[stable(feature = "more_char_conversions", since = "1.51.0")]
impl From<char> for u64 {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<char> for u64 {
/// Converts a [`char`] into a [`u64`].
///
/// # Examples
Expand All @@ -137,7 +139,8 @@ impl From<char> for u64 {
}

#[stable(feature = "more_char_conversions", since = "1.51.0")]
impl From<char> for u128 {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<char> for u128 {
/// Converts a [`char`] into a [`u128`].
///
/// # Examples
Expand Down Expand Up @@ -176,7 +179,8 @@ impl From<char> for u128 {
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<u8> for char {
/// Converts a [`u8`] into a [`char`].
///
/// # Examples
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,8 @@ where

// From (and thus Into) is reflexive
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<T> for T {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for T {
fn from(t: T) -> T {
t
}
Expand All @@ -560,7 +561,8 @@ impl<T> From<T> for T {
#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead.
#[rustc_reservation_impl = "permitting this impl would forbid us from adding \
`impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
impl<T> From<!> for T {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<!> for T {
fn from(t: !) -> T {
t
}
Expand Down Expand Up @@ -726,7 +728,8 @@ impl Ord for Infallible {
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl From<!> for Infallible {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<!> for Infallible {
fn from(x: !) -> Self {
x
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl<T: PartialEq> PartialEq for OnceCell<T> {
impl<T: Eq> Eq for OnceCell<T> {}

#[unstable(feature = "once_cell", issue = "74465")]
impl<T> From<T> for OnceCell<T> {
impl<T> const From<T> for OnceCell<T> {
fn from(value: T) -> Self {
OnceCell { inner: UnsafeCell::new(Some(value)) }
}
Expand Down
5 changes: 3 additions & 2 deletions library/core/src/num/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ impl fmt::Display for TryFromIntError {
}

#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<Infallible> for TryFromIntError {
fn from(x: Infallible) -> TryFromIntError {
match x {}
}
}

#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
impl const From<!> for TryFromIntError {
fn from(never: !) -> TryFromIntError {
// Match rather than coerce to make sure that code like
// `From<Infallible> for TryFromIntError` above will keep working
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ macro_rules! nonzero_integers {
}

#[stable(feature = "from_nonzero", since = "1.31.0")]
impl From<$Ty> for $Int {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<$Ty> for $Int {
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
#[inline]
fn from(nonzero: $Ty) -> Self {
Expand Down
11 changes: 7 additions & 4 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,8 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
}

#[stable(since = "1.12.0", feature = "option_from")]
impl<T> From<T> for Option<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for Option<T> {
/// Moves `val` into a new [`Some`].
///
/// # Examples
Expand All @@ -1739,7 +1740,8 @@ impl<T> From<T> for Option<T> {
}

#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<'a, T> const From<&'a Option<T>> for Option<&'a T> {
/// Converts from `&Option<T>` to `Option<&T>`.
///
/// # Examples
Expand All @@ -1766,7 +1768,8 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
}

#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<'a, T> const From<&'a mut Option<T>> for Option<&'a mut T> {
/// Converts from `&mut Option<T>` to `Option<&mut T>`
///
/// # Examples
Expand Down Expand Up @@ -2052,7 +2055,7 @@ impl<T> ops::Try for Option<T> {
}

#[unstable(feature = "try_trait_v2", issue = "84277")]
impl<T> ops::FromResidual for Option<T> {
impl<T> const ops::FromResidual for Option<T> {
#[inline]
fn from_residual(residual: Option<convert::Infallible>) -> Self {
match residual {
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,8 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
}

#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T: ?Sized> const From<Unique<T>> for NonNull<T> {
#[inline]
fn from(unique: Unique<T>) -> Self {
// SAFETY: A Unique pointer cannot be null, so the conditions for
Expand All @@ -708,7 +709,8 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
}

#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> From<&mut T> for NonNull<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T: ?Sized> const From<&mut T> for NonNull<T> {
#[inline]
fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null.
Expand All @@ -717,7 +719,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
}

#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> From<&T> for NonNull<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T: ?Sized> const From<&T> for NonNull<T> {
#[inline]
fn from(reference: &T) -> Self {
// SAFETY: A reference cannot be null, so the conditions for
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/unique.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
}

#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> From<&mut T> for Unique<T> {
impl<T: ?Sized> const From<&mut T> for Unique<T> {
#[inline]
fn from(reference: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,8 @@ impl<T> AtomicPtr<T> {

#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
impl From<bool> for AtomicBool {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<bool> for AtomicBool {
/// Converts a `bool` into an `AtomicBool`.
///
/// # Examples
Expand All @@ -1291,7 +1292,8 @@ impl From<bool> for AtomicBool {

#[cfg(target_has_atomic_load_store = "ptr")]
#[stable(feature = "atomic_from", since = "1.23.0")]
impl<T> From<*mut T> for AtomicPtr<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<*mut T> for AtomicPtr<T> {
#[inline]
fn from(p: *mut T) -> Self {
Self::new(p)
Expand Down Expand Up @@ -1363,7 +1365,8 @@ macro_rules! atomic_int {
}

#[$stable_from]
impl From<$int_type> for $atomic_type {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl const From<$int_type> for $atomic_type {
#[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
#[inline]
fn from(v: $int_type) -> Self { Self::new(v) }
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/task/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ impl<T, E> Poll<Option<Result<T, E>>> {
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<T> From<T> for Poll<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T> const From<T> for Poll<T> {
/// Convert to a `Ready` variant.
///
/// # Example
Expand Down
7 changes: 7 additions & 0 deletions library/core/tests/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,10 @@ fn atomic_compare_exchange() {
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
}

#[test]
fn atomic_const_from() {
const _ATOMIC_U8: AtomicU8 = AtomicU8::from(1);
const _ATOMIC_BOOL: AtomicBool = AtomicBool::from(true);
const _ATOMIC_PTR: AtomicPtr<u32> = AtomicPtr::from(core::ptr::null_mut());
}
9 changes: 9 additions & 0 deletions library/core/tests/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,4 +465,13 @@ fn const_cells() {

const CELL: Cell<i32> = Cell::new(3);
const _: i32 = CELL.into_inner();

const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3);
const _: i32 = UNSAFE_CELL.into_inner();

const REF_CELL_FROM: RefCell<i32> = RefCell::from(3);
const _: i32 = REF_CELL.into_inner();

const CELL_FROM: Cell<i32> = Cell::from(3);
const _: i32 = CELL.into_inner();
}
12 changes: 12 additions & 0 deletions library/core/tests/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{char, str};
#[test]
fn test_convert() {
assert_eq!(u32::from('a'), 0x61);
assert_eq!(u64::from('b'), 0x62);
assert_eq!(u128::from('c'), 0x63);
assert_eq!(char::from(b'\0'), '\0');
assert_eq!(char::from(b'a'), 'a');
assert_eq!(char::from(b'\xFF'), '\u{FF}');
Expand All @@ -19,6 +21,16 @@ fn test_convert() {
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
}

#[test]
const fn test_convert_const() {
assert!(u32::from('a') == 0x61);
assert!(u64::from('b') == 0x62);
assert!(u128::from('c') == 0x63);
assert!(char::from(b'\0') == '\0');
assert!(char::from(b'a') == 'a');
assert!(char::from(b'\xFF') == '\u{FF}');
}

#[test]
fn test_from_str() {
assert_eq!(char::from_str("a").unwrap(), 'a');
Expand Down
6 changes: 6 additions & 0 deletions library/core/tests/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ fn unsync_once_cell_drop_empty() {
drop(x);
}

#[test]
const fn once_cell_const() {
let _once_cell: OnceCell<u32> = OnceCell::new();
let _once_cell: OnceCell<u32> = OnceCell::from(32);
}

#[test]
fn clone() {
let s = OnceCell::new();
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(cfg_target_has_atomic)]
#![feature(const_assume)]
#![feature(const_cell_into_inner)]
#![feature(const_convert)]
#![feature(const_maybe_uninit_assume_init)]
#![cfg_attr(bootstrap, feature(const_panic))]
#![feature(const_ptr_read)]
Expand Down
3 changes: 3 additions & 0 deletions library/core/tests/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ fn nonzero_const() {

const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
assert!(ONE.is_some());

const FROM_NONZERO: u8 = u8::from(NONZERO);
assert_eq!(FROM_NONZERO, 5);
}

#[test]
Expand Down
15 changes: 15 additions & 0 deletions library/core/tests/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,17 @@ fn option_const() {
// test that the methods of `Option` are usable in a const context

const OPTION: Option<usize> = Some(32);
assert_eq!(OPTION, Some(32));

const OPTION_FROM: Option<usize> = Option::from(32);
assert_eq!(OPTION_FROM, Some(32));

const REF: Option<&usize> = OPTION.as_ref();
assert_eq!(REF, Some(&32));

const REF_FROM: Option<&usize> = Option::from(&OPTION);
assert_eq!(REF_FROM, Some(&32));

const IS_SOME: bool = OPTION.is_some();
assert!(IS_SOME);

Expand All @@ -388,6 +395,14 @@ const fn option_const_mut() {
None => unreachable!(),
}
}

{
let as_mut: Option<&mut usize> = Option::from(&mut option);
match as_mut {
Some(v) => *v = 42,
None => unreachable!(),
}
}
}

#[test]
Expand Down