diff options
Diffstat (limited to 'src/test/ui/compare-method')
20 files changed, 471 insertions, 0 deletions
diff --git a/src/test/ui/compare-method/bad-self-type.rs b/src/test/ui/compare-method/bad-self-type.rs new file mode 100644 index 000000000..f42a9e49a --- /dev/null +++ b/src/test/ui/compare-method/bad-self-type.rs @@ -0,0 +1,26 @@ +use std::future::Future; +use std::task::{Context, Poll}; + +fn main() {} + +struct MyFuture {} + +impl Future for MyFuture { + type Output = (); + fn poll(self, _: &mut Context<'_>) -> Poll<()> { + //~^ ERROR method `poll` has an incompatible type for trait + todo!() + } +} + +trait T { + fn foo(self); + fn bar(self) -> Option<()>; +} + +impl T for MyFuture { + fn foo(self: Box<Self>) {} + //~^ ERROR method `foo` has an incompatible type for trait + fn bar(self) {} + //~^ ERROR method `bar` has an incompatible type for trait +} diff --git a/src/test/ui/compare-method/bad-self-type.stderr b/src/test/ui/compare-method/bad-self-type.stderr new file mode 100644 index 000000000..90e907157 --- /dev/null +++ b/src/test/ui/compare-method/bad-self-type.stderr @@ -0,0 +1,50 @@ +error[E0053]: method `poll` has an incompatible type for trait + --> $DIR/bad-self-type.rs:10:13 + | +LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> { + | ^^^^ + | | + | expected struct `Pin`, found struct `MyFuture` + | help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>` + | + = note: expected fn pointer `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>` + found fn pointer `fn(MyFuture, &mut Context<'_>) -> Poll<_>` + +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/bad-self-type.rs:22:18 + | +LL | fn foo(self: Box<Self>) {} + | ------^^^^^^^^^ + | | | + | | expected struct `MyFuture`, found struct `Box` + | help: change the self-receiver type to match the trait: `self` + | +note: type in trait + --> $DIR/bad-self-type.rs:17:12 + | +LL | fn foo(self); + | ^^^^ + = note: expected fn pointer `fn(MyFuture)` + found fn pointer `fn(Box<MyFuture>)` + +error[E0053]: method `bar` has an incompatible type for trait + --> $DIR/bad-self-type.rs:24:18 + | +LL | fn bar(self) {} + | ^ expected enum `Option`, found `()` + | +note: type in trait + --> $DIR/bad-self-type.rs:18:21 + | +LL | fn bar(self) -> Option<()>; + | ^^^^^^^^^^ + = note: expected fn pointer `fn(MyFuture) -> Option<()>` + found fn pointer `fn(MyFuture)` +help: change the output type to match the trait + | +LL | fn bar(self) -> Option<()> {} + | +++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/compare-method/issue-90444.rs b/src/test/ui/compare-method/issue-90444.rs new file mode 100644 index 000000000..6c287d9a7 --- /dev/null +++ b/src/test/ui/compare-method/issue-90444.rs @@ -0,0 +1,17 @@ +pub struct A; +impl From<fn((), (), &())> for A { + fn from(_: fn((), (), &mut ())) -> Self { + //~^ error: method `from` has an incompatible type for trait + loop {} + } +} + +pub struct B; +impl From<fn((), (), u32)> for B { + fn from(_: fn((), (), u64)) -> Self { + //~^ error: method `from` has an incompatible type for trait + loop {} + } +} + +fn main() {} diff --git a/src/test/ui/compare-method/issue-90444.stderr b/src/test/ui/compare-method/issue-90444.stderr new file mode 100644 index 000000000..84bbec062 --- /dev/null +++ b/src/test/ui/compare-method/issue-90444.stderr @@ -0,0 +1,27 @@ +error[E0053]: method `from` has an incompatible type for trait + --> $DIR/issue-90444.rs:3:16 + | +LL | fn from(_: fn((), (), &mut ())) -> Self { + | ^^^^^^^^^^^^^^^^^^^ + | | + | types differ in mutability + | help: change the parameter type to match the trait: `for<'r> fn((), (), &'r ())` + | + = note: expected fn pointer `fn(for<'r> fn((), (), &'r ())) -> A` + found fn pointer `fn(for<'r> fn((), (), &'r mut ())) -> A` + +error[E0053]: method `from` has an incompatible type for trait + --> $DIR/issue-90444.rs:11:16 + | +LL | fn from(_: fn((), (), u64)) -> Self { + | ^^^^^^^^^^^^^^^ + | | + | expected `u32`, found `u64` + | help: change the parameter type to match the trait: `fn((), (), u32)` + | + = note: expected fn pointer `fn(fn((), (), u32)) -> B` + found fn pointer `fn(fn((), (), u64)) -> B` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/compare-method/proj-outlives-region.rs b/src/test/ui/compare-method/proj-outlives-region.rs new file mode 100644 index 000000000..969bc566d --- /dev/null +++ b/src/test/ui/compare-method/proj-outlives-region.rs @@ -0,0 +1,14 @@ +// Test that we elaborate `Type: 'region` constraints and infer various important things. + +trait Master<'a, T: ?Sized, U> { + fn foo() where T: 'a; +} + +// `U::Item: 'a` does not imply that `U: 'a` +impl<'a, U: Iterator> Master<'a, U::Item, U> for () { + fn foo() where U: 'a { } //~ ERROR E0276 +} + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/compare-method/proj-outlives-region.stderr b/src/test/ui/compare-method/proj-outlives-region.stderr new file mode 100644 index 000000000..797a81679 --- /dev/null +++ b/src/test/ui/compare-method/proj-outlives-region.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/proj-outlives-region.rs:9:23 + | +LL | fn foo() where T: 'a; + | --------------------- definition of `foo` from trait +... +LL | fn foo() where U: 'a { } + | ^^ impl has extra requirement `U: 'a` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-extra-2.rs b/src/test/ui/compare-method/region-extra-2.rs new file mode 100644 index 000000000..3d57b544e --- /dev/null +++ b/src/test/ui/compare-method/region-extra-2.rs @@ -0,0 +1,15 @@ +// Regression test for issue #22779. An extra where clause was +// permitted on the impl that is not present on the trait. + +trait Tr<'a, T> { + fn renew<'b: 'a>(self) -> &'b mut [T]; +} + +impl<'a, T> Tr<'a, T> for &'a mut [T] { + fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { + //~^ ERROR E0276 + &mut self[..] + } +} + +fn main() { } diff --git a/src/test/ui/compare-method/region-extra-2.stderr b/src/test/ui/compare-method/region-extra-2.stderr new file mode 100644 index 000000000..f01d7f471 --- /dev/null +++ b/src/test/ui/compare-method/region-extra-2.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/region-extra-2.rs:9:53 + | +LL | fn renew<'b: 'a>(self) -> &'b mut [T]; + | -------------------------------------- definition of `renew` from trait +... +LL | fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { + | ^^ impl has extra requirement `'a: 'b` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-extra.rs b/src/test/ui/compare-method/region-extra.rs new file mode 100644 index 000000000..1070cb845 --- /dev/null +++ b/src/test/ui/compare-method/region-extra.rs @@ -0,0 +1,14 @@ +// Test that you cannot add an extra where clause in the impl relating +// two regions. + +trait Master<'a, 'b> { + fn foo(); +} + +impl<'a, 'b> Master<'a, 'b> for () { + fn foo() where 'a: 'b { } //~ ERROR impl has stricter +} + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/compare-method/region-extra.stderr b/src/test/ui/compare-method/region-extra.stderr new file mode 100644 index 000000000..4a3af65e9 --- /dev/null +++ b/src/test/ui/compare-method/region-extra.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/region-extra.rs:9:24 + | +LL | fn foo(); + | --------- definition of `foo` from trait +... +LL | fn foo() where 'a: 'b { } + | ^^ impl has extra requirement `'a: 'b` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-unrelated.rs b/src/test/ui/compare-method/region-unrelated.rs new file mode 100644 index 000000000..9730c9dfe --- /dev/null +++ b/src/test/ui/compare-method/region-unrelated.rs @@ -0,0 +1,15 @@ +// Test that we elaborate `Type: 'region` constraints and infer various important things. + +trait Master<'a, T: ?Sized, U> { + fn foo() where T: 'a; +} + +// `U: 'a` does not imply `V: 'a` +impl<'a, U, V> Master<'a, U, V> for () { + fn foo() where V: 'a { } + //~^ ERROR impl has stricter requirements than trait +} + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/compare-method/region-unrelated.stderr b/src/test/ui/compare-method/region-unrelated.stderr new file mode 100644 index 000000000..f7ae6f944 --- /dev/null +++ b/src/test/ui/compare-method/region-unrelated.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/region-unrelated.rs:9:23 + | +LL | fn foo() where T: 'a; + | --------------------- definition of `foo` from trait +... +LL | fn foo() where V: 'a { } + | ^^ impl has extra requirement `V: 'a` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/reordered-type-param.rs b/src/test/ui/compare-method/reordered-type-param.rs new file mode 100644 index 000000000..a858b66d7 --- /dev/null +++ b/src/test/ui/compare-method/reordered-type-param.rs @@ -0,0 +1,19 @@ +// Tests that ty params get matched correctly when comparing +// an impl against a trait +// +// cc #26111 + +trait A { + fn b<C:Clone,D>(&self, x: C) -> C; +} + +struct E { + f: isize +} + +impl A for E { + // n.b. The error message is awful -- see #3404 + fn b<F:Clone,G>(&self, _x: G) -> G { panic!() } //~ ERROR method `b` has an incompatible type +} + +fn main() {} diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr new file mode 100644 index 000000000..49b5b1b92 --- /dev/null +++ b/src/test/ui/compare-method/reordered-type-param.stderr @@ -0,0 +1,24 @@ +error[E0053]: method `b` has an incompatible type for trait + --> $DIR/reordered-type-param.rs:16:30 + | +LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() } + | - - ^ + | | | | + | | | expected type parameter `F`, found type parameter `G` + | | | help: change the parameter type to match the trait: `F` + | | found type parameter + | expected type parameter + | +note: type in trait + --> $DIR/reordered-type-param.rs:7:29 + | +LL | fn b<C:Clone,D>(&self, x: C) -> C; + | ^ + = note: expected fn pointer `fn(&E, F) -> F` + found fn pointer `fn(&E, G) -> G` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/compare-method/trait-bound-on-type-parameter.rs b/src/test/ui/compare-method/trait-bound-on-type-parameter.rs new file mode 100644 index 000000000..5359001ea --- /dev/null +++ b/src/test/ui/compare-method/trait-bound-on-type-parameter.rs @@ -0,0 +1,18 @@ +// Tests that impl can't add extra `F: Sync` bound aren't *more* restrictive +// than the trait method it's implementing. +// +// Regr test for #26111. + +trait A { + fn b<C,D>(&self, x: C) -> C; +} + +struct E { + f: isize +} + +impl A for E { + fn b<F: Sync, G>(&self, _x: F) -> F { panic!() } //~ ERROR E0276 +} + +fn main() {} diff --git a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr new file mode 100644 index 000000000..ce6885c15 --- /dev/null +++ b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/trait-bound-on-type-parameter.rs:15:13 + | +LL | fn b<C,D>(&self, x: C) -> C; + | ---------------------------- definition of `b` from trait +... +LL | fn b<F: Sync, G>(&self, _x: F) -> F { panic!() } + | ^^^^ impl has extra requirement `F: Sync` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/traits-misc-mismatch-1.rs b/src/test/ui/compare-method/traits-misc-mismatch-1.rs new file mode 100644 index 000000000..0da4aba30 --- /dev/null +++ b/src/test/ui/compare-method/traits-misc-mismatch-1.rs @@ -0,0 +1,71 @@ +// +// Make sure rustc checks the type parameter bounds in implementations of traits, +// see #2687 + +use std::marker; + +trait A { } + +trait B: A {} + +trait C: A {} + +trait Foo { + fn test_error1_fn<T: Eq>(&self); + fn test_error2_fn<T: Eq + Ord>(&self); + fn test_error3_fn<T: Eq + Ord>(&self); + fn test3_fn<T: Eq + Ord>(&self); + fn test4_fn<T: Eq + Ord>(&self); + fn test_error5_fn<T: A>(&self); + fn test6_fn<T: A + Eq>(&self); + fn test_error7_fn<T: A>(&self); + fn test_error8_fn<T: B>(&self); +} + +impl Foo for isize { + // invalid bound for T, was defined as Eq in trait + fn test_error1_fn<T: Ord>(&self) {} + //~^ ERROR E0276 + + // invalid bound for T, was defined as Eq + Ord in trait + fn test_error2_fn<T: Eq + B>(&self) {} + //~^ ERROR E0276 + + // invalid bound for T, was defined as Eq + Ord in trait + fn test_error3_fn<T: B + Eq>(&self) {} + //~^ ERROR E0276 + + // multiple bounds, same order as in trait + fn test3_fn<T: Ord + Eq>(&self) {} + + // multiple bounds, different order as in trait + fn test4_fn<T: Eq + Ord>(&self) {} + + // parameters in impls must be equal or more general than in the defining trait + fn test_error5_fn<T: B>(&self) {} + //~^ ERROR E0276 + + // bound `std::cmp::Eq` not enforced by this implementation, but this is OK + fn test6_fn<T: A>(&self) {} + + fn test_error7_fn<T: A + Eq>(&self) {} + //~^ ERROR E0276 + + fn test_error8_fn<T: C>(&self) {} + //~^ ERROR E0276 +} + +trait Getter<T> { + fn get(&self) -> T { loop { } } +} + +trait Trait { + fn method<G:Getter<isize>>(&self); +} + +impl Trait for usize { + fn method<G: Getter<usize>>(&self) {} + //~^ ERROR E0276 +} + +fn main() {} diff --git a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr new file mode 100644 index 000000000..805c04536 --- /dev/null +++ b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr @@ -0,0 +1,66 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:27:26 + | +LL | fn test_error1_fn<T: Eq>(&self); + | -------------------------------- definition of `test_error1_fn` from trait +... +LL | fn test_error1_fn<T: Ord>(&self) {} + | ^^^ impl has extra requirement `T: Ord` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:31:31 + | +LL | fn test_error2_fn<T: Eq + Ord>(&self); + | -------------------------------------- definition of `test_error2_fn` from trait +... +LL | fn test_error2_fn<T: Eq + B>(&self) {} + | ^ impl has extra requirement `T: B` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:35:26 + | +LL | fn test_error3_fn<T: Eq + Ord>(&self); + | -------------------------------------- definition of `test_error3_fn` from trait +... +LL | fn test_error3_fn<T: B + Eq>(&self) {} + | ^ impl has extra requirement `T: B` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:45:26 + | +LL | fn test_error5_fn<T: A>(&self); + | ------------------------------- definition of `test_error5_fn` from trait +... +LL | fn test_error5_fn<T: B>(&self) {} + | ^ impl has extra requirement `T: B` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:51:30 + | +LL | fn test_error7_fn<T: A>(&self); + | ------------------------------- definition of `test_error7_fn` from trait +... +LL | fn test_error7_fn<T: A + Eq>(&self) {} + | ^^ impl has extra requirement `T: Eq` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:54:26 + | +LL | fn test_error8_fn<T: B>(&self); + | ------------------------------- definition of `test_error8_fn` from trait +... +LL | fn test_error8_fn<T: C>(&self) {} + | ^ impl has extra requirement `T: C` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-1.rs:67:18 + | +LL | fn method<G:Getter<isize>>(&self); + | ---------------------------------- definition of `method` from trait +... +LL | fn method<G: Getter<usize>>(&self) {} + | ^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/traits-misc-mismatch-2.rs b/src/test/ui/compare-method/traits-misc-mismatch-2.rs new file mode 100644 index 000000000..d7f31c1d9 --- /dev/null +++ b/src/test/ui/compare-method/traits-misc-mismatch-2.rs @@ -0,0 +1,23 @@ +// Issue #5886: a complex instance of issue #2687. + +trait Iterator<A> { + fn next(&mut self) -> Option<A>; +} + +trait IteratorUtil<A>: Sized +{ + fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>; +} + +impl<A, T: Iterator<A>> IteratorUtil<A> for T { + fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> { + //~^ ERROR E0276 + ZipIterator{a: self, b: other} + } +} + +struct ZipIterator<T, U> { + a: T, b: U +} + +fn main() {} diff --git a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr new file mode 100644 index 000000000..36bb764d4 --- /dev/null +++ b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr @@ -0,0 +1,12 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/traits-misc-mismatch-2.rs:13:18 + | +LL | fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>; + | ------------------------------------------------------------------ definition of `zip` from trait +... +LL | fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> { + | ^^^^^^^^^^^ impl has extra requirement `U: Iterator<B>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. |