@@ -2504,76 +2504,209 @@ impl fmt::Display for TryFromIntError {
25042504 }
25052505}
25062506
2507- macro_rules! same_sign_try_from_int_impl {
2508- ( $storage: ty, $target: ty, $( $source: ty) ,* ) => { $(
2507+ // no possible bounds violation
2508+ macro_rules! try_from_unbounded {
2509+ ( $source: ty, $( $target: ty) ,* ) => { $(
25092510 #[ unstable( feature = "try_from" , issue = "33417" ) ]
25102511 impl TryFrom <$source> for $target {
25112512 type Error = TryFromIntError ;
25122513
2514+ #[ inline]
25132515 fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2514- let min = <$target as FromStrRadixHelper >:: min_value( ) as $storage;
2515- let max = <$target as FromStrRadixHelper >:: max_value( ) as $storage;
2516- if u as $storage < min || u as $storage > max {
2517- Err ( TryFromIntError ( ( ) ) )
2518- } else {
2516+ Ok ( u as $target)
2517+ }
2518+ }
2519+ ) * }
2520+ }
2521+
2522+ // only negative bounds
2523+ macro_rules! try_from_lower_bounded {
2524+ ( $source: ty, $( $target: ty) ,* ) => { $(
2525+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2526+ impl TryFrom <$source> for $target {
2527+ type Error = TryFromIntError ;
2528+
2529+ #[ inline]
2530+ fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2531+ if u >= 0 {
25192532 Ok ( u as $target)
2533+ } else {
2534+ Err ( TryFromIntError ( ( ) ) )
25202535 }
25212536 }
25222537 }
25232538 ) * }
25242539}
25252540
2526- same_sign_try_from_int_impl ! ( u128 , u8 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2527- same_sign_try_from_int_impl ! ( i128 , i8 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2528- same_sign_try_from_int_impl ! ( u128 , u16 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2529- same_sign_try_from_int_impl ! ( i128 , i16 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2530- same_sign_try_from_int_impl ! ( u128 , u32 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2531- same_sign_try_from_int_impl ! ( i128 , i32 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2532- same_sign_try_from_int_impl ! ( u128 , u64 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2533- same_sign_try_from_int_impl ! ( i128 , i64 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2534- same_sign_try_from_int_impl ! ( u128 , u128 , u8 , u16 , u32 , u64 , u128 , usize ) ;
2535- same_sign_try_from_int_impl ! ( i128 , i128 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2536- same_sign_try_from_int_impl ! ( u128 , usize , u8 , u16 , u32 , u64 , u128 , usize ) ;
2537- same_sign_try_from_int_impl ! ( i128 , isize , i8 , i16 , i32 , i64 , i128 , isize ) ;
2538-
2539- macro_rules! cross_sign_from_int_impl {
2540- ( $unsigned: ty, $( $signed: ty) ,* ) => { $(
2541+ // unsigned to signed (only positive bound)
2542+ macro_rules! try_from_upper_bounded {
2543+ ( $source: ty, $( $target: ty) ,* ) => { $(
25412544 #[ unstable( feature = "try_from" , issue = "33417" ) ]
2542- impl TryFrom <$unsigned > for $signed {
2545+ impl TryFrom <$source > for $target {
25432546 type Error = TryFromIntError ;
25442547
2545- fn try_from ( u : $unsigned ) -> Result <$signed , TryFromIntError > {
2546- let max = <$signed as FromStrRadixHelper > :: max_value ( ) as u128 ;
2547- if u as u128 > max {
2548+ # [ inline ]
2549+ fn try_from ( u : $source ) -> Result <$target , TryFromIntError > {
2550+ if u > ( <$target> :: max_value ( ) as $source ) {
25482551 Err ( TryFromIntError ( ( ) ) )
25492552 } else {
2550- Ok ( u as $signed )
2553+ Ok ( u as $target )
25512554 }
25522555 }
25532556 }
2557+ ) * }
2558+ }
25542559
2560+ // all other cases
2561+ macro_rules! try_from_both_bounded {
2562+ ( $source: ty, $( $target: ty) ,* ) => { $(
25552563 #[ unstable( feature = "try_from" , issue = "33417" ) ]
2556- impl TryFrom <$signed > for $unsigned {
2564+ impl TryFrom <$source > for $target {
25572565 type Error = TryFromIntError ;
25582566
2559- fn try_from( u: $signed) -> Result <$unsigned, TryFromIntError > {
2560- let max = <$unsigned as FromStrRadixHelper >:: max_value( ) as u128 ;
2561- if u < 0 || u as u128 > max {
2567+ #[ inline]
2568+ fn try_from( u: $source) -> Result <$target, TryFromIntError > {
2569+ let min = <$target>:: min_value( ) as $source;
2570+ let max = <$target>:: max_value( ) as $source;
2571+ if u < min || u > max {
25622572 Err ( TryFromIntError ( ( ) ) )
25632573 } else {
2564- Ok ( u as $unsigned )
2574+ Ok ( u as $target )
25652575 }
25662576 }
25672577 }
25682578 ) * }
25692579}
25702580
2571- cross_sign_from_int_impl ! ( u8 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2572- cross_sign_from_int_impl ! ( u16 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2573- cross_sign_from_int_impl ! ( u32 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2574- cross_sign_from_int_impl ! ( u64 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2575- cross_sign_from_int_impl ! ( u128 , i8 , i16 , i32 , i64 , i128 , isize ) ;
2576- cross_sign_from_int_impl ! ( usize , i8 , i16 , i32 , i64 , i128 , isize ) ;
2581+ macro_rules! rev {
2582+ ( $mac: ident, $source: ty, $( $target: ty) ,* ) => { $(
2583+ $mac!( $target, $source) ;
2584+ ) * }
2585+ }
2586+
2587+ /// intra-sign conversions
2588+ try_from_unbounded ! ( u8 , u8 , u16 , u32 , u64 , u128 ) ;
2589+ try_from_unbounded ! ( u16 , u16 , u32 , u64 , u128 ) ;
2590+ try_from_unbounded ! ( u32 , u32 , u64 , u128 ) ;
2591+ try_from_unbounded ! ( u64 , u64 , u128 ) ;
2592+ try_from_unbounded ! ( u128 , u128 ) ;
2593+ try_from_upper_bounded ! ( u16 , u8 ) ;
2594+ try_from_upper_bounded ! ( u32 , u16 , u8 ) ;
2595+ try_from_upper_bounded ! ( u64 , u32 , u16 , u8 ) ;
2596+ try_from_upper_bounded ! ( u128 , u64 , u32 , u16 , u8 ) ;
2597+
2598+ try_from_unbounded ! ( i8 , i8 , i16 , i32 , i64 , i128 ) ;
2599+ try_from_unbounded ! ( i16 , i16 , i32 , i64 , i128 ) ;
2600+ try_from_unbounded ! ( i32 , i32 , i64 , i128 ) ;
2601+ try_from_unbounded ! ( i64 , i64 , i128 ) ;
2602+ try_from_unbounded ! ( i128 , i128 ) ;
2603+ try_from_both_bounded ! ( i16 , i8 ) ;
2604+ try_from_both_bounded ! ( i32 , i16 , i8 ) ;
2605+ try_from_both_bounded ! ( i64 , i32 , i16 , i8 ) ;
2606+ try_from_both_bounded ! ( i128 , i64 , i32 , i16 , i8 ) ;
2607+
2608+ // unsigned-to-signed
2609+ try_from_unbounded ! ( u8 , i16 , i32 , i64 , i128 ) ;
2610+ try_from_unbounded ! ( u16 , i32 , i64 , i128 ) ;
2611+ try_from_unbounded ! ( u32 , i64 , i128 ) ;
2612+ try_from_unbounded ! ( u64 , i128 ) ;
2613+ try_from_upper_bounded ! ( u8 , i8 ) ;
2614+ try_from_upper_bounded ! ( u16 , i8 , i16 ) ;
2615+ try_from_upper_bounded ! ( u32 , i8 , i16 , i32 ) ;
2616+ try_from_upper_bounded ! ( u64 , i8 , i16 , i32 , i64 ) ;
2617+ try_from_upper_bounded ! ( u128 , i8 , i16 , i32 , i64 , i128 ) ;
2618+
2619+ // signed-to-unsigned
2620+ try_from_lower_bounded ! ( i8 , u8 , u16 , u32 , u64 , u128 ) ;
2621+ try_from_lower_bounded ! ( i16 , u16 , u32 , u64 , u128 ) ;
2622+ try_from_lower_bounded ! ( i32 , u32 , u64 , u128 ) ;
2623+ try_from_lower_bounded ! ( i64 , u64 , u128 ) ;
2624+ try_from_lower_bounded ! ( i128 , u128 ) ;
2625+ try_from_both_bounded ! ( i16 , u8 ) ;
2626+ try_from_both_bounded ! ( i32 , u16 , u8 ) ;
2627+ try_from_both_bounded ! ( i64 , u32 , u16 , u8 ) ;
2628+ try_from_both_bounded ! ( i128 , u64 , u32 , u16 , u8 ) ;
2629+
2630+ #[ unstable( feature = "try_from" , issue = "33417" ) ]
2631+ pub use self :: ptr_try_from_impls:: * ;
2632+
2633+ #[ cfg( target_pointer_width = "16" ) ]
2634+ mod ptr_try_from_impls {
2635+ use super :: TryFromIntError ;
2636+ use convert:: TryFrom ;
2637+
2638+ try_from_upper_bounded ! ( usize , u8 ) ;
2639+ try_from_unbounded ! ( usize , usize , u16 , u32 , u64 , u128 ) ;
2640+ try_from_upper_bounded ! ( usize , i8 , i16 , isize ) ;
2641+ try_from_unbounded ! ( usize , i32 , i64 , i128 ) ;
2642+
2643+ try_from_both_bounded ! ( isize , u8 ) ;
2644+ try_from_lower_bounded ! ( isize , usize , u16 , u32 , u64 , u128 ) ;
2645+ try_from_both_bounded ! ( isize , i8 ) ;
2646+ try_from_unbounded ! ( isize , i16 , i32 , i64 , i128 ) ;
2647+
2648+ rev ! ( try_from_unbounded, usize , u8 , u16 ) ;
2649+ rev ! ( try_from_upper_bounded, usize , u32 , u64 , u128 ) ;
2650+ rev ! ( try_from_lower_bounded, usize , i8 , i16 ) ;
2651+ rev ! ( try_from_both_bounded, usize , i32 , i64 , i128 ) ;
2652+
2653+ rev ! ( try_from_unbounded, isize , u8 ) ;
2654+ rev ! ( try_from_upper_bounded, isize , u16 , u32 , u64 , u128 ) ;
2655+ rev ! ( try_from_unbounded, isize , i8 , i16 ) ;
2656+ rev ! ( try_from_both_bounded, isize , i32 , i64 , i128 ) ;
2657+ }
2658+
2659+ #[ cfg( target_pointer_width = "32" ) ]
2660+ mod ptr_try_from_impls {
2661+ use super :: TryFromIntError ;
2662+ use convert:: TryFrom ;
2663+
2664+ try_from_upper_bounded ! ( usize , u8 , u16 ) ;
2665+ try_from_unbounded ! ( usize , usize , u32 , u64 , u128 ) ;
2666+ try_from_upper_bounded ! ( usize , i8 , i16 , i32 , isize ) ;
2667+ try_from_unbounded ! ( usize , i64 , i128 ) ;
2668+
2669+ try_from_both_bounded ! ( isize , u8 , u16 ) ;
2670+ try_from_lower_bounded ! ( isize , usize , u32 , u64 , u128 ) ;
2671+ try_from_both_bounded ! ( isize , i8 , i16 ) ;
2672+ try_from_unbounded ! ( isize , i32 , i64 , i128 ) ;
2673+
2674+ rev ! ( try_from_unbounded, usize , u8 , u16 , u32 ) ;
2675+ rev ! ( try_from_upper_bounded, usize , u64 , u128 ) ;
2676+ rev ! ( try_from_lower_bounded, usize , i8 , i16 , i32 ) ;
2677+ rev ! ( try_from_both_bounded, usize , i64 , i128 ) ;
2678+
2679+ rev ! ( try_from_unbounded, isize , u8 , u16 ) ;
2680+ rev ! ( try_from_upper_bounded, isize , u32 , u64 , u128 ) ;
2681+ rev ! ( try_from_unbounded, isize , i8 , i16 , i32 ) ;
2682+ rev ! ( try_from_both_bounded, isize , i64 , i128 ) ;
2683+ }
2684+
2685+ #[ cfg( target_pointer_width = "64" ) ]
2686+ mod ptr_try_from_impls {
2687+ use super :: TryFromIntError ;
2688+ use convert:: TryFrom ;
2689+
2690+ try_from_upper_bounded ! ( usize , u8 , u16 , u32 ) ;
2691+ try_from_unbounded ! ( usize , usize , u64 , u128 ) ;
2692+ try_from_upper_bounded ! ( usize , i8 , i16 , i32 , i64 , isize ) ;
2693+ try_from_unbounded ! ( usize , i128 ) ;
2694+
2695+ try_from_both_bounded ! ( isize , u8 , u16 , u32 ) ;
2696+ try_from_lower_bounded ! ( isize , usize , u64 , u128 ) ;
2697+ try_from_both_bounded ! ( isize , i8 , i16 , i32 ) ;
2698+ try_from_unbounded ! ( isize , i64 , i128 ) ;
2699+
2700+ rev ! ( try_from_unbounded, usize , u8 , u16 , u32 , u64 ) ;
2701+ rev ! ( try_from_upper_bounded, usize , u128 ) ;
2702+ rev ! ( try_from_lower_bounded, usize , i8 , i16 , i32 , i64 ) ;
2703+ rev ! ( try_from_both_bounded, usize , i128 ) ;
2704+
2705+ rev ! ( try_from_unbounded, isize , u8 , u16 , u32 ) ;
2706+ rev ! ( try_from_upper_bounded, isize , u64 , u128 ) ;
2707+ rev ! ( try_from_unbounded, isize , i8 , i16 , i32 , i64 ) ;
2708+ rev ! ( try_from_both_bounded, isize , i128 ) ;
2709+ }
25772710
25782711#[ doc( hidden) ]
25792712trait FromStrRadixHelper : PartialOrd + Copy {
@@ -2587,15 +2720,21 @@ trait FromStrRadixHelper: PartialOrd + Copy {
25872720
25882721macro_rules! doit {
25892722 ( $( $t: ty) * ) => ( $( impl FromStrRadixHelper for $t {
2723+ #[ inline]
25902724 fn min_value( ) -> Self { Self :: min_value( ) }
2725+ #[ inline]
25912726 fn max_value( ) -> Self { Self :: max_value( ) }
2727+ #[ inline]
25922728 fn from_u32( u: u32 ) -> Self { u as Self }
2729+ #[ inline]
25932730 fn checked_mul( & self , other: u32 ) -> Option <Self > {
25942731 Self :: checked_mul( * self , other as Self )
25952732 }
2733+ #[ inline]
25962734 fn checked_sub( & self , other: u32 ) -> Option <Self > {
25972735 Self :: checked_sub( * self , other as Self )
25982736 }
2737+ #[ inline]
25992738 fn checked_add( & self , other: u32 ) -> Option <Self > {
26002739 Self :: checked_add( * self , other as Self )
26012740 }
0 commit comments