Skip to content

Commit

Permalink
Remove TryFrom impls that might become conditionally-infallible with …
Browse files Browse the repository at this point in the history
…a portability lint

rust-lang#49305 (comment)
  • Loading branch information
SimonSapin committed Mar 27, 2018
1 parent 09008cc commit 837d6c7
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 191 deletions.
74 changes: 72 additions & 2 deletions src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ macro_rules! step_impl_unsigned {
#[inline]
#[allow(unreachable_patterns)]
fn add_usize(&self, n: usize) -> Option<Self> {
match <$t>::try_from(n) {
match <$t>::private_try_from(n) {
Ok(n_as_t) => self.checked_add(n_as_t),
Err(_) => None,
}
Expand Down Expand Up @@ -123,7 +123,7 @@ macro_rules! step_impl_signed {
#[inline]
#[allow(unreachable_patterns)]
fn add_usize(&self, n: usize) -> Option<Self> {
match <$unsigned>::try_from(n) {
match <$unsigned>::private_try_from(n) {
Ok(n_as_unsigned) => {
// Wrapping in unsigned space handles cases like
// `-120_i8.add_usize(200) == Some(80_i8)`,
Expand Down Expand Up @@ -461,3 +461,73 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {

#[stable(feature = "fused", since = "1.26.0")]
impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}

/// Compensate removal of some impls per
/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
trait PrivateTryFromUsize: Sized {
fn private_try_from(n: usize) -> Result<Self, ()>;
}

impl<T> PrivateTryFromUsize for T where T: TryFrom<usize> {
#[inline]
fn private_try_from(n: usize) -> Result<Self, ()> {
T::try_from(n).map_err(|_| ())
}
}

// no possible bounds violation
macro_rules! try_from_unbounded {
($($target:ty),*) => {$(
impl PrivateTryFromUsize for $target {
#[inline]
fn private_try_from(value: usize) -> Result<Self, ()> {
Ok(value as $target)
}
}
)*}
}

// unsigned to signed (only positive bound)
macro_rules! try_from_upper_bounded {
($($target:ty),*) => {$(
impl PrivateTryFromUsize for $target {
#[inline]
fn private_try_from(u: usize) -> Result<$target, ()> {
if u > (<$target>::max_value() as usize) {
Err(())
} else {
Ok(u as $target)
}
}
}
)*}
}


#[cfg(target_pointer_width = "16")]
mod ptr_try_from_impls {
use super::PrivateTryFromUsize;

try_from_unbounded!(u16, u32, u64, u128);
try_from_unbounded!(i32, i64, i128);
}

#[cfg(target_pointer_width = "32")]
mod ptr_try_from_impls {
use super::PrivateTryFromUsize;

try_from_upper_bounded!(u16);
try_from_unbounded!(u32, u64, u128);
try_from_upper_bounded!(i32);
try_from_unbounded!(i64, i128);
}

#[cfg(target_pointer_width = "64")]
mod ptr_try_from_impls {
use super::PrivateTryFromUsize;

try_from_upper_bounded!(u16, u32);
try_from_unbounded!(u64, u128);
try_from_upper_bounded!(i32, i64);
try_from_unbounded!(i128);
}
70 changes: 10 additions & 60 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3676,21 +3676,6 @@ impl From<!> for TryFromIntError {
}
}

// no possible bounds violation
macro_rules! try_from_unbounded {
($source:ty, $($target:ty),*) => {$(
#[stable(feature = "try_from", since = "1.26.0")]
impl TryFrom<$source> for $target {
type Error = TryFromIntError;

#[inline]
fn try_from(value: $source) -> Result<Self, Self::Error> {
Ok(value as $target)
}
}
)*}
}

// only negative bounds
macro_rules! try_from_lower_bounded {
($source:ty, $($target:ty),*) => {$(
Expand Down Expand Up @@ -3789,79 +3774,44 @@ try_from_both_bounded!(i128, u64, u32, u16, u8);
try_from_upper_bounded!(usize, isize);
try_from_lower_bounded!(isize, usize);

try_from_upper_bounded!(usize, u8);
try_from_upper_bounded!(usize, i8, i16);
try_from_both_bounded!(isize, u8);
try_from_both_bounded!(isize, i8);

#[cfg(target_pointer_width = "16")]
mod ptr_try_from_impls {
use super::TryFromIntError;
use convert::TryFrom;

try_from_upper_bounded!(usize, u8);
try_from_unbounded!(usize, u16, u32, u64, u128);
try_from_upper_bounded!(usize, i8, i16);
try_from_unbounded!(usize, i32, i64, i128);

try_from_both_bounded!(isize, u8);
// Fallible across platfoms, only implementation differs
try_from_lower_bounded!(isize, u16, u32, u64, u128);
try_from_both_bounded!(isize, i8);
try_from_unbounded!(isize, i16, i32, i64, i128);

rev!(try_from_upper_bounded, usize, u32, u64, u128);
rev!(try_from_lower_bounded, usize, i8, i16);
rev!(try_from_both_bounded, usize, i32, i64, i128);

rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
rev!(try_from_both_bounded, isize, i32, i64, i128);
}

#[cfg(target_pointer_width = "32")]
mod ptr_try_from_impls {
use super::TryFromIntError;
use convert::TryFrom;

try_from_upper_bounded!(usize, u8, u16);
try_from_unbounded!(usize, u32, u64, u128);
try_from_upper_bounded!(usize, i8, i16, i32);
try_from_unbounded!(usize, i64, i128);

try_from_both_bounded!(isize, u8, u16);
// Fallible across platfoms, only implementation differs
try_from_both_bounded!(isize, u16);
try_from_lower_bounded!(isize, u32, u64, u128);
try_from_both_bounded!(isize, i8, i16);
try_from_unbounded!(isize, i32, i64, i128);

rev!(try_from_unbounded, usize, u32);
rev!(try_from_upper_bounded, usize, u64, u128);
rev!(try_from_lower_bounded, usize, i8, i16, i32);
rev!(try_from_both_bounded, usize, i64, i128);

rev!(try_from_unbounded, isize, u16);
rev!(try_from_upper_bounded, isize, u32, u64, u128);
rev!(try_from_unbounded, isize, i32);
rev!(try_from_both_bounded, isize, i64, i128);
}

#[cfg(target_pointer_width = "64")]
mod ptr_try_from_impls {
use super::TryFromIntError;
use convert::TryFrom;

try_from_upper_bounded!(usize, u8, u16, u32);
try_from_unbounded!(usize, u64, u128);
try_from_upper_bounded!(usize, i8, i16, i32, i64);
try_from_unbounded!(usize, i128);

try_from_both_bounded!(isize, u8, u16, u32);
// Fallible across platfoms, only implementation differs
try_from_both_bounded!(isize, u16, u32);
try_from_lower_bounded!(isize, u64, u128);
try_from_both_bounded!(isize, i8, i16, i32);
try_from_unbounded!(isize, i64, i128);

rev!(try_from_unbounded, usize, u32, u64);
rev!(try_from_upper_bounded, usize, u128);
rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
rev!(try_from_both_bounded, usize, i128);

rev!(try_from_unbounded, isize, u16, u32);
rev!(try_from_upper_bounded, isize, u64, u128);
rev!(try_from_unbounded, isize, i32, i64);
rev!(try_from_both_bounded, isize, i128);
}

#[doc(hidden)]
Expand Down
127 changes: 0 additions & 127 deletions src/libcore/tests/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ mod flt2dec;
mod dec2flt;
mod bignum;


/// Adds the attribute to all items in the block.
macro_rules! cfg_block {
($(#[$attr:meta]{$($it:item)*})*) => {$($(
#[$attr]
$it
)*)*}
}

/// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
/// support for larger/smaller pointer widths are added in the future.
macro_rules! assume_usize_width {
Expand Down Expand Up @@ -318,42 +309,6 @@ assume_usize_width! {

test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }

test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }

test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }

cfg_block!(
#[cfg(target_pointer_width = "16")] {
test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 }
test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 }
test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 }
test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
}

#[cfg(target_pointer_width = "32")] {
test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
}

#[cfg(target_pointer_width = "64")] {
test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
test_impl_try_from_always_ok! { test_try_u32isize, u32, isize }
test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
}
);
}

/// Conversions where max of $source can be represented as $target,
Expand Down Expand Up @@ -402,24 +357,6 @@ assume_usize_width! {
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }

cfg_block!(
#[cfg(target_pointer_width = "16")] {
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
}

#[cfg(target_pointer_width = "32")] {
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }

test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
}

#[cfg(target_pointer_width = "64")] {
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
}
);
}

/// Conversions where max of $source can not be represented as $target,
Expand Down Expand Up @@ -461,29 +398,9 @@ test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }

assume_usize_width! {
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }

test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }

cfg_block!(
#[cfg(target_pointer_width = "16")] {
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
}

#[cfg(target_pointer_width = "32")] {
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
}

#[cfg(target_pointer_width = "64")] {
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
}
);
}

/// Conversions where min/max of $source can not be represented as $target.
Expand Down Expand Up @@ -543,34 +460,6 @@ test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 }

assume_usize_width! {
test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }

cfg_block!(
#[cfg(target_pointer_width = "16")] {
test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }

test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
}

#[cfg(target_pointer_width = "32")] {
test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }

test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
}

#[cfg(target_pointer_width = "64")] {
test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }

test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
}
);
}

/// Conversions where neither the min nor the max of $source can be represented by
Expand Down Expand Up @@ -615,22 +504,6 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
assume_usize_width! {
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }

cfg_block! {
#[cfg(target_pointer_width = "16")] {
test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
}
#[cfg(target_pointer_width = "32")] {
test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }

test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
}
#[cfg(target_pointer_width = "64")] {
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
}
}
}

macro_rules! test_float {
Expand Down
Loading

0 comments on commit 837d6c7

Please sign in to comment.