summaryrefslogtreecommitdiffstats
path: root/tests/ui/trait-bounds
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/trait-bounds')
-rw-r--r--tests/ui/trait-bounds/impl-bound-with-references-error.rs20
-rw-r--r--tests/ui/trait-bounds/impl-bound-with-references-error.stderr24
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.rs33
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr31
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound.rs36
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr31
-rw-r--r--tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs38
-rw-r--r--tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr36
-rw-r--r--tests/ui/trait-bounds/issue-75961.rs7
-rw-r--r--tests/ui/trait-bounds/issue-93008.rs15
-rw-r--r--tests/ui/trait-bounds/issue-94680.rs14
-rw-r--r--tests/ui/trait-bounds/issue-94999.rs34
-rw-r--r--tests/ui/trait-bounds/issue-95640.rs31
-rw-r--r--tests/ui/trait-bounds/mismatch-fn-trait.rs28
-rw-r--r--tests/ui/trait-bounds/mismatch-fn-trait.stderr81
-rw-r--r--tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed16
-rw-r--r--tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs14
-rw-r--r--tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr19
-rw-r--r--tests/ui/trait-bounds/unsized-bound.rs32
-rw-r--r--tests/ui/trait-bounds/unsized-bound.stderr273
20 files changed, 813 insertions, 0 deletions
diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.rs b/tests/ui/trait-bounds/impl-bound-with-references-error.rs
new file mode 100644
index 000000000..e5d0a1aae
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-bound-with-references-error.rs
@@ -0,0 +1,20 @@
+// Regression test for #105138.
+// This test ensures that the compiler does not add note
+// for implementation of trait whose inner type is erroneous.
+
+pub enum LabelText {
+ Plain,
+}
+
+impl<T> From<T> for LabelText
+//~^ ERROR conflicting implementations of trait `From<LabelText>` for type `LabelText` [E0119]
+where
+ T: Into<Cow<'static, str>>,
+ //~^ ERROR cannot find type `Cow` in this scope [E0412]
+{
+ fn from(text: T) -> Self {
+ LabelText::Plain(text.into())
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr
new file mode 100644
index 000000000..95fd6bd50
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr
@@ -0,0 +1,24 @@
+error[E0412]: cannot find type `Cow` in this scope
+ --> $DIR/impl-bound-with-references-error.rs:12:13
+ |
+LL | T: Into<Cow<'static, str>>,
+ | ^^^ not found in this scope
+ |
+help: consider importing this enum
+ |
+LL | use std::borrow::Cow;
+ |
+
+error[E0119]: conflicting implementations of trait `From<LabelText>` for type `LabelText`
+ --> $DIR/impl-bound-with-references-error.rs:9:1
+ |
+LL | impl<T> From<T> for LabelText
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: conflicting implementation in crate `core`:
+ - impl<T> From<T> for T;
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0412.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.rs b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.rs
new file mode 100644
index 000000000..557d89088
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.rs
@@ -0,0 +1,33 @@
+struct Victim<'a, T: Perpetrator + ?Sized> {
+ value: u8,
+ perp: &'a T,
+}
+
+trait VictimTrait {
+ type Ret;
+ fn get(self) -> Self::Ret;
+}
+
+// Actual fix is here
+impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ type Ret = u8;
+ fn get(self) -> Self::Ret {
+ self.value
+ }
+}
+
+trait Perpetrator {
+ fn getter<'a>(&'a self) -> Victim<'a, Self> {
+ Victim {
+ value: 0,
+ perp: self,
+ }
+ }
+
+ fn trigger(&self) {
+ self.getter().get();
+ //~^ ERROR the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
new file mode 100644
index 000000000..543ceac8e
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
@@ -0,0 +1,31 @@
+error[E0599]: the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
+ --> $DIR/impl-derived-implicit-sized-bound-2.rs:28:19
+ |
+LL | struct Victim<'a, T: Perpetrator + ?Sized> {
+ | ------------------------------------------
+ | |
+ | method `get` not found for this struct
+ | doesn't satisfy `Victim<'_, Self>: VictimTrait`
+...
+LL | self.getter().get();
+ | ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
+ |
+note: trait bound `Self: Sized` was not satisfied
+ --> $DIR/impl-derived-implicit-sized-bound-2.rs:12:10
+ |
+LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ | ^ ----------- -------------
+ | |
+ | unsatisfied trait bound introduced here
+help: consider relaxing the type parameter's implicit `Sized` bound
+ |
+LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ | ++++++++
+help: consider restricting the type parameter to satisfy the trait bound
+ |
+LL | struct Victim<'a, T: Perpetrator + ?Sized> where Self: Sized {
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.rs b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.rs
new file mode 100644
index 000000000..28da41a0c
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.rs
@@ -0,0 +1,36 @@
+struct Victim<'a, T: Perpetrator + ?Sized>
+where
+ Self: Sized
+{
+ value: u8,
+ perp: &'a T,
+}
+
+trait VictimTrait {
+ type Ret;
+ fn get(self) -> Self::Ret;
+}
+
+// Actual fix is here
+impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ type Ret = u8;
+ fn get(self) -> Self::Ret {
+ self.value
+ }
+}
+
+trait Perpetrator {
+ fn getter<'a>(&'a self) -> Victim<'a, Self> {
+ Victim {
+ value: 0,
+ perp: self,
+ }
+ }
+
+ fn trigger(&self) {
+ self.getter().get();
+ //~^ ERROR the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
new file mode 100644
index 000000000..f08d68583
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
@@ -0,0 +1,31 @@
+error[E0599]: the method `get` exists for struct `Victim<'_, Self>`, but its trait bounds were not satisfied
+ --> $DIR/impl-derived-implicit-sized-bound.rs:31:19
+ |
+LL | struct Victim<'a, T: Perpetrator + ?Sized>
+ | ------------------------------------------
+ | |
+ | method `get` not found for this struct
+ | doesn't satisfy `Victim<'_, Self>: VictimTrait`
+...
+LL | self.getter().get();
+ | ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
+ |
+note: trait bound `Self: Sized` was not satisfied
+ --> $DIR/impl-derived-implicit-sized-bound.rs:15:10
+ |
+LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ | ^ ----------- -------------
+ | |
+ | unsatisfied trait bound introduced here
+help: consider relaxing the type parameter's implicit `Sized` bound
+ |
+LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
+ | ++++++++
+help: consider restricting the type parameter to satisfy the trait bound
+ |
+LL | Self: Sized, Self: Sized
+ | +++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs
new file mode 100644
index 000000000..dcdbd0228
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs
@@ -0,0 +1,38 @@
+trait Trait<T> {
+ fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a;
+}
+
+impl Trait<()> for () {
+ fn foo<'a, K>(self, _: (), _: K) where { //~ ERROR E0195
+ todo!();
+ }
+}
+
+struct State;
+
+trait Foo<T> {
+ fn foo<'a>(&self, state: &'a State) -> &'a T
+ where
+ T: 'a;
+}
+
+impl<F, T> Foo<T> for F
+where
+ F: Fn(&State) -> &T,
+{
+ fn foo<'a>(&self, state: &'a State) -> &'a T { //~ ERROR E0195
+ self(state)
+ }
+}
+
+trait Bar {
+ fn foo<'a>(&'a self) {}
+}
+
+impl Bar for () {
+ fn foo<'a: 'a>(&'a self) {} //~ ERROR E0195
+}
+
+fn main() {
+ ().foo((), ());
+}
diff --git a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
new file mode 100644
index 000000000..e26cb2216
--- /dev/null
+++ b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
@@ -0,0 +1,36 @@
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:6:11
+ |
+LL | fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a;
+ | ------- -- -- this bound might be missing in the impl
+ | | |
+ | | this bound might be missing in the impl
+ | lifetimes in impl do not match this method in trait
+...
+LL | fn foo<'a, K>(self, _: (), _: K) where {
+ | ^^^^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:11
+ |
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T
+ | ---- lifetimes in impl do not match this method in trait
+LL | where
+LL | T: 'a;
+ | -- this bound might be missing in the impl
+...
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T {
+ | ^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:11
+ |
+LL | fn foo<'a>(&'a self) {}
+ | ---- lifetimes in impl do not match this method in trait
+...
+LL | fn foo<'a: 'a>(&'a self) {}
+ | ^^^^^^^^ lifetimes do not match method in trait
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/trait-bounds/issue-75961.rs b/tests/ui/trait-bounds/issue-75961.rs
new file mode 100644
index 000000000..367eac718
--- /dev/null
+++ b/tests/ui/trait-bounds/issue-75961.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
+ <&mut () as Clone>::clone(&s);
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/issue-93008.rs b/tests/ui/trait-bounds/issue-93008.rs
new file mode 100644
index 000000000..f4d21a160
--- /dev/null
+++ b/tests/ui/trait-bounds/issue-93008.rs
@@ -0,0 +1,15 @@
+// build-pass
+// compile-flags: -Zmir-opt-level=3 --crate-type=lib
+
+#![feature(trivial_bounds)]
+#![allow(trivial_bounds)]
+
+trait Foo {
+ fn test(self);
+}
+fn baz<T>()
+where
+ &'static str: Foo,
+{
+ "Foo".test()
+}
diff --git a/tests/ui/trait-bounds/issue-94680.rs b/tests/ui/trait-bounds/issue-94680.rs
new file mode 100644
index 000000000..58e892079
--- /dev/null
+++ b/tests/ui/trait-bounds/issue-94680.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+fn main() {
+ println!("{:?}", {
+ type T = ();
+
+ pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
+ where
+ for<'any> &'any mut T: Clone,
+ {
+ (it.clone(), it)
+ }
+ });
+}
diff --git a/tests/ui/trait-bounds/issue-94999.rs b/tests/ui/trait-bounds/issue-94999.rs
new file mode 100644
index 000000000..e13190234
--- /dev/null
+++ b/tests/ui/trait-bounds/issue-94999.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+trait Identity<Q> {
+ type T;
+}
+
+impl<Q, T> Identity<Q> for T {
+ type T = T;
+}
+
+trait Holds {
+ type Q;
+}
+
+struct S;
+struct X(S);
+
+struct XHelper;
+
+impl Holds for X {
+ type Q = XHelper;
+}
+
+impl<Q> Clone for X
+where
+ <S as Identity<Q>>::T: Clone,
+ X: Holds<Q = Q>,
+{
+ fn clone(&self) -> Self {
+ Self(self.0.clone())
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/issue-95640.rs b/tests/ui/trait-bounds/issue-95640.rs
new file mode 100644
index 000000000..e4e998b5d
--- /dev/null
+++ b/tests/ui/trait-bounds/issue-95640.rs
@@ -0,0 +1,31 @@
+// build-pass
+// compile-flags:-Zmir-opt-level=3
+
+struct D;
+
+trait Tr {
+ type It;
+ fn foo(self) -> Option<Self::It>;
+}
+
+impl<'a> Tr for &'a D {
+ type It = ();
+ fn foo(self) -> Option<()> {
+ None
+ }
+}
+
+fn run<F>(f: F)
+where
+ for<'a> &'a D: Tr,
+ F: Fn(<&D as Tr>::It),
+{
+ let d = &D;
+ while let Some(i) = d.foo() {
+ f(i);
+ }
+}
+
+fn main() {
+ run(|_| {});
+}
diff --git a/tests/ui/trait-bounds/mismatch-fn-trait.rs b/tests/ui/trait-bounds/mismatch-fn-trait.rs
new file mode 100644
index 000000000..0ed64043a
--- /dev/null
+++ b/tests/ui/trait-bounds/mismatch-fn-trait.rs
@@ -0,0 +1,28 @@
+fn take(_f: impl FnMut(i32)) {}
+
+fn test1(f: impl FnMut(u32)) {
+ take(f)
+ //~^ ERROR [E0277]
+}
+
+fn test2(f: impl FnMut(i32, i32)) {
+ take(f)
+ //~^ ERROR [E0277]
+}
+
+fn test3(f: impl FnMut()) {
+ take(f)
+ //~^ ERROR [E0277]
+}
+
+fn test4(f: impl FnOnce(i32)) {
+ take(f)
+ //~^ ERROR [E0277]
+}
+
+fn test5(f: impl FnOnce(u32)) {
+ take(f)
+ //~^ ERROR [E0277]
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/mismatch-fn-trait.stderr b/tests/ui/trait-bounds/mismatch-fn-trait.stderr
new file mode 100644
index 000000000..961e6d88f
--- /dev/null
+++ b/tests/ui/trait-bounds/mismatch-fn-trait.stderr
@@ -0,0 +1,81 @@
+error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut(u32)`
+ --> $DIR/mismatch-fn-trait.rs:4:10
+ |
+LL | take(f)
+ | ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut(u32)`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected a closure with arguments `(u32,)`
+ found a closure with arguments `(i32,)`
+note: required by a bound in `take`
+ --> $DIR/mismatch-fn-trait.rs:1:18
+ |
+LL | fn take(_f: impl FnMut(i32)) {}
+ | ^^^^^^^^^^ required by this bound in `take`
+
+error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut(i32, i32)`
+ --> $DIR/mismatch-fn-trait.rs:9:10
+ |
+LL | take(f)
+ | ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut(i32, i32)`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected a closure taking 2 arguments, but one taking 1 argument was given
+note: required by a bound in `take`
+ --> $DIR/mismatch-fn-trait.rs:1:18
+ |
+LL | fn take(_f: impl FnMut(i32)) {}
+ | ^^^^^^^^^^ required by this bound in `take`
+
+error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnMut()`
+ --> $DIR/mismatch-fn-trait.rs:14:10
+ |
+LL | take(f)
+ | ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnMut()`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected a closure taking 0 arguments, but one taking 1 argument was given
+note: required by a bound in `take`
+ --> $DIR/mismatch-fn-trait.rs:1:18
+ |
+LL | fn take(_f: impl FnMut(i32)) {}
+ | ^^^^^^^^^^ required by this bound in `take`
+
+error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnOnce(i32)`
+ --> $DIR/mismatch-fn-trait.rs:19:10
+ |
+LL | take(f)
+ | ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnOnce(i32)`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: `impl FnOnce(i32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
+note: required by a bound in `take`
+ --> $DIR/mismatch-fn-trait.rs:1:18
+ |
+LL | fn take(_f: impl FnMut(i32)) {}
+ | ^^^^^^^^^^ required by this bound in `take`
+
+error[E0277]: expected a `FnMut<(i32,)>` closure, found `impl FnOnce(u32)`
+ --> $DIR/mismatch-fn-trait.rs:24:10
+ |
+LL | take(f)
+ | ---- ^ expected an `FnMut<(i32,)>` closure, found `impl FnOnce(u32)`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: `impl FnOnce(u32)` implements `FnOnce`, but it must implement `FnMut`, which is more general
+ = note: expected a closure with arguments `(u32,)`
+ found a closure with arguments `(i32,)`
+note: required by a bound in `take`
+ --> $DIR/mismatch-fn-trait.rs:1:18
+ |
+LL | fn take(_f: impl FnMut(i32)) {}
+ | ^^^^^^^^^^ required by this bound in `take`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed
new file mode 100644
index 000000000..39e90d7a3
--- /dev/null
+++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed
@@ -0,0 +1,16 @@
+// run-rustfix
+#![allow(non_snake_case)]
+mod A {
+ pub trait Trait {}
+ impl Trait for i32 {}
+}
+
+mod B {
+ use A::Trait;
+
+pub struct A<H: Trait>(pub H); //~ ERROR cannot find trait
+}
+
+fn main() {
+ let _ = B::A(42);
+}
diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs
new file mode 100644
index 000000000..ee6ed0cae
--- /dev/null
+++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+#![allow(non_snake_case)]
+mod A {
+ pub trait Trait {}
+ impl Trait for i32 {}
+}
+
+mod B {
+ pub struct A<H: A::Trait>(pub H); //~ ERROR cannot find trait
+}
+
+fn main() {
+ let _ = B::A(42);
+}
diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr
new file mode 100644
index 000000000..b29766295
--- /dev/null
+++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr
@@ -0,0 +1,19 @@
+error[E0405]: cannot find trait `Trait` in `A`
+ --> $DIR/shadowed-path-in-trait-bound-suggestion.rs:9:24
+ |
+LL | pub struct A<H: A::Trait>(pub H);
+ | ^^^^^ not found in `A`
+ |
+help: consider importing this trait
+ |
+LL | use A::Trait;
+ |
+help: if you import `Trait`, refer to it directly
+ |
+LL - pub struct A<H: A::Trait>(pub H);
+LL + pub struct A<H: Trait>(pub H);
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/trait-bounds/unsized-bound.rs b/tests/ui/trait-bounds/unsized-bound.rs
new file mode 100644
index 000000000..035b8ef1b
--- /dev/null
+++ b/tests/ui/trait-bounds/unsized-bound.rs
@@ -0,0 +1,32 @@
+trait Trait<A> {}
+impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+//~^ ERROR E0277
+//~| ERROR E0277
+impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+//~^ ERROR E0277
+//~| ERROR E0277
+//~| ERROR E0277
+trait Trait2<A> {}
+impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+//~^ ERROR E0277
+//~| ERROR E0277
+trait Trait3<A> {}
+impl<A> Trait3<A> for A where A: ?Sized {}
+//~^ ERROR E0277
+trait Trait4<A> {}
+impl<A: ?Sized> Trait4<A> for A {}
+//~^ ERROR E0277
+trait Trait5<A, B> {}
+impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
+//~^ ERROR E0277
+trait Trait6<A, B> {}
+impl<X: ?Sized, Y> Trait6<X, Y> for X {}
+//~^ ERROR E0277
+trait Trait7<A, B> {}
+impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
+//~^ ERROR E0277
+trait Trait8<A, B> {}
+impl<X, Y: ?Sized> Trait8<X, Y> for X {}
+//~^ ERROR E0277
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/unsized-bound.stderr b/tests/ui/trait-bounds/unsized-bound.stderr
new file mode 100644
index 000000000..da27ba1c5
--- /dev/null
+++ b/tests/ui/trait-bounds/unsized-bound.stderr
@@ -0,0 +1,273 @@
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:2:30
+ |
+LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+ | - ^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: required because it appears within the type `(A, B)`
+note: required by a bound in `Trait`
+ --> $DIR/unsized-bound.rs:1:13
+ |
+LL | trait Trait<A> {}
+ | ^ required by this bound in `Trait`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+LL + impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait<A: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:2:30
+ |
+LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+ | - ^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
+ |
+
+error[E0277]: the size for values of type `C` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:5:52
+ |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+ | - ^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: required because it appears within the type `(A, B, C)`
+note: required by a bound in `Trait`
+ --> $DIR/unsized-bound.rs:1:13
+ |
+LL | trait Trait<A> {}
+ | ^ required by this bound in `Trait`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+LL + impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait<A: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:5:52
+ |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+ | - ^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
+ |
+
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:5:52
+ |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+ | - ^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+ |
+
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:10:47
+ |
+LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+ | - ^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: required because it appears within the type `(A, B)`
+note: required by a bound in `Trait2`
+ --> $DIR/unsized-bound.rs:9:14
+ |
+LL | trait Trait2<A> {}
+ | ^ required by this bound in `Trait2`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+LL + impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait2<A: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:10:47
+ |
+LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+ | - ^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+ = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+ |
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:14:23
+ |
+LL | impl<A> Trait3<A> for A where A: ?Sized {}
+ | - ^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait3`
+ --> $DIR/unsized-bound.rs:13:14
+ |
+LL | trait Trait3<A> {}
+ | ^ required by this bound in `Trait3`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A> Trait3<A> for A where A: ?Sized {}
+LL + impl<A> Trait3<A> for A {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait3<A: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:17:31
+ |
+LL | impl<A: ?Sized> Trait4<A> for A {}
+ | - ^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait4`
+ --> $DIR/unsized-bound.rs:16:14
+ |
+LL | trait Trait4<A> {}
+ | ^ required by this bound in `Trait4`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<A: ?Sized> Trait4<A> for A {}
+LL + impl<A> Trait4<A> for A {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait4<A: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `X` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:20:29
+ |
+LL | impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
+ | - ^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait5`
+ --> $DIR/unsized-bound.rs:19:14
+ |
+LL | trait Trait5<A, B> {}
+ | ^ required by this bound in `Trait5`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
+LL + impl<X, Y> Trait5<X, Y> for X {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait5<A: ?Sized, B> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `X` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:23:37
+ |
+LL | impl<X: ?Sized, Y> Trait6<X, Y> for X {}
+ | - ^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait6`
+ --> $DIR/unsized-bound.rs:22:14
+ |
+LL | trait Trait6<A, B> {}
+ | ^ required by this bound in `Trait6`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<X: ?Sized, Y> Trait6<X, Y> for X {}
+LL + impl<X, Y> Trait6<X, Y> for X {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait6<A: ?Sized, B> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `Y` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:26:12
+ |
+LL | impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
+ | - ^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait7`
+ --> $DIR/unsized-bound.rs:25:17
+ |
+LL | trait Trait7<A, B> {}
+ | ^ required by this bound in `Trait7`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
+LL + impl<X, Y> Trait7<X, Y> for X {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait7<A, B: ?Sized> {}
+ | ++++++++
+
+error[E0277]: the size for values of type `Y` cannot be known at compilation time
+ --> $DIR/unsized-bound.rs:29:20
+ |
+LL | impl<X, Y: ?Sized> Trait8<X, Y> for X {}
+ | - ^^^^^^^^^^^^ doesn't have a size known at compile-time
+ | |
+ | this type parameter needs to be `std::marker::Sized`
+ |
+note: required by a bound in `Trait8`
+ --> $DIR/unsized-bound.rs:28:17
+ |
+LL | trait Trait8<A, B> {}
+ | ^ required by this bound in `Trait8`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - impl<X, Y: ?Sized> Trait8<X, Y> for X {}
+LL + impl<X, Y> Trait8<X, Y> for X {}
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait Trait8<A, B: ?Sized> {}
+ | ++++++++
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0277`.