diff options
Diffstat (limited to 'src/test/ui/binop')
43 files changed, 1657 insertions, 0 deletions
diff --git a/src/test/ui/binop/binary-minus-without-space.rs b/src/test/ui/binop/binary-minus-without-space.rs new file mode 100644 index 000000000..2fbd5300d --- /dev/null +++ b/src/test/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/src/test/ui/binop/binary-op-on-double-ref.fixed b/src/test/ui/binop/binary-op-on-double-ref.fixed new file mode 100644 index 000000000..de9dc19af --- /dev/null +++ b/src/test/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/src/test/ui/binop/binary-op-on-double-ref.rs b/src/test/ui/binop/binary-op-on-double-ref.rs new file mode 100644 index 000000000..2616c560c --- /dev/null +++ b/src/test/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/src/test/ui/binop/binary-op-on-double-ref.stderr b/src/test/ui/binop/binary-op-on-double-ref.stderr new file mode 100644 index 000000000..1651f70d5 --- /dev/null +++ b/src/test/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}`, you can dereference `x` + | +LL | *x % 2 == 0 + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/binop/binary-op-on-fn-ptr-eq.rs b/src/test/ui/binop/binary-op-on-fn-ptr-eq.rs new file mode 100644 index 000000000..8e20640b5 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-bitxor-str.rs b/src/test/ui/binop/binop-bitxor-str.rs new file mode 100644 index 000000000..3085cce3f --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-bitxor-str.stderr b/src/test/ui/binop/binop-bitxor-str.stderr new file mode 100644 index 000000000..f236cd61e --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-consume-args.rs b/src/test/ui/binop/binop-consume-args.rs new file mode 100644 index 000000000..8d6c725d7 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-consume-args.stderr b/src/test/ui/binop/binop-consume-args.stderr new file mode 100644 index 000000000..c734f8c1e --- /dev/null +++ b/src/test/ui/binop/binop-consume-args.stderr @@ -0,0 +1,363 @@ +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 + | +LL | fn add(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn sub(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn mul(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn div(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn rem(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn bitand(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn bitor(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn bitxor(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn shl(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 + | +LL | fn shr(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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/src/test/ui/binop/binop-fail-3.rs b/src/test/ui/binop/binop-fail-3.rs new file mode 100644 index 000000000..49f635e0c --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-logic-float.rs b/src/test/ui/binop/binop-logic-float.rs new file mode 100644 index 000000000..1750d97ba --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-logic-float.stderr b/src/test/ui/binop/binop-logic-float.stderr new file mode 100644 index 000000000..3615622ae --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-logic-int.rs b/src/test/ui/binop/binop-logic-int.rs new file mode 100644 index 000000000..e71daa2dd --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-logic-int.stderr b/src/test/ui/binop/binop-logic-int.stderr new file mode 100644 index 000000000..50d857cd9 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-move-semantics.rs b/src/test/ui/binop/binop-move-semantics.rs new file mode 100644 index 000000000..b5133ea7c --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr new file mode 100644 index 000000000..695b01d5e --- /dev/null +++ b/src/test/ui/binop/binop-move-semantics.stderr @@ -0,0 +1,120 @@ +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 + | +LL | fn add(self, rhs: Rhs) -> Self::Output; + | ^^^^ +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 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 + | +LL | fn add(self, rhs: Rhs) -> Self::Output; + | ^^^^ + +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/src/test/ui/binop/binop-mul-bool.rs b/src/test/ui/binop/binop-mul-bool.rs new file mode 100644 index 000000000..41494c7a0 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-mul-bool.stderr b/src/test/ui/binop/binop-mul-bool.stderr new file mode 100644 index 000000000..8b5cde63c --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-mul-i32-f32.rs b/src/test/ui/binop/binop-mul-i32-f32.rs new file mode 100644 index 000000000..d18be51a4 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-mul-i32-f32.stderr b/src/test/ui/binop/binop-mul-i32-f32.stderr new file mode 100644 index 000000000..21c490965 --- /dev/null +++ b/src/test/ui/binop/binop-mul-i32-f32.stderr @@ -0,0 +1,21 @@ +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 f32 as Mul<f32>> + <&'a f64 as Mul<f64>> + <&'a i128 as Mul<i128>> + <&'a i16 as Mul<i16>> + <&'a i32 as Mul<i32>> + <&'a i64 as Mul<i64>> + <&'a i8 as Mul<i8>> + <&'a isize as Mul<isize>> + and 49 others + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/binop/binop-panic.rs b/src/test/ui/binop/binop-panic.rs new file mode 100644 index 000000000..44cdfffee --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-typeck.rs b/src/test/ui/binop/binop-typeck.rs new file mode 100644 index 000000000..812fe95db --- /dev/null +++ b/src/test/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/src/test/ui/binop/binop-typeck.stderr b/src/test/ui/binop/binop-typeck.stderr new file mode 100644 index 000000000..42d910819 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binops-issue-22743.rs b/src/test/ui/binop/binops-issue-22743.rs new file mode 100644 index 000000000..393ba0a56 --- /dev/null +++ b/src/test/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/src/test/ui/binop/binops.rs b/src/test/ui/binop/binops.rs new file mode 100644 index 000000000..a7abf6087 --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-25916.rs b/src/test/ui/binop/issue-25916.rs new file mode 100644 index 000000000..0b4159479 --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-28837.rs b/src/test/ui/binop/issue-28837.rs new file mode 100644 index 000000000..9719c3afa --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-28837.stderr b/src/test/ui/binop/issue-28837.stderr new file mode 100644 index 000000000..b9c7e1bea --- /dev/null +++ b/src/test/ui/binop/issue-28837.stderr @@ -0,0 +1,282 @@ +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Add<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Sub<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Mul<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Div<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Rem<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | pub trait BitAnd<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | pub trait BitOr<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | pub trait Shl<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | pub trait Shr<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +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/src/test/ui/binop/issue-3820.rs b/src/test/ui/binop/issue-3820.rs new file mode 100644 index 000000000..b987a90b2 --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-3820.stderr b/src/test/ui/binop/issue-3820.stderr new file mode 100644 index 000000000..f21f89069 --- /dev/null +++ b/src/test/ui/binop/issue-3820.stderr @@ -0,0 +1,22 @@ +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 following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Mul<Rhs = Self> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/binop/issue-77910-1.rs b/src/test/ui/binop/issue-77910-1.rs new file mode 100644 index 000000000..d786e3358 --- /dev/null +++ b/src/test/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<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` +} diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr new file mode 100644 index 000000000..68303b842 --- /dev/null +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -0,0 +1,28 @@ +error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}` + --> $DIR/issue-77910-1.rs:8:5 + | +LL | assert_eq!(foo, y); + | ^^^^^^^^^^^^^^^^^^ + | | + | for<'r> fn(&'r i32) -> &'r 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<'r> fn(&'r i32) -> &'r 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<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` + = help: use parentheses to call the function: `foo(s)` + = 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/src/test/ui/binop/issue-77910-2.rs b/src/test/ui/binop/issue-77910-2.rs new file mode 100644 index 000000000..2bb48d365 --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr new file mode 100644 index 000000000..5477a5762 --- /dev/null +++ b/src/test/ui/binop/issue-77910-2.stderr @@ -0,0 +1,11 @@ +error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}` + --> $DIR/issue-77910-2.rs:7:12 + | +LL | if foo == y {} + | --- ^^ - _ + | | + | for<'r> fn(&'r i32) -> &'r i32 {foo} + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/binop/issue-93927.rs b/src/test/ui/binop/issue-93927.rs new file mode 100644 index 000000000..de27c9785 --- /dev/null +++ b/src/test/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/src/test/ui/binop/issue-93927.stderr b/src/test/ui/binop/issue-93927.stderr new file mode 100644 index 000000000..75558b502 --- /dev/null +++ b/src/test/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/src/test/ui/binop/operator-multidispatch.rs b/src/test/ui/binop/operator-multidispatch.rs new file mode 100644 index 000000000..0d1dcfd8b --- /dev/null +++ b/src/test/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/src/test/ui/binop/operator-overloading.rs b/src/test/ui/binop/operator-overloading.rs new file mode 100644 index 000000000..6b3abcbc7 --- /dev/null +++ b/src/test/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/src/test/ui/binop/placement-syntax.rs b/src/test/ui/binop/placement-syntax.rs new file mode 100644 index 000000000..4df96dedb --- /dev/null +++ b/src/test/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/src/test/ui/binop/placement-syntax.stderr b/src/test/ui/binop/placement-syntax.stderr new file mode 100644 index 000000000..3fdaf4cd0 --- /dev/null +++ b/src/test/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/src/test/ui/binop/shift-various-bad-types.rs b/src/test/ui/binop/shift-various-bad-types.rs new file mode 100644 index 000000000..31224bbca --- /dev/null +++ b/src/test/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/src/test/ui/binop/shift-various-bad-types.stderr b/src/test/ui/binop/shift-various-bad-types.stderr new file mode 100644 index 000000000..38db66f86 --- /dev/null +++ b/src/test/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/src/test/ui/binop/structured-compare.rs b/src/test/ui/binop/structured-compare.rs new file mode 100644 index 000000000..63d30c4da --- /dev/null +++ b/src/test/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)); +} |