15
15
16
16
use char:: CharExt ;
17
17
use cmp:: PartialOrd ;
18
- use convert:: From ;
18
+ use convert:: { From , TryFrom } ;
19
19
use fmt;
20
20
use intrinsics;
21
21
use marker:: { Copy , Sized } ;
@@ -2341,9 +2341,101 @@ macro_rules! from_str_radix_int_impl {
2341
2341
}
2342
2342
from_str_radix_int_impl ! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 }
2343
2343
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
+
2344
2435
#[ doc( hidden) ]
2345
2436
trait FromStrRadixHelper : PartialOrd + Copy {
2346
2437
fn min_value ( ) -> Self ;
2438
+ fn max_value ( ) -> Self ;
2347
2439
fn from_u32 ( u : u32 ) -> Self ;
2348
2440
fn checked_mul ( & self , other : u32 ) -> Option < Self > ;
2349
2441
fn checked_sub ( & self , other : u32 ) -> Option < Self > ;
@@ -2353,6 +2445,7 @@ trait FromStrRadixHelper: PartialOrd + Copy {
2353
2445
macro_rules! doit {
2354
2446
( $( $t: ty) * ) => ( $( impl FromStrRadixHelper for $t {
2355
2447
fn min_value( ) -> Self { Self :: min_value( ) }
2448
+ fn max_value( ) -> Self { Self :: max_value( ) }
2356
2449
fn from_u32( u: u32 ) -> Self { u as Self }
2357
2450
fn checked_mul( & self , other: u32 ) -> Option <Self > {
2358
2451
Self :: checked_mul( * self , other as Self )
0 commit comments