summaryrefslogtreecommitdiffstats
path: root/tests/ui/binop
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/binop
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/binop')
-rw-r--r--tests/ui/binop/binary-minus-without-space.rs8
-rw-r--r--tests/ui/binop/binary-op-on-double-ref.fixed9
-rw-r--r--tests/ui/binop/binary-op-on-double-ref.rs9
-rw-r--r--tests/ui/binop/binary-op-on-double-ref.stderr16
-rw-r--r--tests/ui/binop/binary-op-on-fn-ptr-eq.rs9
-rw-r--r--tests/ui/binop/binop-bitxor-str.rs3
-rw-r--r--tests/ui/binop/binop-bitxor-str.stderr11
-rw-r--r--tests/ui/binop/binop-consume-args.rs65
-rw-r--r--tests/ui/binop/binop-consume-args.stderr333
-rw-r--r--tests/ui/binop/binop-fail-3.rs11
-rw-r--r--tests/ui/binop/binop-logic-float.rs3
-rw-r--r--tests/ui/binop/binop-logic-float.stderr15
-rw-r--r--tests/ui/binop/binop-logic-int.rs3
-rw-r--r--tests/ui/binop/binop-logic-int.stderr15
-rw-r--r--tests/ui/binop/binop-move-semantics.rs68
-rw-r--r--tests/ui/binop/binop-move-semantics.stderr118
-rw-r--r--tests/ui/binop/binop-mul-bool.rs3
-rw-r--r--tests/ui/binop/binop-mul-bool.stderr11
-rw-r--r--tests/ui/binop/binop-mul-i32-f32.rs5
-rw-r--r--tests/ui/binop/binop-mul-i32-f32.stderr16
-rw-r--r--tests/ui/binop/binop-panic.rs12
-rw-r--r--tests/ui/binop/binop-typeck.rs8
-rw-r--r--tests/ui/binop/binop-typeck.stderr11
-rw-r--r--tests/ui/binop/binops-issue-22743.rs24
-rw-r--r--tests/ui/binop/binops.rs89
-rw-r--r--tests/ui/binop/issue-25916.rs28
-rw-r--r--tests/ui/binop/issue-28837.rs35
-rw-r--r--tests/ui/binop/issue-28837.stderr255
-rw-r--r--tests/ui/binop/issue-3820.rs15
-rw-r--r--tests/ui/binop/issue-3820.stderr19
-rw-r--r--tests/ui/binop/issue-77910-1.rs11
-rw-r--r--tests/ui/binop/issue-77910-1.stderr28
-rw-r--r--tests/ui/binop/issue-77910-2.rs9
-rw-r--r--tests/ui/binop/issue-77910-2.stderr16
-rw-r--r--tests/ui/binop/issue-93927.rs20
-rw-r--r--tests/ui/binop/issue-93927.stderr16
-rw-r--r--tests/ui/binop/operator-multidispatch.rs36
-rw-r--r--tests/ui/binop/operator-overloading.rs81
-rw-r--r--tests/ui/binop/placement-syntax.rs6
-rw-r--r--tests/ui/binop/placement-syntax.stderr13
-rw-r--r--tests/ui/binop/shift-various-bad-types.rs31
-rw-r--r--tests/ui/binop/shift-various-bad-types.stderr71
-rw-r--r--tests/ui/binop/structured-compare.rs30
43 files changed, 1595 insertions, 0 deletions
diff --git a/tests/ui/binop/binary-minus-without-space.rs b/tests/ui/binop/binary-minus-without-space.rs
new file mode 100644
index 000000000..2fbd5300d
--- /dev/null
+++ b/tests/ui/binop/binary-minus-without-space.rs
@@ -0,0 +1,8 @@
+// run-pass
+// Check that issue #954 stays fixed
+
+
+pub fn main() {
+ match -1 { -1 => {}, _ => panic!("wat") }
+ assert_eq!(1-1, 0);
+}
diff --git a/tests/ui/binop/binary-op-on-double-ref.fixed b/tests/ui/binop/binary-op-on-double-ref.fixed
new file mode 100644
index 000000000..de9dc19af
--- /dev/null
+++ b/tests/ui/binop/binary-op-on-double-ref.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+fn main() {
+ let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let vr = v.iter().filter(|x| {
+ *x % 2 == 0
+ //~^ ERROR cannot mod `&&{integer}` by `{integer}`
+ });
+ println!("{:?}", vr);
+}
diff --git a/tests/ui/binop/binary-op-on-double-ref.rs b/tests/ui/binop/binary-op-on-double-ref.rs
new file mode 100644
index 000000000..2616c560c
--- /dev/null
+++ b/tests/ui/binop/binary-op-on-double-ref.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+fn main() {
+ let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let vr = v.iter().filter(|x| {
+ x % 2 == 0
+ //~^ ERROR cannot mod `&&{integer}` by `{integer}`
+ });
+ println!("{:?}", vr);
+}
diff --git a/tests/ui/binop/binary-op-on-double-ref.stderr b/tests/ui/binop/binary-op-on-double-ref.stderr
new file mode 100644
index 000000000..34826d2f4
--- /dev/null
+++ b/tests/ui/binop/binary-op-on-double-ref.stderr
@@ -0,0 +1,16 @@
+error[E0369]: cannot mod `&&{integer}` by `{integer}`
+ --> $DIR/binary-op-on-double-ref.rs:5:11
+ |
+LL | x % 2 == 0
+ | - ^ - {integer}
+ | |
+ | &&{integer}
+ |
+help: `%` can be used on `&{integer}` if you dereference the left-hand side
+ |
+LL | *x % 2 == 0
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/binary-op-on-fn-ptr-eq.rs b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs
new file mode 100644
index 000000000..8e20640b5
--- /dev/null
+++ b/tests/ui/binop/binary-op-on-fn-ptr-eq.rs
@@ -0,0 +1,9 @@
+// run-pass
+// Tests equality between supertype and subtype of a function
+// See the issue #91636
+fn foo(_a: &str) {}
+
+fn main() {
+ let x = foo as fn(&'static str);
+ let _ = x == foo;
+}
diff --git a/tests/ui/binop/binop-bitxor-str.rs b/tests/ui/binop/binop-bitxor-str.rs
new file mode 100644
index 000000000..3085cce3f
--- /dev/null
+++ b/tests/ui/binop/binop-bitxor-str.rs
@@ -0,0 +1,3 @@
+// error-pattern:no implementation for `String ^ String`
+
+fn main() { let x = "a".to_string() ^ "b".to_string(); }
diff --git a/tests/ui/binop/binop-bitxor-str.stderr b/tests/ui/binop/binop-bitxor-str.stderr
new file mode 100644
index 000000000..f236cd61e
--- /dev/null
+++ b/tests/ui/binop/binop-bitxor-str.stderr
@@ -0,0 +1,11 @@
+error[E0369]: no implementation for `String ^ String`
+ --> $DIR/binop-bitxor-str.rs:3:37
+ |
+LL | fn main() { let x = "a".to_string() ^ "b".to_string(); }
+ | --------------- ^ --------------- String
+ | |
+ | String
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/binop-consume-args.rs b/tests/ui/binop/binop-consume-args.rs
new file mode 100644
index 000000000..8d6c725d7
--- /dev/null
+++ b/tests/ui/binop/binop-consume-args.rs
@@ -0,0 +1,65 @@
+// Test that binary operators consume their arguments
+
+use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitXor, BitOr, Shl, Shr};
+
+fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs + rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs - rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs * rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs / rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs % rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs & rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs | rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs ^ rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs << rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
+ lhs >> rhs;
+ drop(lhs); //~ ERROR use of moved value: `lhs`
+ drop(rhs); //~ ERROR use of moved value: `rhs`
+}
+
+fn main() {}
diff --git a/tests/ui/binop/binop-consume-args.stderr b/tests/ui/binop/binop-consume-args.stderr
new file mode 100644
index 000000000..6fbbb5543
--- /dev/null
+++ b/tests/ui/binop/binop-consume-args.stderr
@@ -0,0 +1,333 @@
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:7:10
+ |
+LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs + rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn add<A: Add<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:8:10
+ |
+LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs + rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn add<A: Add<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:13:10
+ |
+LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs - rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn sub<A: Sub<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:14:10
+ |
+LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs - rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn sub<A: Sub<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:19:10
+ |
+LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs * rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn mul<A: Mul<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:20:10
+ |
+LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs * rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn mul<A: Mul<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:25:10
+ |
+LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs / rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn div<A: Div<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:26:10
+ |
+LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs / rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn div<A: Div<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:31:10
+ |
+LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs % rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn rem<A: Rem<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:32:10
+ |
+LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs % rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn rem<A: Rem<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:37:10
+ |
+LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs & rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn bitand<A: BitAnd<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:38:10
+ |
+LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs & rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn bitand<A: BitAnd<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:43:10
+ |
+LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs | rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn bitor<A: BitOr<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:44:10
+ |
+LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs | rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn bitor<A: BitOr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:49:10
+ |
+LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs ^ rhs;
+ | --------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn bitxor<A: BitXor<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:50:10
+ |
+LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs ^ rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn bitxor<A: BitXor<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:55:10
+ |
+LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs << rhs;
+ | ---------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn shl<A: Shl<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:56:10
+ |
+LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs << rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn shl<A: Shl<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `lhs`
+ --> $DIR/binop-consume-args.rs:61:10
+ |
+LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
+LL | lhs >> rhs;
+ | ---------- `lhs` moved due to usage in operator
+LL | drop(lhs);
+ | ^^^ value used here after move
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn shr<A: Shr<B, Output=()> + Copy, B>(lhs: A, rhs: B) {
+ | ++++++
+
+error[E0382]: use of moved value: `rhs`
+ --> $DIR/binop-consume-args.rs:62:10
+ |
+LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
+ | --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
+LL | lhs >> rhs;
+ | --- value moved here
+LL | drop(lhs);
+LL | drop(rhs);
+ | ^^^ value used here after move
+ |
+help: consider restricting type parameter `B`
+ |
+LL | fn shr<A: Shr<B, Output=()>, B: Copy>(lhs: A, rhs: B) {
+ | ++++++
+
+error: aborting due to 20 previous errors
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/binop/binop-fail-3.rs b/tests/ui/binop/binop-fail-3.rs
new file mode 100644
index 000000000..49f635e0c
--- /dev/null
+++ b/tests/ui/binop/binop-fail-3.rs
@@ -0,0 +1,11 @@
+// run-fail
+// error-pattern:quux
+// ignore-emscripten no processes
+
+fn foo() -> ! {
+ panic!("quux");
+}
+
+fn main() {
+ foo() == foo(); // these types wind up being defaulted to ()
+}
diff --git a/tests/ui/binop/binop-logic-float.rs b/tests/ui/binop/binop-logic-float.rs
new file mode 100644
index 000000000..1750d97ba
--- /dev/null
+++ b/tests/ui/binop/binop-logic-float.rs
@@ -0,0 +1,3 @@
+fn main() { let x = 1.0_f32 || 2.0_f32; }
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
diff --git a/tests/ui/binop/binop-logic-float.stderr b/tests/ui/binop/binop-logic-float.stderr
new file mode 100644
index 000000000..3615622ae
--- /dev/null
+++ b/tests/ui/binop/binop-logic-float.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/binop-logic-float.rs:1:21
+ |
+LL | fn main() { let x = 1.0_f32 || 2.0_f32; }
+ | ^^^^^^^ expected `bool`, found `f32`
+
+error[E0308]: mismatched types
+ --> $DIR/binop-logic-float.rs:1:32
+ |
+LL | fn main() { let x = 1.0_f32 || 2.0_f32; }
+ | ^^^^^^^ expected `bool`, found `f32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/binop/binop-logic-int.rs b/tests/ui/binop/binop-logic-int.rs
new file mode 100644
index 000000000..e71daa2dd
--- /dev/null
+++ b/tests/ui/binop/binop-logic-int.rs
@@ -0,0 +1,3 @@
+fn main() { let x = 1 && 2; }
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
diff --git a/tests/ui/binop/binop-logic-int.stderr b/tests/ui/binop/binop-logic-int.stderr
new file mode 100644
index 000000000..50d857cd9
--- /dev/null
+++ b/tests/ui/binop/binop-logic-int.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/binop-logic-int.rs:1:21
+ |
+LL | fn main() { let x = 1 && 2; }
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/binop-logic-int.rs:1:26
+ |
+LL | fn main() { let x = 1 && 2; }
+ | ^ expected `bool`, found integer
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/binop/binop-move-semantics.rs b/tests/ui/binop/binop-move-semantics.rs
new file mode 100644
index 000000000..b5133ea7c
--- /dev/null
+++ b/tests/ui/binop/binop-move-semantics.rs
@@ -0,0 +1,68 @@
+// Test that move restrictions are enforced on overloaded binary operations
+
+use std::ops::Add;
+
+fn double_move<T: Add<Output=()>>(x: T) {
+ x
+ +
+ x; //~ ERROR: use of moved value
+}
+
+fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
+ x
+ +
+ x.clone(); //~ ERROR: borrow of moved value
+}
+
+fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
+ let m = &x;
+ let n = &mut y;
+
+ x //~ ERROR: cannot move out of `x` because it is borrowed
+ +
+ y; //~ ERROR: cannot move out of `y` because it is borrowed
+ use_mut(n); use_imm(m);
+}
+fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
+ let m = &mut x;
+ let n = &y;
+
+ *m //~ ERROR: cannot move
+ +
+ *n; //~ ERROR: cannot move
+ use_imm(n); use_mut(m);
+}
+struct Foo;
+
+impl<'a, 'b> Add<&'b Foo> for &'a mut Foo {
+ type Output = ();
+
+ fn add(self, _: &Foo) {}
+}
+
+impl<'a, 'b> Add<&'b mut Foo> for &'a Foo {
+ type Output = ();
+
+ fn add(self, _: &mut Foo) {}
+}
+
+fn mut_plus_immut() {
+ let mut f = Foo;
+
+ &mut f
+ +
+ &f; //~ ERROR: cannot borrow `f` as immutable because it is also borrowed as mutable
+}
+
+fn immut_plus_mut() {
+ let mut f = Foo;
+
+ &f
+ +
+ &mut f; //~ ERROR: cannot borrow `f` as mutable because it is also borrowed as immutable
+}
+
+fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
diff --git a/tests/ui/binop/binop-move-semantics.stderr b/tests/ui/binop/binop-move-semantics.stderr
new file mode 100644
index 000000000..dae267da0
--- /dev/null
+++ b/tests/ui/binop/binop-move-semantics.stderr
@@ -0,0 +1,118 @@
+error[E0382]: use of moved value: `x`
+ --> $DIR/binop-move-semantics.rs:8:5
+ |
+LL | fn double_move<T: Add<Output=()>>(x: T) {
+ | - move occurs because `x` has type `T`, which does not implement the `Copy` trait
+LL | / x
+LL | | +
+LL | | x;
+ | | ^
+ | | |
+ | |_____value used here after move
+ | `x` moved due to usage in operator
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+help: consider further restricting this bound
+ |
+LL | fn double_move<T: Add<Output=()> + Copy>(x: T) {
+ | ++++++
+
+error[E0382]: borrow of moved value: `x`
+ --> $DIR/binop-move-semantics.rs:14:5
+ |
+LL | fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
+ | - move occurs because `x` has type `T`, which does not implement the `Copy` trait
+LL | x
+ | - value moved here
+LL | +
+LL | x.clone();
+ | ^^^^^^^^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x.clone()
+ | ++++++++
+help: consider further restricting this bound
+ |
+LL | fn move_then_borrow<T: Add<Output=()> + Clone + Copy>(x: T) {
+ | ++++++
+
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/binop-move-semantics.rs:21:5
+ |
+LL | let m = &x;
+ | -- borrow of `x` occurs here
+...
+LL | x
+ | ^ move out of `x` occurs here
+...
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/binop-move-semantics.rs:23:5
+ |
+LL | let n = &mut y;
+ | ------ borrow of `y` occurs here
+...
+LL | y;
+ | ^ move out of `y` occurs here
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
+error[E0507]: cannot move out of `*m` which is behind a mutable reference
+ --> $DIR/binop-move-semantics.rs:30:5
+ |
+LL | *m
+ | -^
+ | |
+ | _____move occurs because `*m` has type `T`, which does not implement the `Copy` trait
+ | |
+LL | | +
+LL | | *n;
+ | |______- `*m` moved due to usage in operator
+ |
+note: calling this operator moves the left-hand side
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0507]: cannot move out of `*n` which is behind a shared reference
+ --> $DIR/binop-move-semantics.rs:32:5
+ |
+LL | *n;
+ | ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
+
+error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
+ --> $DIR/binop-move-semantics.rs:54:5
+ |
+LL | &mut f
+ | ------
+ | |
+ | _____mutable borrow occurs here
+ | |
+LL | | +
+LL | | &f;
+ | | ^-
+ | |_____||
+ | |mutable borrow later used here
+ | immutable borrow occurs here
+
+error[E0502]: cannot borrow `f` as mutable because it is also borrowed as immutable
+ --> $DIR/binop-move-semantics.rs:62:5
+ |
+LL | &f
+ | --
+ | |
+ | _____immutable borrow occurs here
+ | |
+LL | | +
+LL | | &mut f;
+ | | ^^^^^-
+ | |_____|____|
+ | | immutable borrow later used here
+ | mutable borrow occurs here
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0382, E0502, E0505, E0507.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/binop/binop-mul-bool.rs b/tests/ui/binop/binop-mul-bool.rs
new file mode 100644
index 000000000..41494c7a0
--- /dev/null
+++ b/tests/ui/binop/binop-mul-bool.rs
@@ -0,0 +1,3 @@
+// error-pattern:cannot multiply `bool` by `bool`
+
+fn main() { let x = true * false; }
diff --git a/tests/ui/binop/binop-mul-bool.stderr b/tests/ui/binop/binop-mul-bool.stderr
new file mode 100644
index 000000000..8b5cde63c
--- /dev/null
+++ b/tests/ui/binop/binop-mul-bool.stderr
@@ -0,0 +1,11 @@
+error[E0369]: cannot multiply `bool` by `bool`
+ --> $DIR/binop-mul-bool.rs:3:26
+ |
+LL | fn main() { let x = true * false; }
+ | ---- ^ ----- bool
+ | |
+ | bool
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/binop-mul-i32-f32.rs b/tests/ui/binop/binop-mul-i32-f32.rs
new file mode 100644
index 000000000..d18be51a4
--- /dev/null
+++ b/tests/ui/binop/binop-mul-i32-f32.rs
@@ -0,0 +1,5 @@
+fn foo(x: i32, y: f32) -> f32 {
+ x * y //~ ERROR cannot multiply `i32` by `f32`
+}
+
+fn main() {}
diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr
new file mode 100644
index 000000000..c986bc3fd
--- /dev/null
+++ b/tests/ui/binop/binop-mul-i32-f32.stderr
@@ -0,0 +1,16 @@
+error[E0277]: cannot multiply `i32` by `f32`
+ --> $DIR/binop-mul-i32-f32.rs:2:7
+ |
+LL | x * y
+ | ^ no implementation for `i32 * f32`
+ |
+ = help: the trait `Mul<f32>` is not implemented for `i32`
+ = help: the following other types implement trait `Mul<Rhs>`:
+ <&'a i32 as Mul<i32>>
+ <&i32 as Mul<&i32>>
+ <i32 as Mul<&i32>>
+ <i32 as Mul>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/binop/binop-panic.rs b/tests/ui/binop/binop-panic.rs
new file mode 100644
index 000000000..44cdfffee
--- /dev/null
+++ b/tests/ui/binop/binop-panic.rs
@@ -0,0 +1,12 @@
+// run-fail
+// error-pattern:quux
+// ignore-emscripten no processes
+
+fn my_err(s: String) -> ! {
+ println!("{}", s);
+ panic!("quux");
+}
+
+fn main() {
+ 3_usize == my_err("bye".to_string());
+}
diff --git a/tests/ui/binop/binop-typeck.rs b/tests/ui/binop/binop-typeck.rs
new file mode 100644
index 000000000..812fe95db
--- /dev/null
+++ b/tests/ui/binop/binop-typeck.rs
@@ -0,0 +1,8 @@
+// issue #500
+
+fn main() {
+ let x = true;
+ let y = 1;
+ let z = x + y;
+ //~^ ERROR cannot add `{integer}` to `bool`
+}
diff --git a/tests/ui/binop/binop-typeck.stderr b/tests/ui/binop/binop-typeck.stderr
new file mode 100644
index 000000000..42d910819
--- /dev/null
+++ b/tests/ui/binop/binop-typeck.stderr
@@ -0,0 +1,11 @@
+error[E0369]: cannot add `{integer}` to `bool`
+ --> $DIR/binop-typeck.rs:6:15
+ |
+LL | let z = x + y;
+ | - ^ - {integer}
+ | |
+ | bool
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/binops-issue-22743.rs b/tests/ui/binop/binops-issue-22743.rs
new file mode 100644
index 000000000..393ba0a56
--- /dev/null
+++ b/tests/ui/binop/binops-issue-22743.rs
@@ -0,0 +1,24 @@
+// run-pass
+
+use std::ops::Mul;
+
+#[derive(Copy, Clone)]
+pub struct Foo {
+ x: f64,
+}
+
+impl Mul<Foo> for f64 {
+ type Output = Foo;
+
+ fn mul(self, rhs: Foo) -> Foo {
+ // intentionally do something that is not *
+ Foo { x: self + rhs.x }
+ }
+}
+
+pub fn main() {
+ let f: Foo = Foo { x: 5.0 };
+ let val: f64 = 3.0;
+ let f2: Foo = val * f;
+ assert_eq!(f2.x, 8.0);
+}
diff --git a/tests/ui/binop/binops.rs b/tests/ui/binop/binops.rs
new file mode 100644
index 000000000..a7abf6087
--- /dev/null
+++ b/tests/ui/binop/binops.rs
@@ -0,0 +1,89 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+// Binop corner cases
+
+fn test_nil() {
+ assert_eq!((), ());
+ assert!((!(() != ())));
+ assert!((!(() < ())));
+ assert!((() <= ()));
+ assert!((!(() > ())));
+ assert!((() >= ()));
+}
+
+fn test_bool() {
+ assert!((!(true < false)));
+ assert!((!(true <= false)));
+ assert!((true > false));
+ assert!((true >= false));
+
+ assert!((false < true));
+ assert!((false <= true));
+ assert!((!(false > true)));
+ assert!((!(false >= true)));
+
+ // Bools support bitwise binops
+ assert_eq!(false & false, false);
+ assert_eq!(true & false, false);
+ assert_eq!(true & true, true);
+ assert_eq!(false | false, false);
+ assert_eq!(true | false, true);
+ assert_eq!(true | true, true);
+ assert_eq!(false ^ false, false);
+ assert_eq!(true ^ false, true);
+ assert_eq!(true ^ true, false);
+}
+
+fn test_ptr() {
+ unsafe {
+ let p1: *const u8 = ::std::mem::transmute(0_usize);
+ let p2: *const u8 = ::std::mem::transmute(0_usize);
+ let p3: *const u8 = ::std::mem::transmute(1_usize);
+
+ assert_eq!(p1, p2);
+ assert!(p1 != p3);
+ assert!(p1 < p3);
+ assert!(p1 <= p3);
+ assert!(p3 > p1);
+ assert!(p3 >= p3);
+ assert!(p1 <= p2);
+ assert!(p1 >= p2);
+ }
+}
+
+#[derive(PartialEq, Debug)]
+struct p {
+ x: isize,
+ y: isize,
+}
+
+fn p(x: isize, y: isize) -> p {
+ p {
+ x: x,
+ y: y
+ }
+}
+
+fn test_class() {
+ let q = p(1, 2);
+ let mut r = p(1, 2);
+
+ unsafe {
+ println!("q = {:x}, r = {:x}",
+ (::std::mem::transmute::<*const p, usize>(&q)),
+ (::std::mem::transmute::<*const p, usize>(&r)));
+ }
+ assert_eq!(q, r);
+ r.y = 17;
+ assert!((r.y != q.y));
+ assert_eq!(r.y, 17);
+ assert!((q != r));
+}
+
+pub fn main() {
+ test_nil();
+ test_bool();
+ test_ptr();
+ test_class();
+}
diff --git a/tests/ui/binop/issue-25916.rs b/tests/ui/binop/issue-25916.rs
new file mode 100644
index 000000000..0b4159479
--- /dev/null
+++ b/tests/ui/binop/issue-25916.rs
@@ -0,0 +1,28 @@
+// run-pass
+#![allow(unused_must_use)]
+
+fn main() {
+ macro_rules! f {
+ () => { 0 + 0 }
+ }
+ // 16 per line
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+ f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
+}
diff --git a/tests/ui/binop/issue-28837.rs b/tests/ui/binop/issue-28837.rs
new file mode 100644
index 000000000..9719c3afa
--- /dev/null
+++ b/tests/ui/binop/issue-28837.rs
@@ -0,0 +1,35 @@
+struct A;
+
+fn main() {
+ let a = A;
+
+ a + a; //~ ERROR cannot add `A` to `A`
+
+ a - a; //~ ERROR cannot subtract `A` from `A`
+
+ a * a; //~ ERROR cannot multiply `A` by `A`
+
+ a / a; //~ ERROR cannot divide `A` by `A`
+
+ a % a; //~ ERROR cannot mod `A` by `A`
+
+ a & a; //~ ERROR no implementation for `A & A`
+
+ a | a; //~ ERROR no implementation for `A | A`
+
+ a << a; //~ ERROR no implementation for `A << A`
+
+ a >> a; //~ ERROR no implementation for `A >> A`
+
+ a == a; //~ ERROR binary operation `==` cannot be applied to type `A`
+
+ a != a; //~ ERROR binary operation `!=` cannot be applied to type `A`
+
+ a < a; //~ ERROR binary operation `<` cannot be applied to type `A`
+
+ a <= a; //~ ERROR binary operation `<=` cannot be applied to type `A`
+
+ a > a; //~ ERROR binary operation `>` cannot be applied to type `A`
+
+ a >= a; //~ ERROR binary operation `>=` cannot be applied to type `A`
+}
diff --git a/tests/ui/binop/issue-28837.stderr b/tests/ui/binop/issue-28837.stderr
new file mode 100644
index 000000000..6e236ca52
--- /dev/null
+++ b/tests/ui/binop/issue-28837.stderr
@@ -0,0 +1,255 @@
+error[E0369]: cannot add `A` to `A`
+ --> $DIR/issue-28837.rs:6:7
+ |
+LL | a + a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `Add<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Add<_>`
+note: the trait `Add` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0369]: cannot subtract `A` from `A`
+ --> $DIR/issue-28837.rs:8:7
+ |
+LL | a - a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `Sub<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Sub<_>`
+note: the trait `Sub` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0369]: cannot multiply `A` by `A`
+ --> $DIR/issue-28837.rs:10:7
+ |
+LL | a * a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `Mul<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Mul<_>`
+note: the trait `Mul` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0369]: cannot divide `A` by `A`
+ --> $DIR/issue-28837.rs:12:7
+ |
+LL | a / a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `Div<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Div<_>`
+note: the trait `Div` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0369]: cannot mod `A` by `A`
+ --> $DIR/issue-28837.rs:14:7
+ |
+LL | a % a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `Rem<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Rem<_>`
+note: the trait `Rem` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error[E0369]: no implementation for `A & A`
+ --> $DIR/issue-28837.rs:16:7
+ |
+LL | a & a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `BitAnd<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `BitAnd<_>`
+note: the trait `BitAnd` must be implemented
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+
+error[E0369]: no implementation for `A | A`
+ --> $DIR/issue-28837.rs:18:7
+ |
+LL | a | a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `BitOr<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `BitOr<_>`
+note: the trait `BitOr` must be implemented
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+
+error[E0369]: no implementation for `A << A`
+ --> $DIR/issue-28837.rs:20:7
+ |
+LL | a << a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `Shl<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Shl<_>`
+note: the trait `Shl` must be implemented
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+
+error[E0369]: no implementation for `A >> A`
+ --> $DIR/issue-28837.rs:22:7
+ |
+LL | a >> a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `Shr<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `Shr<_>`
+note: the trait `Shr` must be implemented
+ --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+
+error[E0369]: binary operation `==` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:24:7
+ |
+LL | a == a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialEq<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialEq<_>`
+help: consider annotating `A` with `#[derive(PartialEq)]`
+ |
+LL | #[derive(PartialEq)]
+ |
+
+error[E0369]: binary operation `!=` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:26:7
+ |
+LL | a != a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialEq<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialEq<_>`
+help: consider annotating `A` with `#[derive(PartialEq)]`
+ |
+LL | #[derive(PartialEq)]
+ |
+
+error[E0369]: binary operation `<` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:28:7
+ |
+LL | a < a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialOrd<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialOrd<_>`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
+ |
+LL | #[derive(PartialEq, PartialOrd)]
+ |
+
+error[E0369]: binary operation `<=` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:30:7
+ |
+LL | a <= a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialOrd<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialOrd<_>`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
+ |
+LL | #[derive(PartialEq, PartialOrd)]
+ |
+
+error[E0369]: binary operation `>` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:32:7
+ |
+LL | a > a;
+ | - ^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialOrd<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialOrd<_>`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
+ |
+LL | #[derive(PartialEq, PartialOrd)]
+ |
+
+error[E0369]: binary operation `>=` cannot be applied to type `A`
+ --> $DIR/issue-28837.rs:34:7
+ |
+LL | a >= a;
+ | - ^^ - A
+ | |
+ | A
+ |
+note: an implementation of `PartialOrd<_>` might be missing for `A`
+ --> $DIR/issue-28837.rs:1:1
+ |
+LL | struct A;
+ | ^^^^^^^^ must implement `PartialOrd<_>`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
+ |
+LL | #[derive(PartialEq, PartialOrd)]
+ |
+
+error: aborting due to 15 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/issue-3820.rs b/tests/ui/binop/issue-3820.rs
new file mode 100644
index 000000000..b987a90b2
--- /dev/null
+++ b/tests/ui/binop/issue-3820.rs
@@ -0,0 +1,15 @@
+struct Thing {
+ x: isize
+}
+
+impl Thing {
+ fn mul(&self, c: &isize) -> Thing {
+ Thing {x: self.x * *c}
+ }
+}
+
+fn main() {
+ let u = Thing {x: 2};
+ let _v = u.mul(&3); // This is ok
+ let w = u * 3; //~ ERROR cannot multiply `Thing` by `{integer}`
+}
diff --git a/tests/ui/binop/issue-3820.stderr b/tests/ui/binop/issue-3820.stderr
new file mode 100644
index 000000000..c313ed603
--- /dev/null
+++ b/tests/ui/binop/issue-3820.stderr
@@ -0,0 +1,19 @@
+error[E0369]: cannot multiply `Thing` by `{integer}`
+ --> $DIR/issue-3820.rs:14:15
+ |
+LL | let w = u * 3;
+ | - ^ - {integer}
+ | |
+ | Thing
+ |
+note: an implementation of `Mul<_>` might be missing for `Thing`
+ --> $DIR/issue-3820.rs:1:1
+ |
+LL | struct Thing {
+ | ^^^^^^^^^^^^ must implement `Mul<_>`
+note: the trait `Mul` must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/issue-77910-1.rs b/tests/ui/binop/issue-77910-1.rs
new file mode 100644
index 000000000..95bbd6a60
--- /dev/null
+++ b/tests/ui/binop/issue-77910-1.rs
@@ -0,0 +1,11 @@
+fn foo(s: &i32) -> &i32 {
+ let xs;
+ xs
+}
+fn main() {
+ let y;
+ // we shouldn't ice with the bound var here.
+ assert_eq!(foo, y);
+ //~^ ERROR binary operation `==` cannot be applied to type
+ //~| ERROR `for<'a> fn(&'a i32) -> &'a i32 {foo}` doesn't implement `Debug`
+}
diff --git a/tests/ui/binop/issue-77910-1.stderr b/tests/ui/binop/issue-77910-1.stderr
new file mode 100644
index 000000000..263a35d98
--- /dev/null
+++ b/tests/ui/binop/issue-77910-1.stderr
@@ -0,0 +1,28 @@
+error[E0369]: binary operation `==` cannot be applied to type `for<'a> fn(&'a i32) -> &'a i32 {foo}`
+ --> $DIR/issue-77910-1.rs:8:5
+ |
+LL | assert_eq!(foo, y);
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | for<'a> fn(&'a i32) -> &'a i32 {foo}
+ | _
+ |
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `for<'a> fn(&'a i32) -> &'a i32 {foo}` doesn't implement `Debug`
+ --> $DIR/issue-77910-1.rs:8:5
+ |
+LL | fn foo(s: &i32) -> &i32 {
+ | --- consider calling this function
+...
+LL | assert_eq!(foo, y);
+ | ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
+ = help: use parentheses to call this function: `foo(/* &i32 */)`
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0369.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/binop/issue-77910-2.rs b/tests/ui/binop/issue-77910-2.rs
new file mode 100644
index 000000000..2bb48d365
--- /dev/null
+++ b/tests/ui/binop/issue-77910-2.rs
@@ -0,0 +1,9 @@
+fn foo(s: &i32) -> &i32 {
+ let xs;
+ xs
+}
+fn main() {
+ let y;
+ if foo == y {}
+ //~^ ERROR binary operation `==` cannot be applied to type
+}
diff --git a/tests/ui/binop/issue-77910-2.stderr b/tests/ui/binop/issue-77910-2.stderr
new file mode 100644
index 000000000..b3856b6ae
--- /dev/null
+++ b/tests/ui/binop/issue-77910-2.stderr
@@ -0,0 +1,16 @@
+error[E0369]: binary operation `==` cannot be applied to type `for<'a> fn(&'a i32) -> &'a i32 {foo}`
+ --> $DIR/issue-77910-2.rs:7:12
+ |
+LL | if foo == y {}
+ | --- ^^ - _
+ | |
+ | for<'a> fn(&'a i32) -> &'a i32 {foo}
+ |
+help: use parentheses to call this function
+ |
+LL | if foo(/* &i32 */) == y {}
+ | ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/issue-93927.rs b/tests/ui/binop/issue-93927.rs
new file mode 100644
index 000000000..de27c9785
--- /dev/null
+++ b/tests/ui/binop/issue-93927.rs
@@ -0,0 +1,20 @@
+// Regression test for #93927: suggested trait bound for T should be Eq, not PartialEq
+struct MyType<T>(T);
+
+impl<T> PartialEq for MyType<T>
+where
+ T: Eq,
+{
+ fn eq(&self, other: &Self) -> bool {
+ true
+ }
+}
+
+fn cond<T: PartialEq>(val: MyType<T>) -> bool {
+ val == val
+ //~^ ERROR binary operation `==` cannot be applied to type `MyType<T>`
+}
+
+fn main() {
+ cond(MyType(0));
+}
diff --git a/tests/ui/binop/issue-93927.stderr b/tests/ui/binop/issue-93927.stderr
new file mode 100644
index 000000000..75558b502
--- /dev/null
+++ b/tests/ui/binop/issue-93927.stderr
@@ -0,0 +1,16 @@
+error[E0369]: binary operation `==` cannot be applied to type `MyType<T>`
+ --> $DIR/issue-93927.rs:14:9
+ |
+LL | val == val
+ | --- ^^ --- MyType<T>
+ | |
+ | MyType<T>
+ |
+help: consider further restricting this bound
+ |
+LL | fn cond<T: PartialEq + std::cmp::Eq>(val: MyType<T>) -> bool {
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/binop/operator-multidispatch.rs b/tests/ui/binop/operator-multidispatch.rs
new file mode 100644
index 000000000..0d1dcfd8b
--- /dev/null
+++ b/tests/ui/binop/operator-multidispatch.rs
@@ -0,0 +1,36 @@
+// run-pass
+// Test that we can overload the `+` operator for points so that two
+// points can be added, and a point can be added to an integer.
+
+use std::ops;
+
+#[derive(Debug,PartialEq,Eq)]
+struct Point {
+ x: isize,
+ y: isize
+}
+
+impl ops::Add for Point {
+ type Output = Point;
+
+ fn add(self, other: Point) -> Point {
+ Point {x: self.x + other.x, y: self.y + other.y}
+ }
+}
+
+impl ops::Add<isize> for Point {
+ type Output = Point;
+
+ fn add(self, other: isize) -> Point {
+ Point {x: self.x + other,
+ y: self.y + other}
+ }
+}
+
+pub fn main() {
+ let mut p = Point {x: 10, y: 20};
+ p = p + Point {x: 101, y: 102};
+ assert_eq!(p, Point {x: 111, y: 122});
+ p = p + 1;
+ assert_eq!(p, Point {x: 112, y: 123});
+}
diff --git a/tests/ui/binop/operator-overloading.rs b/tests/ui/binop/operator-overloading.rs
new file mode 100644
index 000000000..6b3abcbc7
--- /dev/null
+++ b/tests/ui/binop/operator-overloading.rs
@@ -0,0 +1,81 @@
+// run-pass
+
+#![allow(unused_variables)]
+use std::cmp;
+use std::ops;
+
+#[derive(Copy, Clone, Debug)]
+struct Point {
+ x: isize,
+ y: isize
+}
+
+impl ops::Add for Point {
+ type Output = Point;
+
+ fn add(self, other: Point) -> Point {
+ Point {x: self.x + other.x, y: self.y + other.y}
+ }
+}
+
+impl ops::Sub for Point {
+ type Output = Point;
+
+ fn sub(self, other: Point) -> Point {
+ Point {x: self.x - other.x, y: self.y - other.y}
+ }
+}
+
+impl ops::Neg for Point {
+ type Output = Point;
+
+ fn neg(self) -> Point {
+ Point {x: -self.x, y: -self.y}
+ }
+}
+
+impl ops::Not for Point {
+ type Output = Point;
+
+ fn not(self) -> Point {
+ Point {x: !self.x, y: !self.y }
+ }
+}
+
+impl ops::Index<bool> for Point {
+ type Output = isize;
+
+ fn index(&self, x: bool) -> &isize {
+ if x {
+ &self.x
+ } else {
+ &self.y
+ }
+ }
+}
+
+impl cmp::PartialEq for Point {
+ fn eq(&self, other: &Point) -> bool {
+ (*self).x == (*other).x && (*self).y == (*other).y
+ }
+ fn ne(&self, other: &Point) -> bool { !(*self).eq(other) }
+}
+
+pub fn main() {
+ let mut p = Point {x: 10, y: 20};
+ p = p + Point {x: 101, y: 102};
+ p = p - Point {x: 100, y: 100};
+ assert_eq!(p + Point {x: 5, y: 5}, Point {x: 16, y: 27});
+ assert_eq!(-p, Point {x: -11, y: -22});
+ assert_eq!(p[true], 11);
+ assert_eq!(p[false], 22);
+
+ let q = !p;
+ assert_eq!(q.x, !(p.x));
+ assert_eq!(q.y, !(p.y));
+
+ // Issue #1733
+ result(p[true]);
+}
+
+fn result(i: isize) { }
diff --git a/tests/ui/binop/placement-syntax.rs b/tests/ui/binop/placement-syntax.rs
new file mode 100644
index 000000000..4df96dedb
--- /dev/null
+++ b/tests/ui/binop/placement-syntax.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let x = -5;
+ if x<-1 { //~ ERROR unexpected token: `<-`
+ println!("ok");
+ }
+}
diff --git a/tests/ui/binop/placement-syntax.stderr b/tests/ui/binop/placement-syntax.stderr
new file mode 100644
index 000000000..3fdaf4cd0
--- /dev/null
+++ b/tests/ui/binop/placement-syntax.stderr
@@ -0,0 +1,13 @@
+error: unexpected token: `<-`
+ --> $DIR/placement-syntax.rs:3:9
+ |
+LL | if x<-1 {
+ | ^^
+ |
+help: if you meant to write a comparison against a negative value, add a space in between `<` and `-`
+ |
+LL | if x< -1 {
+ | ~~~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/binop/shift-various-bad-types.rs b/tests/ui/binop/shift-various-bad-types.rs
new file mode 100644
index 000000000..31224bbca
--- /dev/null
+++ b/tests/ui/binop/shift-various-bad-types.rs
@@ -0,0 +1,31 @@
+// 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 E0277
+
+ 22 >> p.str;
+ //~^ ERROR E0277
+
+ 22 >> p;
+ //~^ ERROR E0277
+
+ let x;
+ 22 >> x; // ambiguity error winds up being suppressed
+
+ 22 >> 1;
+ // Integer literal types are OK
+
+ // Type of the result follows the LHS, not the RHS:
+ let _: i32 = 22_i64 >> 1_i32;
+ //~^ ERROR mismatched types
+ //~| expected `i32`, found `i64`
+}
+
+fn main() {
+}
diff --git a/tests/ui/binop/shift-various-bad-types.stderr b/tests/ui/binop/shift-various-bad-types.stderr
new file mode 100644
index 000000000..38db66f86
--- /dev/null
+++ b/tests/ui/binop/shift-various-bad-types.stderr
@@ -0,0 +1,71 @@
+error[E0277]: no implementation for `{integer} >> char`
+ --> $DIR/shift-various-bad-types.rs:9:8
+ |
+LL | 22 >> p.char;
+ | ^^ no implementation for `{integer} >> char`
+ |
+ = help: the trait `Shr<char>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Shr<Rhs>`:
+ <&'a i128 as Shr<i128>>
+ <&'a i128 as Shr<i16>>
+ <&'a i128 as Shr<i32>>
+ <&'a i128 as Shr<i64>>
+ <&'a i128 as Shr<i8>>
+ <&'a i128 as Shr<isize>>
+ <&'a i128 as Shr<u128>>
+ <&'a i128 as Shr<u16>>
+ and 568 others
+
+error[E0277]: no implementation for `{integer} >> &str`
+ --> $DIR/shift-various-bad-types.rs:12:8
+ |
+LL | 22 >> p.str;
+ | ^^ no implementation for `{integer} >> &str`
+ |
+ = help: the trait `Shr<&str>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Shr<Rhs>`:
+ <&'a i128 as Shr<i128>>
+ <&'a i128 as Shr<i16>>
+ <&'a i128 as Shr<i32>>
+ <&'a i128 as Shr<i64>>
+ <&'a i128 as Shr<i8>>
+ <&'a i128 as Shr<isize>>
+ <&'a i128 as Shr<u128>>
+ <&'a i128 as Shr<u16>>
+ and 568 others
+
+error[E0277]: no implementation for `{integer} >> &Panolpy`
+ --> $DIR/shift-various-bad-types.rs:15:8
+ |
+LL | 22 >> p;
+ | ^^ no implementation for `{integer} >> &Panolpy`
+ |
+ = help: the trait `Shr<&Panolpy>` is not implemented for `{integer}`
+ = help: the following other types implement trait `Shr<Rhs>`:
+ <&'a i128 as Shr<i128>>
+ <&'a i128 as Shr<i16>>
+ <&'a i128 as Shr<i32>>
+ <&'a i128 as Shr<i64>>
+ <&'a i128 as Shr<i8>>
+ <&'a i128 as Shr<isize>>
+ <&'a i128 as Shr<u128>>
+ <&'a i128 as Shr<u16>>
+ and 568 others
+
+error[E0308]: mismatched types
+ --> $DIR/shift-various-bad-types.rs:25:18
+ |
+LL | let _: i32 = 22_i64 >> 1_i32;
+ | --- ^^^^^^^^^^^^^^^ expected `i32`, found `i64`
+ | |
+ | expected due to this
+ |
+help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | let _: i32 = (22_i64 >> 1_i32).try_into().unwrap();
+ | + +++++++++++++++++++++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/binop/structured-compare.rs b/tests/ui/binop/structured-compare.rs
new file mode 100644
index 000000000..63d30c4da
--- /dev/null
+++ b/tests/ui/binop/structured-compare.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+
+
+#[derive(Copy, Clone, Debug)]
+enum foo { large, small, }
+
+impl PartialEq for foo {
+ fn eq(&self, other: &foo) -> bool {
+ ((*self) as usize) == ((*other) as usize)
+ }
+ fn ne(&self, other: &foo) -> bool { !(*self).eq(other) }
+}
+
+pub fn main() {
+ let a = (1, 2, 3);
+ let b = (1, 2, 3);
+ assert_eq!(a, b);
+ assert!((a != (1, 2, 4)));
+ assert!((a < (1, 2, 4)));
+ assert!((a <= (1, 2, 4)));
+ assert!(((1, 2, 4) > a));
+ assert!(((1, 2, 4) >= a));
+ let x = foo::large;
+ let y = foo::small;
+ assert!((x != y));
+ assert_eq!(x, foo::large);
+ assert!((x != foo::small));
+}