Skip to content

Commit fa9a421

Browse files
committed
Auto merge of #28921 - petrochenkov:intconv, r=alexcrichton
Part of rust-lang/rfcs#1218 (comment) r? @aturon
2 parents 99dc124 + 6f3e84d commit fa9a421

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/libcore/num/mod.rs

+43
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use self::wrapping::OverflowingOps;
1717

1818
use char::CharExt;
1919
use cmp::{Eq, PartialOrd};
20+
use convert::From;
2021
use fmt;
2122
use intrinsics;
2223
use marker::{Copy, Sized};
@@ -1471,3 +1472,45 @@ impl fmt::Display for ParseIntError {
14711472
}
14721473

14731474
pub use num::dec2flt::ParseFloatError;
1475+
1476+
// Conversion traits for primitive integer types
1477+
// Conversions T -> T are covered by a blanket impl and therefore excluded
1478+
// Some conversions from and to usize/isize are not implemented due to portability concerns
1479+
macro_rules! impl_from {
1480+
($Small: ty, $Large: ty) => {
1481+
#[stable(feature = "lossless_int_conv", since = "1.5.0")]
1482+
impl From<$Small> for $Large {
1483+
#[stable(feature = "lossless_int_conv", since = "1.5.0")]
1484+
#[inline]
1485+
fn from(small: $Small) -> $Large {
1486+
small as $Large
1487+
}
1488+
}
1489+
}
1490+
}
1491+
1492+
// Unsigned -> Unsigned
1493+
impl_from! { u8, u16 }
1494+
impl_from! { u8, u32 }
1495+
impl_from! { u8, u64 }
1496+
impl_from! { u8, usize }
1497+
impl_from! { u16, u32 }
1498+
impl_from! { u16, u64 }
1499+
impl_from! { u32, u64 }
1500+
1501+
// Signed -> Signed
1502+
impl_from! { i8, i16 }
1503+
impl_from! { i8, i32 }
1504+
impl_from! { i8, i64 }
1505+
impl_from! { i8, isize }
1506+
impl_from! { i16, i32 }
1507+
impl_from! { i16, i64 }
1508+
impl_from! { i32, i64 }
1509+
1510+
// Unsigned -> Signed
1511+
impl_from! { u8, i16 }
1512+
impl_from! { u8, i32 }
1513+
impl_from! { u8, i64 }
1514+
impl_from! { u16, i32 }
1515+
impl_from! { u16, i64 }
1516+
impl_from! { u32, i64 }

src/libcoretest/num/mod.rs

+40
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,44 @@ mod tests {
137137
assert_eq!("+".parse::<i8>().ok(), None);
138138
assert_eq!("".parse::<u8>().ok(), None);
139139
}
140+
141+
macro_rules! test_impl_from {
142+
($fn_name: ident, $Small: ty, $Large: ty) => {
143+
#[test]
144+
fn $fn_name() {
145+
let small_max = <$Small>::max_value();
146+
let small_min = <$Small>::min_value();
147+
let large_max: $Large = small_max.into();
148+
let large_min: $Large = small_min.into();
149+
assert_eq!(large_max as $Small, small_max);
150+
assert_eq!(large_min as $Small, small_min);
151+
}
152+
}
153+
}
154+
155+
// Unsigned -> Unsigned
156+
test_impl_from! { test_u8u16, u8, u16 }
157+
test_impl_from! { test_u8u32, u8, u32 }
158+
test_impl_from! { test_u8u64, u8, u64 }
159+
test_impl_from! { test_u8usize, u8, usize }
160+
test_impl_from! { test_u16u32, u16, u32 }
161+
test_impl_from! { test_u16u64, u16, u64 }
162+
test_impl_from! { test_u32u64, u32, u64 }
163+
164+
// Signed -> Signed
165+
test_impl_from! { test_i8i16, i8, i16 }
166+
test_impl_from! { test_i8i32, i8, i32 }
167+
test_impl_from! { test_i8i64, i8, i64 }
168+
test_impl_from! { test_i8isize, i8, isize }
169+
test_impl_from! { test_i16i32, i16, i32 }
170+
test_impl_from! { test_i16i64, i16, i64 }
171+
test_impl_from! { test_i32i64, i32, i64 }
172+
173+
// Unsigned -> Signed
174+
test_impl_from! { test_u8i16, u8, i16 }
175+
test_impl_from! { test_u8i32, u8, i32 }
176+
test_impl_from! { test_u8i64, u8, i64 }
177+
test_impl_from! { test_u16i32, u16, i32 }
178+
test_impl_from! { test_u16i64, u16, i64 }
179+
test_impl_from! { test_u32i64, u32, i64 }
140180
}

0 commit comments

Comments
 (0)