1515
1616use char:: CharExt ;
1717use cmp:: PartialOrd ;
18- use convert:: From ;
18+ use convert:: { From , TryFrom } ;
1919use fmt;
2020use intrinsics;
2121use marker:: { Copy , Sized } ;
@@ -2341,9 +2341,101 @@ macro_rules! from_str_radix_int_impl {
23412341}
23422342from_str_radix_int_impl ! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 }
23432343
2344+ /// The error type returned when a checked integral type conversion fails.
2345+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2346+ #[ derive( Debug , Copy , Clone ) ]
2347+ pub struct TryFromIntError ( ( ) ) ;
2348+
2349+ impl TryFromIntError {
2350+ #[ unstable( feature = "int_error_internals" ,
2351+ reason = "available through Error trait and this method should \
2352+ not be exposed publicly",
2353+ issue = "0" ) ]
2354+ #[ doc( hidden) ]
2355+ pub fn __description ( & self ) -> & str {
2356+ "out of range integral type conversion attempted"
2357+ }
2358+ }
2359+
2360+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2361+ impl fmt:: Display for TryFromIntError {
2362+ fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
2363+ self . __description ( ) . fmt ( fmt)
2364+ }
2365+ }
2366+
2367+ macro_rules! same_sign_from_int_impl {
2368+ ( $storage: ty, $target: ty, $( $source: ty) ,* ) => { $(
2369+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
2370+ impl TryFrom <$source> for $target {
2371+ type Err = TryFromIntError ;
2372+
2373+ fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2374+ let min = <$target as FromStrRadixHelper >:: min_value( ) as $storage;
2375+ let max = <$target as FromStrRadixHelper >:: max_value( ) as $storage;
2376+ if u as $storage < min || u as $storage > max {
2377+ Err ( TryFromIntError ( ( ) ) )
2378+ } else {
2379+ Ok ( u as $target)
2380+ }
2381+ }
2382+ }
2383+ ) * }
2384+ }
2385+
2386+ same_sign_from_int_impl ! ( u64 , u8 , u8 , u16 , u32 , u64 , usize ) ;
2387+ same_sign_from_int_impl ! ( i64 , i8 , i8 , i16 , i32 , i64 , isize ) ;
2388+ same_sign_from_int_impl ! ( u64 , u16 , u8 , u16 , u32 , u64 , usize ) ;
2389+ same_sign_from_int_impl ! ( i64 , i16 , i8 , i16 , i32 , i64 , isize ) ;
2390+ same_sign_from_int_impl ! ( u64 , u32 , u8 , u16 , u32 , u64 , usize ) ;
2391+ same_sign_from_int_impl ! ( i64 , i32 , i8 , i16 , i32 , i64 , isize ) ;
2392+ same_sign_from_int_impl ! ( u64 , u64 , u8 , u16 , u32 , u64 , usize ) ;
2393+ same_sign_from_int_impl ! ( i64 , i64 , i8 , i16 , i32 , i64 , isize ) ;
2394+ same_sign_from_int_impl ! ( u64 , usize , u8 , u16 , u32 , u64 , usize ) ;
2395+ same_sign_from_int_impl ! ( i64 , isize , i8 , i16 , i32 , i64 , isize ) ;
2396+
2397+ macro_rules! cross_sign_from_int_impl {
2398+ ( $unsigned: ty, $( $signed: ty) ,* ) => { $(
2399+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
2400+ impl TryFrom <$unsigned> for $signed {
2401+ type Err = TryFromIntError ;
2402+
2403+ fn try_from( u: $unsigned) -> Result <$signed, TryFromIntError > {
2404+ let max = <$signed as FromStrRadixHelper >:: max_value( ) as u64 ;
2405+ if u as u64 > max {
2406+ Err ( TryFromIntError ( ( ) ) )
2407+ } else {
2408+ Ok ( u as $signed)
2409+ }
2410+ }
2411+ }
2412+
2413+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
2414+ impl TryFrom <$signed> for $unsigned {
2415+ type Err = TryFromIntError ;
2416+
2417+ fn try_from( u: $signed) -> Result <$unsigned, TryFromIntError > {
2418+ let max = <$unsigned as FromStrRadixHelper >:: max_value( ) as u64 ;
2419+ if u < 0 || u as u64 > max {
2420+ Err ( TryFromIntError ( ( ) ) )
2421+ } else {
2422+ Ok ( u as $unsigned)
2423+ }
2424+ }
2425+ }
2426+ ) * }
2427+ }
2428+
2429+ cross_sign_from_int_impl ! ( u8 , i8 , i16 , i32 , i64 , isize ) ;
2430+ cross_sign_from_int_impl ! ( u16 , i8 , i16 , i32 , i64 , isize ) ;
2431+ cross_sign_from_int_impl ! ( u32 , i8 , i16 , i32 , i64 , isize ) ;
2432+ cross_sign_from_int_impl ! ( u64 , i8 , i16 , i32 , i64 , isize ) ;
2433+ cross_sign_from_int_impl ! ( usize , i8 , i16 , i32 , i64 , isize ) ;
2434+
23442435#[ doc( hidden) ]
23452436trait FromStrRadixHelper : PartialOrd + Copy {
23462437 fn min_value ( ) -> Self ;
2438+ fn max_value ( ) -> Self ;
23472439 fn from_u32 ( u : u32 ) -> Self ;
23482440 fn checked_mul ( & self , other : u32 ) -> Option < Self > ;
23492441 fn checked_sub ( & self , other : u32 ) -> Option < Self > ;
@@ -2353,6 +2445,7 @@ trait FromStrRadixHelper: PartialOrd + Copy {
23532445macro_rules! doit {
23542446 ( $( $t: ty) * ) => ( $( impl FromStrRadixHelper for $t {
23552447 fn min_value( ) -> Self { Self :: min_value( ) }
2448+ fn max_value( ) -> Self { Self :: max_value( ) }
23562449 fn from_u32( u: u32 ) -> Self { u as Self }
23572450 fn checked_mul( & self , other: u32 ) -> Option <Self > {
23582451 Self :: checked_mul( * self , other as Self )
0 commit comments