Skip to content

Commit 80e3f89

Browse files
committed
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.
1 parent c11f689 commit 80e3f89

File tree

4 files changed

+42
-44
lines changed

4 files changed

+42
-44
lines changed

src/libcore/convert.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,24 @@
4848
4949
#![stable(feature = "rust1", since = "1.0.0")]
5050

51-
use str::FromStr;
51+
use fmt;
52+
53+
/// An uninhabited type used as the error type for implementations of fallible
54+
/// conversion traits in cases where they cannot actually fail.
55+
///
56+
/// Because `Infallible` has no constructors (variants), a value of this type
57+
/// can never exist. It is used only to satisfy trait signatures that expect
58+
/// an error type, and signals to both the compiler and the user that the error
59+
/// case is impossible.
60+
#[unstable(feature = "try_from", issue = "33417")]
61+
pub enum Infallible {}
62+
63+
#[unstable(feature = "try_from", issue = "33417")]
64+
impl fmt::Debug for Infallible {
65+
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
66+
match *self {}
67+
}
68+
}
5269

5370
/// A cheap reference-to-reference conversion. Used to convert a value to a
5471
/// reference value within generic code.
@@ -417,6 +434,17 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
417434
}
418435
}
419436

437+
// Infallible conversions are semantically equivalent to fallible conversions
438+
// with an uninhabited error type.
439+
#[unstable(feature = "try_from", issue = "33417")]
440+
impl<T, U> TryFrom<U> for T where T: From<U> {
441+
type Error = Infallible;
442+
443+
fn try_from(value: U) -> Result<Self, Self::Error> {
444+
Ok(T::from(value))
445+
}
446+
}
447+
420448
////////////////////////////////////////////////////////////////////////////////
421449
// CONCRETE IMPLS
422450
////////////////////////////////////////////////////////////////////////////////
@@ -442,14 +470,3 @@ impl AsRef<str> for str {
442470
self
443471
}
444472
}
445-
446-
// FromStr implies TryFrom<&str>
447-
#[unstable(feature = "try_from", issue = "33417")]
448-
impl<'a, T> TryFrom<&'a str> for T where T: FromStr
449-
{
450-
type Error = <T as FromStr>::Err;
451-
452-
fn try_from(s: &'a str) -> Result<T, Self::Error> {
453-
FromStr::from_str(s)
454-
}
455-
}

src/libcore/iter/range.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ macro_rules! step_impl_unsigned {
8989
}
9090

9191
#[inline]
92+
#[allow(unreachable_patterns)]
9293
fn add_usize(&self, n: usize) -> Option<Self> {
9394
match <$t>::try_from(n) {
9495
Ok(n_as_t) => self.checked_add(n_as_t),
@@ -120,6 +121,7 @@ macro_rules! step_impl_signed {
120121
}
121122

122123
#[inline]
124+
#[allow(unreachable_patterns)]
123125
fn add_usize(&self, n: usize) -> Option<Self> {
124126
match <$unsigned>::try_from(n) {
125127
Ok(n_as_unsigned) => {

src/libcore/num/mod.rs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,12 +2507,10 @@ impl fmt::Display for TryFromIntError {
25072507
macro_rules! try_from_unbounded {
25082508
($source:ty, $($target:ty),*) => {$(
25092509
#[unstable(feature = "try_from", issue = "33417")]
2510-
impl TryFrom<$source> for $target {
2511-
type Error = TryFromIntError;
2512-
2510+
impl From<$source> for $target {
25132511
#[inline]
2514-
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
2515-
Ok(u as $target)
2512+
fn from(value: $source) -> $target {
2513+
value as $target
25162514
}
25172515
}
25182516
)*}
@@ -2584,31 +2582,17 @@ macro_rules! rev {
25842582
}
25852583

25862584
/// intra-sign conversions
2587-
try_from_unbounded!(u8, u8, u16, u32, u64, u128);
2588-
try_from_unbounded!(u16, u16, u32, u64, u128);
2589-
try_from_unbounded!(u32, u32, u64, u128);
2590-
try_from_unbounded!(u64, u64, u128);
2591-
try_from_unbounded!(u128, u128);
25922585
try_from_upper_bounded!(u16, u8);
25932586
try_from_upper_bounded!(u32, u16, u8);
25942587
try_from_upper_bounded!(u64, u32, u16, u8);
25952588
try_from_upper_bounded!(u128, u64, u32, u16, u8);
25962589

2597-
try_from_unbounded!(i8, i8, i16, i32, i64, i128);
2598-
try_from_unbounded!(i16, i16, i32, i64, i128);
2599-
try_from_unbounded!(i32, i32, i64, i128);
2600-
try_from_unbounded!(i64, i64, i128);
2601-
try_from_unbounded!(i128, i128);
26022590
try_from_both_bounded!(i16, i8);
26032591
try_from_both_bounded!(i32, i16, i8);
26042592
try_from_both_bounded!(i64, i32, i16, i8);
26052593
try_from_both_bounded!(i128, i64, i32, i16, i8);
26062594

26072595
// unsigned-to-signed
2608-
try_from_unbounded!(u8, i16, i32, i64, i128);
2609-
try_from_unbounded!(u16, i32, i64, i128);
2610-
try_from_unbounded!(u32, i64, i128);
2611-
try_from_unbounded!(u64, i128);
26122596
try_from_upper_bounded!(u8, i8);
26132597
try_from_upper_bounded!(u16, i8, i16);
26142598
try_from_upper_bounded!(u32, i8, i16, i32);
@@ -2627,10 +2611,8 @@ try_from_both_bounded!(i64, u32, u16, u8);
26272611
try_from_both_bounded!(i128, u64, u32, u16, u8);
26282612

26292613
// usize/isize
2630-
try_from_unbounded!(usize, usize);
26312614
try_from_upper_bounded!(usize, isize);
26322615
try_from_lower_bounded!(isize, usize);
2633-
try_from_unbounded!(isize, isize);
26342616

26352617
#[cfg(target_pointer_width = "16")]
26362618
mod ptr_try_from_impls {
@@ -2647,14 +2629,14 @@ mod ptr_try_from_impls {
26472629
try_from_both_bounded!(isize, i8);
26482630
try_from_unbounded!(isize, i16, i32, i64, i128);
26492631

2650-
rev!(try_from_unbounded, usize, u8, u16);
2632+
rev!(try_from_unbounded, usize, u16);
26512633
rev!(try_from_upper_bounded, usize, u32, u64, u128);
26522634
rev!(try_from_lower_bounded, usize, i8, i16);
26532635
rev!(try_from_both_bounded, usize, i32, i64, i128);
26542636

26552637
rev!(try_from_unbounded, isize, u8);
26562638
rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
2657-
rev!(try_from_unbounded, isize, i8, i16);
2639+
rev!(try_from_unbounded, isize, i16);
26582640
rev!(try_from_both_bounded, isize, i32, i64, i128);
26592641
}
26602642

@@ -2673,14 +2655,14 @@ mod ptr_try_from_impls {
26732655
try_from_both_bounded!(isize, i8, i16);
26742656
try_from_unbounded!(isize, i32, i64, i128);
26752657

2676-
rev!(try_from_unbounded, usize, u8, u16, u32);
2658+
rev!(try_from_unbounded, usize, u16, u32);
26772659
rev!(try_from_upper_bounded, usize, u64, u128);
26782660
rev!(try_from_lower_bounded, usize, i8, i16, i32);
26792661
rev!(try_from_both_bounded, usize, i64, i128);
26802662

26812663
rev!(try_from_unbounded, isize, u8, u16);
26822664
rev!(try_from_upper_bounded, isize, u32, u64, u128);
2683-
rev!(try_from_unbounded, isize, i8, i16, i32);
2665+
rev!(try_from_unbounded, isize, i16, i32);
26842666
rev!(try_from_both_bounded, isize, i64, i128);
26852667
}
26862668

@@ -2699,14 +2681,14 @@ mod ptr_try_from_impls {
26992681
try_from_both_bounded!(isize, i8, i16, i32);
27002682
try_from_unbounded!(isize, i64, i128);
27012683

2702-
rev!(try_from_unbounded, usize, u8, u16, u32, u64);
2684+
rev!(try_from_unbounded, usize, u16, u32, u64);
27032685
rev!(try_from_upper_bounded, usize, u128);
27042686
rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
27052687
rev!(try_from_both_bounded, usize, i128);
27062688

27072689
rev!(try_from_unbounded, isize, u8, u16, u32);
27082690
rev!(try_from_upper_bounded, isize, u64, u128);
2709-
rev!(try_from_unbounded, isize, i8, i16, i32, i64);
2691+
rev!(try_from_unbounded, isize, i16, i32, i64);
27102692
rev!(try_from_both_bounded, isize, i128);
27112693
}
27122694

src/libcore/str/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use self::pattern::Pattern;
1818
use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
1919

2020
use char;
21-
use convert::TryFrom;
2221
use fmt;
2322
use iter::{Map, Cloned, FusedIterator};
2423
use slice::{self, SliceIndex};
@@ -2142,7 +2141,7 @@ pub trait StrExt {
21422141
#[stable(feature = "core", since = "1.6.0")]
21432142
fn is_empty(&self) -> bool;
21442143
#[stable(feature = "core", since = "1.6.0")]
2145-
fn parse<'a, T: TryFrom<&'a str>>(&'a self) -> Result<T, T::Error>;
2144+
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
21462145
}
21472146

21482147
// truncate `&str` to length at most equal to `max`
@@ -2462,9 +2461,7 @@ impl StrExt for str {
24622461
fn is_empty(&self) -> bool { self.len() == 0 }
24632462

24642463
#[inline]
2465-
fn parse<'a, T>(&'a self) -> Result<T, T::Error> where T: TryFrom<&'a str> {
2466-
T::try_from(self)
2467-
}
2464+
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
24682465
}
24692466

24702467
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)