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