]> git.lizzy.rs Git - rust.git/commitdiff
Allow shift operator to take any integral type (and add a test).
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 8 Jan 2015 15:28:59 +0000 (10:28 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 8 Jan 2015 16:02:24 +0000 (11:02 -0500)
src/librustc_typeck/check/mod.rs
src/test/compile-fail/shift-various-bad-types.rs [new file with mode: 0644]
src/test/run-pass/shift-various-types.rs [new file with mode: 0644]

index f3778eb054037ee355ded8af6bcfe1a29b1625c4..a6df676e63c8f429d20c10adfa5d6f8e599f8c87 100644 (file)
@@ -3208,8 +3208,24 @@ fn check_binop(fcx: &FnCtxt,
 
         if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
             // Shift is a special case: rhs must be uint, no matter what lhs is
-            check_expr_has_type(fcx, &**rhs, fcx.tcx().types.uint);
-            fcx.write_ty(expr.id, lhs_t);
+            check_expr(fcx, &**rhs);
+            let rhs_ty = fcx.expr_ty(&**rhs);
+            let rhs_ty = fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
+            if ty::type_is_integral(rhs_ty) {
+                fcx.write_ty(expr.id, lhs_t);
+            } else {
+                fcx.type_error_message(
+                    expr.span,
+                    |actual| {
+                        format!(
+                            "right-hand-side of a shift operation must have integral type, \
+                             not `{}`",
+                            actual)
+                    },
+                    rhs_ty,
+                    None);
+                fcx.write_ty(expr.id, fcx.tcx().types.err);
+            }
             return;
         }
 
diff --git a/src/test/compile-fail/shift-various-bad-types.rs b/src/test/compile-fail/shift-various-bad-types.rs
new file mode 100644 (file)
index 0000000..6287d79
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can do shifts by any integral type.
+
+struct Panolpy {
+    char: char,
+    str: &'static str,
+}
+
+fn foo(p: &Panolpy) {
+    22 >> p.char;
+    //~^ ERROR right-hand-side of a shift operation must have integral type
+
+    22 >> p.str;
+    //~^ ERROR right-hand-side of a shift operation must have integral type
+
+    22 >> p;
+    //~^ ERROR right-hand-side of a shift operation must have integral type
+
+    // We could be more accepting in the case of a type not yet inferred, but not
+    // known to be an integer, but meh.
+    let x;
+    22 >> x;
+    //~^ ERROR right-hand-side of a shift operation must have integral type
+
+    22 >> 1;
+    // Integer literal types are OK
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/shift-various-types.rs b/src/test/run-pass/shift-various-types.rs
new file mode 100644 (file)
index 0000000..3482dd4
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can do shifts by any integral type.
+
+struct Panolpy {
+    i8: i8,
+    i16: i16,
+    i32: i32,
+    i64: i64,
+    isize: isize,
+
+    u8: u8,
+    u16: u16,
+    u32: u32,
+    u64: u64,
+    usize: usize,
+}
+
+fn foo(p: &Panolpy) {
+    assert_eq!(22 >> p.i8, 11_i8);
+    assert_eq!(22 >> p.i16, 11_i16);
+    assert_eq!(22 >> p.i32, 11_i32);
+    assert_eq!(22 >> p.i64, 11_i64);
+    assert_eq!(22 >> p.isize, 11_is);
+
+    assert_eq!(22 >> p.u8, 11_u8);
+    assert_eq!(22 >> p.u16, 11_u16);
+    assert_eq!(22 >> p.u32, 11_u32);
+    assert_eq!(22 >> p.u64, 11_u64);
+    assert_eq!(22 >> p.usize, 11_us);
+}
+
+fn main() {
+    let p = Panolpy {
+        i8: 1,
+        i16: 1,
+        i32: 1,
+        i64: 1,
+        isize: 1,
+
+        u8: 1,
+        u16: 1,
+        u32: 1,
+        u64: 1,
+        usize: 1,
+    };
+    foo(&p)
+}