about summary refs log tree commit diff
path: root/src/librustc_const_math
diff options
context:
space:
mode:
authorJake Goulding <jake.goulding@gmail.com>2016-05-06 09:31:11 -0400
committerJake Goulding <jake.goulding@gmail.com>2016-05-19 13:55:13 -0400
commitbc7595c8abbf4e3b737e926d61814686e0ebda77 (patch)
tree3ead763b6c18622639409543dc3a46ba1e6374c1 /src/librustc_const_math
parent2fb6f8e2c94a7041877ed8460f2621974c5233f7 (diff)
Support 16-bit pointers as well as i/usize
This is based on the original work of Dylan McKay for the
[avr-rust project][ar].

[ar]: https://github.com/avr-rust/rust
Diffstat (limited to 'src/librustc_const_math')
-rw-r--r--src/librustc_const_math/int.rs39
-rw-r--r--src/librustc_const_math/is.rs4
-rw-r--r--src/librustc_const_math/us.rs4
3 files changed, 47 insertions, 0 deletions
diff --git a/src/librustc_const_math/int.rs b/src/librustc_const_math/int.rs
index 64f03be3b5f..28a58878472 100644
--- a/src/librustc_const_math/int.rs
+++ b/src/librustc_const_math/int.rs
@@ -77,12 +77,14 @@ impl ConstInt {
             (Infer(a @ 0...as_u64::I16MAX), I16(_)) => I16(a as i64 as i16),
             (Infer(a @ 0...as_u64::I32MAX), I32(_)) => I32(a as i64 as i32),
             (Infer(a @ 0...as_u64::I64MAX), I64(_)) => I64(a as i64),
+            (Infer(a @ 0...as_u64::I16MAX), Isize(Is16(_))) => Isize(Is16(a as i64 as i16)),
             (Infer(a @ 0...as_u64::I32MAX), Isize(Is32(_))) => Isize(Is32(a as i64 as i32)),
             (Infer(a @ 0...as_u64::I64MAX), Isize(Is64(_))) => Isize(Is64(a as i64)),
             (Infer(a @ 0...as_u64::U8MAX), U8(_)) => U8(a as u8),
             (Infer(a @ 0...as_u64::U16MAX), U16(_)) => U16(a as u16),
             (Infer(a @ 0...as_u64::U32MAX), U32(_)) => U32(a as u32),
             (Infer(a), U64(_)) => U64(a),
+            (Infer(a @ 0...as_u64::U16MAX), Usize(Us16(_))) => Usize(Us16(a as u16)),
             (Infer(a @ 0...as_u64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
             (Infer(a), Usize(Us64(_))) => Usize(Us64(a)),
 
@@ -92,6 +94,9 @@ impl ConstInt {
             (InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), I16(_)) => I16(a as i16),
             (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), I32(_)) => I32(a as i32),
             (InferSigned(a), I64(_)) => I64(a),
+            (InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), Isize(Is16(_))) => {
+                Isize(Is16(a as i16))
+            },
             (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), Isize(Is32(_))) => {
                 Isize(Is32(a as i32))
             },
@@ -100,6 +105,7 @@ impl ConstInt {
             (InferSigned(a @ 0...as_i64::U16MAX), U16(_)) => U16(a as u16),
             (InferSigned(a @ 0...as_i64::U32MAX), U32(_)) => U32(a as u32),
             (InferSigned(a @ 0...as_i64::I64MAX), U64(_)) => U64(a as u64),
+            (InferSigned(a @ 0...as_i64::U16MAX), Usize(Us16(_))) => Usize(Us16(a as u16)),
             (InferSigned(a @ 0...as_i64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
             (InferSigned(a @ 0...as_i64::I64MAX), Usize(Us64(_))) => Usize(Us64(a as u64)),
             (InferSigned(_), _) => return Err(ConstMathErr::NotInRange),
@@ -117,6 +123,7 @@ impl ConstInt {
             I16(i) if i < 0 => InferSigned(i as i64),
             I32(i) if i < 0 => InferSigned(i as i64),
             I64(i) if i < 0 => InferSigned(i as i64),
+            Isize(Is16(i)) if i < 0 => InferSigned(i as i64),
             Isize(Is32(i)) if i < 0 => InferSigned(i as i64),
             Isize(Is64(i)) if i < 0 => InferSigned(i as i64),
             InferSigned(i) => Infer(i as u64),
@@ -124,12 +131,14 @@ impl ConstInt {
             I16(i) => Infer(i as u64),
             I32(i) => Infer(i as u64),
             I64(i) => Infer(i as u64),
+            Isize(Is16(i)) => Infer(i as u64),
             Isize(Is32(i)) => Infer(i as u64),
             Isize(Is64(i)) => Infer(i as u64),
             U8(i) => Infer(i as u64),
             U16(i) => Infer(i as u64),
             U32(i) => Infer(i as u64),
             U64(i) => Infer(i as u64),
+            Usize(Us16(i)) => Infer(i as u64),
             Usize(Us32(i)) => Infer(i as u64),
             Usize(Us64(i)) => Infer(i),
         }
@@ -173,6 +182,7 @@ impl ConstInt {
             | Isize(Is64(v))
             | I64(v) if v >= 0 && v <= ::std::u32::MAX as i64 => Some(v as u32),
             Isize(Is32(v)) if v >= 0 => Some(v as u32),
+            Isize(Is16(v)) if v >= 0 => Some(v as u32),
             U8(v) => Some(v as u32),
             U16(v) => Some(v as u32),
             U32(v) => Some(v),
@@ -180,6 +190,7 @@ impl ConstInt {
             | Usize(Us64(v))
             | U64(v) if v <= ::std::u32::MAX as u64 => Some(v as u32),
             Usize(Us32(v)) => Some(v),
+            Usize(Us16(v)) => Some(v as u32),
             _ => None,
         }
     }
@@ -193,12 +204,14 @@ impl ConstInt {
             I16(v) if v >= 0 => Some(v as u64),
             I32(v) if v >= 0 => Some(v as u64),
             I64(v) if v >= 0 => Some(v as u64),
+            Isize(Is16(v)) if v >= 0 => Some(v as u64),
             Isize(Is32(v)) if v >= 0 => Some(v as u64),
             Isize(Is64(v)) if v >= 0 => Some(v as u64),
             U8(v) => Some(v as u64),
             U16(v) => Some(v as u64),
             U32(v) => Some(v as u64),
             U64(v) => Some(v),
+            Usize(Us16(v)) => Some(v as u64),
             Usize(Us32(v)) => Some(v as u64),
             Usize(Us64(v)) => Some(v),
             _ => None,
@@ -211,6 +224,7 @@ impl ConstInt {
             I16(v) => v < 0,
             I32(v) => v < 0,
             I64(v) => v < 0,
+            Isize(Is16(v)) => v < 0,
             Isize(Is32(v)) => v < 0,
             Isize(Is64(v)) => v < 0,
             InferSigned(v) => v < 0,
@@ -225,12 +239,14 @@ impl ConstInt {
             (I16(a), I16(b)) => Ok(a.cmp(&b)),
             (I32(a), I32(b)) => Ok(a.cmp(&b)),
             (I64(a), I64(b)) => Ok(a.cmp(&b)),
+            (Isize(Is16(a)), Isize(Is16(b))) => Ok(a.cmp(&b)),
             (Isize(Is32(a)), Isize(Is32(b))) => Ok(a.cmp(&b)),
             (Isize(Is64(a)), Isize(Is64(b))) => Ok(a.cmp(&b)),
             (U8(a), U8(b)) => Ok(a.cmp(&b)),
             (U16(a), U16(b)) => Ok(a.cmp(&b)),
             (U32(a), U32(b)) => Ok(a.cmp(&b)),
             (U64(a), U64(b)) => Ok(a.cmp(&b)),
+            (Usize(Us16(a)), Usize(Us16(b))) => Ok(a.cmp(&b)),
             (Usize(Us32(a)), Usize(Us32(b))) => Ok(a.cmp(&b)),
             (Usize(Us64(a)), Usize(Us64(b))) => Ok(a.cmp(&b)),
             (Infer(a), Infer(b)) => Ok(a.cmp(&b)),
@@ -249,12 +265,14 @@ impl ConstInt {
             ConstInt::I16(i) => ConstInt::I16(add1!(i)),
             ConstInt::I32(i) => ConstInt::I32(add1!(i)),
             ConstInt::I64(i) => ConstInt::I64(add1!(i)),
+            ConstInt::Isize(ConstIsize::Is16(i)) => ConstInt::Isize(ConstIsize::Is16(add1!(i))),
             ConstInt::Isize(ConstIsize::Is32(i)) => ConstInt::Isize(ConstIsize::Is32(add1!(i))),
             ConstInt::Isize(ConstIsize::Is64(i)) => ConstInt::Isize(ConstIsize::Is64(add1!(i))),
             ConstInt::U8(i) => ConstInt::U8(add1!(i)),
             ConstInt::U16(i) => ConstInt::U16(add1!(i)),
             ConstInt::U32(i) => ConstInt::U32(add1!(i)),
             ConstInt::U64(i) => ConstInt::U64(add1!(i)),
+            ConstInt::Usize(ConstUsize::Us16(i)) => ConstInt::Usize(ConstUsize::Us16(add1!(i))),
             ConstInt::Usize(ConstUsize::Us32(i)) => ConstInt::Usize(ConstUsize::Us32(add1!(i))),
             ConstInt::Usize(ConstUsize::Us64(i)) => ConstInt::Usize(ConstUsize::Us64(add1!(i))),
             ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
@@ -301,12 +319,14 @@ impl ::std::fmt::Display for ConstInt {
             I64(i) => write!(fmt, "{}i64", i),
             Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i),
             Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i),
+            Isize(ConstIsize::Is16(i)) => write!(fmt, "{}isize", i),
             U8(i) => write!(fmt, "{}u8", i),
             U16(i) => write!(fmt, "{}u16", i),
             U32(i) => write!(fmt, "{}u32", i),
             U64(i) => write!(fmt, "{}u64", i),
             Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i),
             Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i),
+            Usize(ConstUsize::Us16(i)) => write!(fmt, "{}usize", i),
         }
     }
 }
@@ -331,12 +351,14 @@ macro_rules! impl_binop {
                     (I16(a), I16(b)) => a.$checked_func(b).map(I16),
                     (I32(a), I32(b)) => a.$checked_func(b).map(I32),
                     (I64(a), I64(b)) => a.$checked_func(b).map(I64),
+                    (Isize(Is16(a)), Isize(Is16(b))) => a.$checked_func(b).map(Is16).map(Isize),
                     (Isize(Is32(a)), Isize(Is32(b))) => a.$checked_func(b).map(Is32).map(Isize),
                     (Isize(Is64(a)), Isize(Is64(b))) => a.$checked_func(b).map(Is64).map(Isize),
                     (U8(a), U8(b)) => a.$checked_func(b).map(U8),
                     (U16(a), U16(b)) => a.$checked_func(b).map(U16),
                     (U32(a), U32(b)) => a.$checked_func(b).map(U32),
                     (U64(a), U64(b)) => a.$checked_func(b).map(U64),
+                    (Usize(Us16(a)), Usize(Us16(b))) => a.$checked_func(b).map(Us16).map(Usize),
                     (Usize(Us32(a)), Usize(Us32(b))) => a.$checked_func(b).map(Us32).map(Usize),
                     (Usize(Us64(a)), Usize(Us64(b))) => a.$checked_func(b).map(Us64).map(Usize),
                     (Infer(a), Infer(b)) => a.$checked_func(b).map(Infer),
@@ -358,12 +380,14 @@ macro_rules! derive_binop {
                     (I16(a), I16(b)) => Ok(I16(a.$func(b))),
                     (I32(a), I32(b)) => Ok(I32(a.$func(b))),
                     (I64(a), I64(b)) => Ok(I64(a.$func(b))),
+                    (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a.$func(b)))),
                     (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a.$func(b)))),
                     (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a.$func(b)))),
                     (U8(a), U8(b)) => Ok(U8(a.$func(b))),
                     (U16(a), U16(b)) => Ok(U16(a.$func(b))),
                     (U32(a), U32(b)) => Ok(U32(a.$func(b))),
                     (U64(a), U64(b)) => Ok(U64(a.$func(b))),
+                    (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a.$func(b)))),
                     (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a.$func(b)))),
                     (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a.$func(b)))),
                     (Infer(a), Infer(b)) => Ok(Infer(a.$func(b))),
@@ -393,6 +417,7 @@ fn check_division(
         (I16(_), I16(0)) => Err(zerr),
         (I32(_), I32(0)) => Err(zerr),
         (I64(_), I64(0)) => Err(zerr),
+        (Isize(_), Isize(Is16(0))) => Err(zerr),
         (Isize(_), Isize(Is32(0))) => Err(zerr),
         (Isize(_), Isize(Is64(0))) => Err(zerr),
         (InferSigned(_), InferSigned(0)) => Err(zerr),
@@ -401,6 +426,7 @@ fn check_division(
         (U16(_), U16(0)) => Err(zerr),
         (U32(_), U32(0)) => Err(zerr),
         (U64(_), U64(0)) => Err(zerr),
+        (Usize(_), Usize(Us16(0))) => Err(zerr),
         (Usize(_), Usize(Us32(0))) => Err(zerr),
         (Usize(_), Usize(Us64(0))) => Err(zerr),
         (Infer(_), Infer(0)) => Err(zerr),
@@ -409,6 +435,7 @@ fn check_division(
         (I16(::std::i16::MIN), I16(-1)) => Err(Overflow(op)),
         (I32(::std::i32::MIN), I32(-1)) => Err(Overflow(op)),
         (I64(::std::i64::MIN), I64(-1)) => Err(Overflow(op)),
+        (Isize(Is16(::std::i16::MIN)), Isize(Is16(-1))) => Err(Overflow(op)),
         (Isize(Is32(::std::i32::MIN)), Isize(Is32(-1))) => Err(Overflow(op)),
         (Isize(Is64(::std::i64::MIN)), Isize(Is64(-1))) => Err(Overflow(op)),
         (InferSigned(::std::i64::MIN), InferSigned(-1)) => Err(Overflow(op)),
@@ -427,6 +454,7 @@ impl ::std::ops::Div for ConstInt {
             (I16(a), I16(b)) => Ok(I16(a/b)),
             (I32(a), I32(b)) => Ok(I32(a/b)),
             (I64(a), I64(b)) => Ok(I64(a/b)),
+            (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a/b))),
             (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a/b))),
             (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a/b))),
             (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a/b)),
@@ -435,6 +463,7 @@ impl ::std::ops::Div for ConstInt {
             (U16(a), U16(b)) => Ok(U16(a/b)),
             (U32(a), U32(b)) => Ok(U32(a/b)),
             (U64(a), U64(b)) => Ok(U64(a/b)),
+            (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a/b))),
             (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a/b))),
             (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a/b))),
             (Infer(a), Infer(b)) => Ok(Infer(a/b)),
@@ -455,6 +484,7 @@ impl ::std::ops::Rem for ConstInt {
             (I16(a), I16(b)) => Ok(I16(a%b)),
             (I32(a), I32(b)) => Ok(I32(a%b)),
             (I64(a), I64(b)) => Ok(I64(a%b)),
+            (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a%b))),
             (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a%b))),
             (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a%b))),
             (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a%b)),
@@ -463,6 +493,7 @@ impl ::std::ops::Rem for ConstInt {
             (U16(a), U16(b)) => Ok(U16(a%b)),
             (U32(a), U32(b)) => Ok(U32(a%b)),
             (U64(a), U64(b)) => Ok(U64(a%b)),
+            (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a%b))),
             (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a%b))),
             (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a%b))),
             (Infer(a), Infer(b)) => Ok(Infer(a%b)),
@@ -481,12 +512,14 @@ impl ::std::ops::Shl<ConstInt> for ConstInt {
             I16(a) => Ok(I16(overflowing!(a.overflowing_shl(b), Op::Shl))),
             I32(a) => Ok(I32(overflowing!(a.overflowing_shl(b), Op::Shl))),
             I64(a) => Ok(I64(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             U8(a) => Ok(U8(overflowing!(a.overflowing_shl(b), Op::Shl))),
             U16(a) => Ok(U16(overflowing!(a.overflowing_shl(b), Op::Shl))),
             U32(a) => Ok(U32(overflowing!(a.overflowing_shl(b), Op::Shl))),
             U64(a) => Ok(U64(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
             Infer(a) => Ok(Infer(overflowing!(a.overflowing_shl(b), Op::Shl))),
@@ -504,12 +537,14 @@ impl ::std::ops::Shr<ConstInt> for ConstInt {
             I16(a) => Ok(I16(overflowing!(a.overflowing_shr(b), Op::Shr))),
             I32(a) => Ok(I32(overflowing!(a.overflowing_shr(b), Op::Shr))),
             I64(a) => Ok(I64(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             U8(a) => Ok(U8(overflowing!(a.overflowing_shr(b), Op::Shr))),
             U16(a) => Ok(U16(overflowing!(a.overflowing_shr(b), Op::Shr))),
             U32(a) => Ok(U32(overflowing!(a.overflowing_shr(b), Op::Shr))),
             U64(a) => Ok(U64(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
             Infer(a) => Ok(Infer(overflowing!(a.overflowing_shr(b), Op::Shr))),
@@ -526,12 +561,14 @@ impl ::std::ops::Neg for ConstInt {
             I16(a) => Ok(I16(overflowing!(a.overflowing_neg(), Op::Neg))),
             I32(a) => Ok(I32(overflowing!(a.overflowing_neg(), Op::Neg))),
             I64(a) => Ok(I64(overflowing!(a.overflowing_neg(), Op::Neg))),
+            Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_neg(), Op::Neg)))),
             Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_neg(), Op::Neg)))),
             Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_neg(), Op::Neg)))),
             U8(0) => Ok(U8(0)),
             U16(0) => Ok(U16(0)),
             U32(0) => Ok(U32(0)),
             U64(0) => Ok(U64(0)),
+            Usize(Us16(0)) => Ok(Usize(Us16(0))),
             Usize(Us32(0)) => Ok(Usize(Us32(0))),
             Usize(Us64(0)) => Ok(Usize(Us64(0))),
             U8(_) => Err(UnsignedNegation),
@@ -554,12 +591,14 @@ impl ::std::ops::Not for ConstInt {
             I16(a) => Ok(I16(!a)),
             I32(a) => Ok(I32(!a)),
             I64(a) => Ok(I64(!a)),
+            Isize(Is16(a)) => Ok(Isize(Is16(!a))),
             Isize(Is32(a)) => Ok(Isize(Is32(!a))),
             Isize(Is64(a)) => Ok(Isize(Is64(!a))),
             U8(a) => Ok(U8(!a)),
             U16(a) => Ok(U16(!a)),
             U32(a) => Ok(U32(!a)),
             U64(a) => Ok(U64(!a)),
+            Usize(Us16(a)) => Ok(Usize(Us16(!a))),
             Usize(Us32(a)) => Ok(Usize(Us32(!a))),
             Usize(Us64(a)) => Ok(Usize(Us64(!a))),
             Infer(a) => Ok(Infer(!a)),
diff --git a/src/librustc_const_math/is.rs b/src/librustc_const_math/is.rs
index 082c6510f8b..4d2db355eb0 100644
--- a/src/librustc_const_math/is.rs
+++ b/src/librustc_const_math/is.rs
@@ -15,6 +15,7 @@ use super::err::*;
 /// Anything else is an error. This invariant is checked at several locations
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
 pub enum ConstIsize {
+    Is16(i16),
     Is32(i32),
     Is64(i64),
 }
@@ -23,6 +24,7 @@ pub use self::ConstIsize::*;
 impl ConstIsize {
     pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 {
         match (self, target_int_ty) {
+            (Is16(i), ast::IntTy::I16) => i as i64,
             (Is32(i), ast::IntTy::I32) => i as i64,
             (Is64(i), ast::IntTy::I64) => i,
             _ => panic!("got invalid isize size for target"),
@@ -30,6 +32,8 @@ impl ConstIsize {
     }
     pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
         match target_int_ty {
+            ast::IntTy::I16 if i as i16 as i64 == i => Ok(Is16(i as i16)),
+            ast::IntTy::I16 => Err(LitOutOfRange(ast::IntTy::Is)),
             ast::IntTy::I32 if i as i32 as i64 == i => Ok(Is32(i as i32)),
             ast::IntTy::I32 => Err(LitOutOfRange(ast::IntTy::Is)),
             ast::IntTy::I64 => Ok(Is64(i)),
diff --git a/src/librustc_const_math/us.rs b/src/librustc_const_math/us.rs
index e5a7086d436..2b224d06466 100644
--- a/src/librustc_const_math/us.rs
+++ b/src/librustc_const_math/us.rs
@@ -15,6 +15,7 @@ use super::err::*;
 /// Anything else is an error. This invariant is checked at several locations
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
 pub enum ConstUsize {
+    Us16(u16),
     Us32(u32),
     Us64(u64),
 }
@@ -23,6 +24,7 @@ pub use self::ConstUsize::*;
 impl ConstUsize {
     pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 {
         match (self, target_uint_ty) {
+            (Us16(i), ast::UintTy::U16) => i as u64,
             (Us32(i), ast::UintTy::U32) => i as u64,
             (Us64(i), ast::UintTy::U64) => i,
             _ => panic!("got invalid usize size for target"),
@@ -30,6 +32,8 @@ impl ConstUsize {
     }
     pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
         match target_uint_ty {
+            ast::UintTy::U16 if i as u16 as u64 == i => Ok(Us16(i as u16)),
+            ast::UintTy::U16 => Err(ULitOutOfRange(ast::UintTy::Us)),
             ast::UintTy::U32 if i as u32 as u64 == i => Ok(Us32(i as u32)),
             ast::UintTy::U32 => Err(ULitOutOfRange(ast::UintTy::Us)),
             ast::UintTy::U64 => Ok(Us64(i)),