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 } ;
@@ -2352,9 +2352,101 @@ macro_rules! from_str_radix_int_impl {
2352
2352
}
2353
2353
from_str_radix_int_impl ! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 }
2354
2354
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
+
2355
2446
#[ doc( hidden) ]
2356
2447
trait FromStrRadixHelper : PartialOrd + Copy {
2357
2448
fn min_value ( ) -> Self ;
2449
+ fn max_value ( ) -> Self ;
2358
2450
fn from_u32 ( u : u32 ) -> Self ;
2359
2451
fn checked_mul ( & self , other : u32 ) -> Option < Self > ;
2360
2452
fn checked_sub ( & self , other : u32 ) -> Option < Self > ;
@@ -2364,6 +2456,7 @@ trait FromStrRadixHelper: PartialOrd + Copy {
2364
2456
macro_rules! doit {
2365
2457
( $( $t: ty) * ) => ( $( impl FromStrRadixHelper for $t {
2366
2458
fn min_value( ) -> Self { Self :: min_value( ) }
2459
+ fn max_value( ) -> Self { Self :: max_value( ) }
2367
2460
fn from_u32( u: u32 ) -> Self { u as Self }
2368
2461
fn checked_mul( & self , other: u32 ) -> Option <Self > {
2369
2462
Self :: checked_mul( * self , other as Self )
0 commit comments