Add blanket TryFrom impl when From is implemented.
Adds `impl<T, U> TryFrom<T> for U where U: From<T>`. Removes `impl<'a, T> TryFrom<&'a str> for T where T: FromStr` due to overlapping impls caused by the new blanket impl. This removal is to be discussed further on the tracking issue for TryFrom. Refs #33417.
This commit is contained in:
parent
c11f689d24
commit
80e3f8941d
4 changed files with 42 additions and 44 deletions
|
|
@ -48,7 +48,24 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use str::FromStr;
|
||||
use fmt;
|
||||
|
||||
/// An uninhabited type used as the error type for implementations of fallible
|
||||
/// conversion traits in cases where they cannot actually fail.
|
||||
///
|
||||
/// Because `Infallible` has no constructors (variants), a value of this type
|
||||
/// can never exist. It is used only to satisfy trait signatures that expect
|
||||
/// an error type, and signals to both the compiler and the user that the error
|
||||
/// case is impossible.
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
pub enum Infallible {}
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl fmt::Debug for Infallible {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {}
|
||||
}
|
||||
}
|
||||
|
||||
/// A cheap reference-to-reference conversion. Used to convert a value to a
|
||||
/// reference value within generic code.
|
||||
|
|
@ -417,6 +434,17 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
|
|||
}
|
||||
}
|
||||
|
||||
// Infallible conversions are semantically equivalent to fallible conversions
|
||||
// with an uninhabited error type.
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl<T, U> TryFrom<U> for T where T: From<U> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn try_from(value: U) -> Result<Self, Self::Error> {
|
||||
Ok(T::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// CONCRETE IMPLS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -442,14 +470,3 @@ impl AsRef<str> for str {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
// FromStr implies TryFrom<&str>
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl<'a, T> TryFrom<&'a str> for T where T: FromStr
|
||||
{
|
||||
type Error = <T as FromStr>::Err;
|
||||
|
||||
fn try_from(s: &'a str) -> Result<T, Self::Error> {
|
||||
FromStr::from_str(s)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ macro_rules! step_impl_unsigned {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unreachable_patterns)]
|
||||
fn add_usize(&self, n: usize) -> Option<Self> {
|
||||
match <$t>::try_from(n) {
|
||||
Ok(n_as_t) => self.checked_add(n_as_t),
|
||||
|
|
@ -120,6 +121,7 @@ macro_rules! step_impl_signed {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unreachable_patterns)]
|
||||
fn add_usize(&self, n: usize) -> Option<Self> {
|
||||
match <$unsigned>::try_from(n) {
|
||||
Ok(n_as_unsigned) => {
|
||||
|
|
|
|||
|
|
@ -2507,12 +2507,10 @@ impl fmt::Display for TryFromIntError {
|
|||
macro_rules! try_from_unbounded {
|
||||
($source:ty, $($target:ty),*) => {$(
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$source> for $target {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
impl From<$source> for $target {
|
||||
#[inline]
|
||||
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
|
||||
Ok(u as $target)
|
||||
fn from(value: $source) -> $target {
|
||||
value as $target
|
||||
}
|
||||
}
|
||||
)*}
|
||||
|
|
@ -2584,31 +2582,17 @@ macro_rules! rev {
|
|||
}
|
||||
|
||||
/// intra-sign conversions
|
||||
try_from_unbounded!(u8, u8, u16, u32, u64, u128);
|
||||
try_from_unbounded!(u16, u16, u32, u64, u128);
|
||||
try_from_unbounded!(u32, u32, u64, u128);
|
||||
try_from_unbounded!(u64, u64, u128);
|
||||
try_from_unbounded!(u128, u128);
|
||||
try_from_upper_bounded!(u16, u8);
|
||||
try_from_upper_bounded!(u32, u16, u8);
|
||||
try_from_upper_bounded!(u64, u32, u16, u8);
|
||||
try_from_upper_bounded!(u128, u64, u32, u16, u8);
|
||||
|
||||
try_from_unbounded!(i8, i8, i16, i32, i64, i128);
|
||||
try_from_unbounded!(i16, i16, i32, i64, i128);
|
||||
try_from_unbounded!(i32, i32, i64, i128);
|
||||
try_from_unbounded!(i64, i64, i128);
|
||||
try_from_unbounded!(i128, i128);
|
||||
try_from_both_bounded!(i16, i8);
|
||||
try_from_both_bounded!(i32, i16, i8);
|
||||
try_from_both_bounded!(i64, i32, i16, i8);
|
||||
try_from_both_bounded!(i128, i64, i32, i16, i8);
|
||||
|
||||
// unsigned-to-signed
|
||||
try_from_unbounded!(u8, i16, i32, i64, i128);
|
||||
try_from_unbounded!(u16, i32, i64, i128);
|
||||
try_from_unbounded!(u32, i64, i128);
|
||||
try_from_unbounded!(u64, i128);
|
||||
try_from_upper_bounded!(u8, i8);
|
||||
try_from_upper_bounded!(u16, i8, i16);
|
||||
try_from_upper_bounded!(u32, i8, i16, i32);
|
||||
|
|
@ -2627,10 +2611,8 @@ try_from_both_bounded!(i64, u32, u16, u8);
|
|||
try_from_both_bounded!(i128, u64, u32, u16, u8);
|
||||
|
||||
// usize/isize
|
||||
try_from_unbounded!(usize, usize);
|
||||
try_from_upper_bounded!(usize, isize);
|
||||
try_from_lower_bounded!(isize, usize);
|
||||
try_from_unbounded!(isize, isize);
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
mod ptr_try_from_impls {
|
||||
|
|
@ -2647,14 +2629,14 @@ mod ptr_try_from_impls {
|
|||
try_from_both_bounded!(isize, i8);
|
||||
try_from_unbounded!(isize, i16, i32, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16);
|
||||
rev!(try_from_unbounded, usize, u16);
|
||||
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_unbounded, isize, u8);
|
||||
rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16);
|
||||
rev!(try_from_unbounded, isize, i16);
|
||||
rev!(try_from_both_bounded, isize, i32, i64, i128);
|
||||
}
|
||||
|
||||
|
|
@ -2673,14 +2655,14 @@ mod ptr_try_from_impls {
|
|||
try_from_both_bounded!(isize, i8, i16);
|
||||
try_from_unbounded!(isize, i32, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16, u32);
|
||||
rev!(try_from_unbounded, usize, u16, 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, u8, u16);
|
||||
rev!(try_from_upper_bounded, isize, u32, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16, i32);
|
||||
rev!(try_from_unbounded, isize, i16, i32);
|
||||
rev!(try_from_both_bounded, isize, i64, i128);
|
||||
}
|
||||
|
||||
|
|
@ -2699,14 +2681,14 @@ mod ptr_try_from_impls {
|
|||
try_from_both_bounded!(isize, i8, i16, i32);
|
||||
try_from_unbounded!(isize, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16, u32, u64);
|
||||
rev!(try_from_unbounded, usize, u16, 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, u8, u16, u32);
|
||||
rev!(try_from_upper_bounded, isize, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16, i32, i64);
|
||||
rev!(try_from_unbounded, isize, i16, i32, i64);
|
||||
rev!(try_from_both_bounded, isize, i128);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ use self::pattern::Pattern;
|
|||
use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
||||
|
||||
use char;
|
||||
use convert::TryFrom;
|
||||
use fmt;
|
||||
use iter::{Map, Cloned, FusedIterator};
|
||||
use slice::{self, SliceIndex};
|
||||
|
|
@ -2142,7 +2141,7 @@ pub trait StrExt {
|
|||
#[stable(feature = "core", since = "1.6.0")]
|
||||
fn is_empty(&self) -> bool;
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
fn parse<'a, T: TryFrom<&'a str>>(&'a self) -> Result<T, T::Error>;
|
||||
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
|
||||
}
|
||||
|
||||
// truncate `&str` to length at most equal to `max`
|
||||
|
|
@ -2462,9 +2461,7 @@ impl StrExt for str {
|
|||
fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
#[inline]
|
||||
fn parse<'a, T>(&'a self) -> Result<T, T::Error> where T: TryFrom<&'a str> {
|
||||
T::try_from(self)
|
||||
}
|
||||
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue