summaryrefslogtreecommitdiffstats
path: root/src/test/ui/wf
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/wf/hir-wf-check-erase-regions.rs14
-rw-r--r--src/test/ui/wf/hir-wf-check-erase-regions.stderr33
-rw-r--r--src/test/ui/wf/issue-48638.rs21
-rw-r--r--src/test/ui/wf/issue-87495.rs8
-rw-r--r--src/test/ui/wf/issue-87495.stderr18
-rw-r--r--src/test/ui/wf/issue-95665.rs18
-rw-r--r--src/test/ui/wf/issue-95665.stderr15
-rw-r--r--src/test/ui/wf/issue-96810.rs12
-rw-r--r--src/test/ui/wf/issue-96810.stderr19
-rw-r--r--src/test/ui/wf/wf-array-elem-sized.rs11
-rw-r--r--src/test/ui/wf/wf-array-elem-sized.stderr12
-rw-r--r--src/test/ui/wf/wf-complex-assoc-type.rs12
-rw-r--r--src/test/ui/wf/wf-complex-assoc-type.stderr15
-rw-r--r--src/test/ui/wf/wf-const-type.rs14
-rw-r--r--src/test/ui/wf/wf-const-type.stderr20
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs18
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr51
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.rs18
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr51
-rw-r--r--src/test/ui/wf/wf-enum-bound.rs16
-rw-r--r--src/test/ui/wf/wf-enum-bound.stderr19
-rw-r--r--src/test/ui/wf/wf-enum-fields-struct-variant.rs18
-rw-r--r--src/test/ui/wf/wf-enum-fields-struct-variant.stderr19
-rw-r--r--src/test/ui/wf/wf-enum-fields.rs16
-rw-r--r--src/test/ui/wf/wf-enum-fields.stderr19
-rw-r--r--src/test/ui/wf/wf-fn-where-clause.rs20
-rw-r--r--src/test/ui/wf/wf-fn-where-clause.stderr49
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.rs18
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.stderr21
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-region.rs14
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-region.stderr14
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-trait.rs22
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-trait.stderr19
-rw-r--r--src/test/ui/wf/wf-impl-self-type.rs7
-rw-r--r--src/test/ui/wf/wf-impl-self-type.stderr16
-rw-r--r--src/test/ui/wf/wf-in-fn-arg.rs14
-rw-r--r--src/test/ui/wf/wf-in-fn-arg.stderr19
-rw-r--r--src/test/ui/wf/wf-in-fn-ret.rs14
-rw-r--r--src/test/ui/wf/wf-in-fn-ret.stderr19
-rw-r--r--src/test/ui/wf/wf-in-fn-type-arg.rs12
-rw-r--r--src/test/ui/wf/wf-in-fn-type-arg.stderr19
-rw-r--r--src/test/ui/wf/wf-in-fn-type-ret.rs12
-rw-r--r--src/test/ui/wf/wf-in-fn-type-ret.stderr19
-rw-r--r--src/test/ui/wf/wf-in-fn-type-static.rs22
-rw-r--r--src/test/ui/wf/wf-in-fn-type-static.stderr25
-rw-r--r--src/test/ui/wf/wf-in-fn-where-clause.rs15
-rw-r--r--src/test/ui/wf/wf-in-fn-where-clause.stderr19
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs17
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr37
-rw-r--r--src/test/ui/wf/wf-in-obj-type-static.rs18
-rw-r--r--src/test/ui/wf/wf-in-obj-type-static.stderr14
-rw-r--r--src/test/ui/wf/wf-in-obj-type-trait.rs14
-rw-r--r--src/test/ui/wf/wf-in-obj-type-trait.stderr19
-rw-r--r--src/test/ui/wf/wf-inherent-impl-method-where-clause.rs17
-rw-r--r--src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr19
-rw-r--r--src/test/ui/wf/wf-inherent-impl-where-clause.rs16
-rw-r--r--src/test/ui/wf/wf-inherent-impl-where-clause.stderr19
-rw-r--r--src/test/ui/wf/wf-misc-methods-issue-28609.rs74
-rw-r--r--src/test/ui/wf/wf-misc-methods-issue-28609.stderr55
-rw-r--r--src/test/ui/wf/wf-object-safe.rs10
-rw-r--r--src/test/ui/wf/wf-object-safe.stderr18
-rw-r--r--src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs22
-rw-r--r--src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr25
-rw-r--r--src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs31
-rw-r--r--src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr9
-rw-r--r--src/test/ui/wf/wf-static-method.rs59
-rw-r--r--src/test/ui/wf/wf-static-method.stderr77
-rw-r--r--src/test/ui/wf/wf-static-type.rs14
-rw-r--r--src/test/ui/wf/wf-static-type.stderr20
-rw-r--r--src/test/ui/wf/wf-struct-bound.rs16
-rw-r--r--src/test/ui/wf/wf-struct-bound.stderr19
-rw-r--r--src/test/ui/wf/wf-struct-field.rs16
-rw-r--r--src/test/ui/wf/wf-struct-field.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-bound.rs14
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-bound.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-region.rs14
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-region.stderr12
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-trait.rs16
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-trait.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-bound.rs15
-rw-r--r--src/test/ui/wf/wf-trait-bound.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-arg.rs19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-arg.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-ret.rs19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-ret.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-where-clause.rs19
-rw-r--r--src/test/ui/wf/wf-trait-default-fn-where-clause.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-fn-arg.rs16
-rw-r--r--src/test/ui/wf/wf-trait-fn-arg.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-fn-ret.rs16
-rw-r--r--src/test/ui/wf/wf-trait-fn-ret.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-fn-where-clause.rs17
-rw-r--r--src/test/ui/wf/wf-trait-fn-where-clause.stderr19
-rw-r--r--src/test/ui/wf/wf-trait-superbound.rs12
-rw-r--r--src/test/ui/wf/wf-trait-superbound.stderr19
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.rs29
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr54
97 files changed, 2032 insertions, 0 deletions
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.rs b/src/test/ui/wf/hir-wf-check-erase-regions.rs
new file mode 100644
index 000000000..2b4b480df
--- /dev/null
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.rs
@@ -0,0 +1,14 @@
+// Regression test for #87549.
+// incremental
+
+pub struct Table<T, const N: usize>([Option<T>; N]);
+
+impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
+ type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; //~ ERROR `&T` is not an iterator
+ type Item = &'a T;
+
+ fn into_iter(self) -> Self::IntoIter { //~ ERROR `&T` is not an iterator
+ unimplemented!()
+ }
+}
+fn main() {}
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.stderr b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
new file mode 100644
index 000000000..037f8b9f3
--- /dev/null
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
@@ -0,0 +1,33 @@
+error[E0277]: `&T` is not an iterator
+ --> $DIR/hir-wf-check-erase-regions.rs:7:21
+ |
+LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&T` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `&T`
+ = help: the trait `Iterator` is implemented for `&mut I`
+ = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+note: required by a bound in `Flatten`
+ --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
+ |
+LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
+ | ^^^^^^^^^^^^ required by this bound in `Flatten`
+
+error[E0277]: `&T` is not an iterator
+ --> $DIR/hir-wf-check-erase-regions.rs:10:27
+ |
+LL | fn into_iter(self) -> Self::IntoIter {
+ | ^^^^^^^^^^^^^^ `&T` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `&T`
+ = help: the trait `Iterator` is implemented for `&mut I`
+ = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+note: required by a bound in `Flatten`
+ --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
+ |
+LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
+ | ^^^^^^^^^^^^ required by this bound in `Flatten`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/issue-48638.rs b/src/test/ui/wf/issue-48638.rs
new file mode 100644
index 000000000..f07843103
--- /dev/null
+++ b/src/test/ui/wf/issue-48638.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+pub trait D {}
+pub struct DT;
+impl D for DT {}
+
+pub trait A<R: D>: Sized {
+ type AS;
+}
+
+pub struct As<R: D>(R);
+
+pub struct AT;
+impl<R: D> A<R> for AT {
+ type AS = As<R>;
+}
+
+#[repr(packed)]
+struct S(<AT as A<DT>>::AS);
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-87495.rs b/src/test/ui/wf/issue-87495.rs
new file mode 100644
index 000000000..5aab74311
--- /dev/null
+++ b/src/test/ui/wf/issue-87495.rs
@@ -0,0 +1,8 @@
+// Regression test for the ICE described in #87495.
+
+trait T {
+ const CONST: (bool, dyn T);
+ //~^ ERROR: the trait `T` cannot be made into an object [E0038]
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-87495.stderr b/src/test/ui/wf/issue-87495.stderr
new file mode 100644
index 000000000..c924cd879
--- /dev/null
+++ b/src/test/ui/wf/issue-87495.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `T` cannot be made into an object
+ --> $DIR/issue-87495.rs:4:25
+ |
+LL | const CONST: (bool, dyn T);
+ | ^^^^^ `T` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-87495.rs:4:11
+ |
+LL | trait T {
+ | - this trait cannot be made into an object...
+LL | const CONST: (bool, dyn T);
+ | ^^^^^ ...because it contains this associated `const`
+ = help: consider moving `CONST` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/issue-95665.rs b/src/test/ui/wf/issue-95665.rs
new file mode 100644
index 000000000..67923cbb2
--- /dev/null
+++ b/src/test/ui/wf/issue-95665.rs
@@ -0,0 +1,18 @@
+// Regression test for the ICE described in #95665.
+// Ensure that the expected error is output (and thus that there is no ICE)
+
+pub trait Trait: {}
+
+pub struct Struct<T: Trait> {
+ member: T,
+}
+
+// uncomment and bug goes away
+// impl Trait for u8 {}
+
+extern "C" {
+ static VAR: Struct<u8>;
+ //~^ 14:17: 14:27: the trait bound `u8: Trait` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-95665.stderr b/src/test/ui/wf/issue-95665.stderr
new file mode 100644
index 000000000..b1cda59a9
--- /dev/null
+++ b/src/test/ui/wf/issue-95665.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u8: Trait` is not satisfied
+ --> $DIR/issue-95665.rs:14:17
+ |
+LL | static VAR: Struct<u8>;
+ | ^^^^^^^^^^ the trait `Trait` is not implemented for `u8`
+ |
+note: required by a bound in `Struct`
+ --> $DIR/issue-95665.rs:6:22
+ |
+LL | pub struct Struct<T: Trait> {
+ | ^^^^^ required by this bound in `Struct`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/issue-96810.rs b/src/test/ui/wf/issue-96810.rs
new file mode 100644
index 000000000..c2948086b
--- /dev/null
+++ b/src/test/ui/wf/issue-96810.rs
@@ -0,0 +1,12 @@
+struct S<T: Tr>(T::Assoc);
+
+trait Tr {
+ type Assoc;
+}
+
+struct Hoge<K> {
+ s: S<K>, //~ ERROR the trait bound `K: Tr` is not satisfied
+ a: u32,
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-96810.stderr b/src/test/ui/wf/issue-96810.stderr
new file mode 100644
index 000000000..1407e62b1
--- /dev/null
+++ b/src/test/ui/wf/issue-96810.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `K: Tr` is not satisfied
+ --> $DIR/issue-96810.rs:8:8
+ |
+LL | s: S<K>,
+ | ^^^^ the trait `Tr` is not implemented for `K`
+ |
+note: required by a bound in `S`
+ --> $DIR/issue-96810.rs:1:13
+ |
+LL | struct S<T: Tr>(T::Assoc);
+ | ^^ required by this bound in `S`
+help: consider restricting type parameter `K`
+ |
+LL | struct Hoge<K: Tr> {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-array-elem-sized.rs b/src/test/ui/wf/wf-array-elem-sized.rs
new file mode 100644
index 000000000..34bf22034
--- /dev/null
+++ b/src/test/ui/wf/wf-array-elem-sized.rs
@@ -0,0 +1,11 @@
+// Check that array element types must be Sized. Issue #25692.
+
+
+#![allow(dead_code)]
+
+struct Foo {
+ foo: [[u8]], //~ ERROR E0277
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-array-elem-sized.stderr b/src/test/ui/wf/wf-array-elem-sized.stderr
new file mode 100644
index 000000000..7f3c58d6b
--- /dev/null
+++ b/src/test/ui/wf/wf-array-elem-sized.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/wf-array-elem-sized.rs:7:10
+ |
+LL | foo: [[u8]],
+ | ^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: slice and array elements must have `Sized` type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-complex-assoc-type.rs b/src/test/ui/wf/wf-complex-assoc-type.rs
new file mode 100644
index 000000000..c3811e823
--- /dev/null
+++ b/src/test/ui/wf/wf-complex-assoc-type.rs
@@ -0,0 +1,12 @@
+trait MyTrait {}
+struct AssertMyTrait<T: MyTrait>(T);
+
+trait HelperTrait {
+ type MyItem;
+}
+
+impl HelperTrait for () {
+ type MyItem = Option<((AssertMyTrait<bool>, u8))>; //~ ERROR the trait bound
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-complex-assoc-type.stderr b/src/test/ui/wf/wf-complex-assoc-type.stderr
new file mode 100644
index 000000000..ef613e313
--- /dev/null
+++ b/src/test/ui/wf/wf-complex-assoc-type.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `bool: MyTrait` is not satisfied
+ --> $DIR/wf-complex-assoc-type.rs:9:28
+ |
+LL | type MyItem = Option<((AssertMyTrait<bool>, u8))>;
+ | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `bool`
+ |
+note: required by a bound in `AssertMyTrait`
+ --> $DIR/wf-complex-assoc-type.rs:2:25
+ |
+LL | struct AssertMyTrait<T: MyTrait>(T);
+ | ^^^^^^^ required by this bound in `AssertMyTrait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-const-type.rs b/src/test/ui/wf/wf-const-type.rs
new file mode 100644
index 000000000..df79aa267
--- /dev/null
+++ b/src/test/ui/wf/wf-const-type.rs
@@ -0,0 +1,14 @@
+// Test that we check the types of constants are well-formed.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> { t: T }
+struct NotCopy;
+
+const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+//~^ ERROR E0277
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-const-type.stderr b/src/test/ui/wf/wf-const-type.stderr
new file mode 100644
index 000000000..e47920d3d
--- /dev/null
+++ b/src/test/ui/wf/wf-const-type.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
+ --> $DIR/wf-const-type.rs:10:12
+ |
+LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
+ |
+ = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-const-type.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> { t: T }
+ | ^^^^ required by this bound in `IsCopy`
+help: consider annotating `NotCopy` with `#[derive(Copy)]`
+ |
+LL | #[derive(Copy)]
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
new file mode 100644
index 000000000..ffdb49a3b
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
@@ -0,0 +1,18 @@
+// Check that we do not allow casts or coercions
+// to object unsafe trait objects inside a Box
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+fn takes_box(t: Box<dyn Trait>) {}
+
+fn main() {
+ Box::new(S) as Box<dyn Trait>; //~ ERROR E0038
+ let t_box: Box<dyn Trait> = Box::new(S); //~ ERROR E0038
+ takes_box(Box::new(S)); //~ ERROR E0038
+}
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
new file mode 100644
index 000000000..29dfb585a
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -0,0 +1,51 @@
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
+ |
+LL | let t_box: Box<dyn Trait> = Box::new(S);
+ | ^^^^^^^^^^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required by cast to type `Box<dyn Trait>`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
+ |
+LL | takes_box(Box::new(S));
+ | ^^^^^^^^^^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required by cast to type `Box<(dyn Trait + 'static)>`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
+ |
+LL | Box::new(S) as Box<dyn Trait>;
+ | ^^^^^^^^^^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+ = note: required by cast to type `Box<dyn Trait>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
new file mode 100644
index 000000000..143b854ed
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
@@ -0,0 +1,18 @@
+// Check that we do not allow casts or coercions
+// to object unsafe trait objects by ref
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+fn takes_trait(t: &dyn Trait) {}
+
+fn main() {
+ &S as &dyn Trait; //~ ERROR E0038
+ let t: &dyn Trait = &S; //~ ERROR E0038
+ takes_trait(&S); //~ ERROR E0038
+}
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
new file mode 100644
index 000000000..02169f26f
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -0,0 +1,51 @@
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
+ |
+LL | let t: &dyn Trait = &S;
+ | ^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
+ |
+LL | takes_trait(&S);
+ | ^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
+ |
+LL | &S as &dyn Trait;
+ | ^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required by cast to type `&dyn Trait`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-enum-bound.rs b/src/test/ui/wf/wf-enum-bound.rs
new file mode 100644
index 000000000..042a2cb09
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-bound.rs
@@ -0,0 +1,16 @@
+// Test that we check enum bounds for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+enum SomeEnum<T,U>
+ where T: ExtraCopy<U> //~ ERROR E0277
+{
+ SomeVariant(T,U)
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr
new file mode 100644
index 000000000..d39fc0c6a
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-bound.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-enum-bound.rs:10:14
+ |
+LL | where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-enum-bound.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | where T: ExtraCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-enum-fields-struct-variant.rs b/src/test/ui/wf/wf-enum-fields-struct-variant.rs
new file mode 100644
index 000000000..c25622fa7
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-fields-struct-variant.rs
@@ -0,0 +1,18 @@
+// Test that we check struct fields for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> {
+ value: T
+}
+
+enum AnotherEnum<A> {
+ AnotherVariant {
+ f: IsCopy<A> //~ ERROR E0277
+ }
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
new file mode 100644
index 000000000..c12d62521
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `A: Copy` is not satisfied
+ --> $DIR/wf-enum-fields-struct-variant.rs:13:12
+ |
+LL | f: IsCopy<A>
+ | ^^^^^^^^^ the trait `Copy` is not implemented for `A`
+ |
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-enum-fields-struct-variant.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> {
+ | ^^^^ required by this bound in `IsCopy`
+help: consider restricting type parameter `A`
+ |
+LL | enum AnotherEnum<A: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-enum-fields.rs b/src/test/ui/wf/wf-enum-fields.rs
new file mode 100644
index 000000000..a465ffe5e
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-fields.rs
@@ -0,0 +1,16 @@
+// Test that we check struct fields for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> {
+ value: T
+}
+
+enum SomeEnum<A> {
+ SomeVariant(IsCopy<A>) //~ ERROR E0277
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-enum-fields.stderr b/src/test/ui/wf/wf-enum-fields.stderr
new file mode 100644
index 000000000..ac3301a96
--- /dev/null
+++ b/src/test/ui/wf/wf-enum-fields.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `A: Copy` is not satisfied
+ --> $DIR/wf-enum-fields.rs:12:17
+ |
+LL | SomeVariant(IsCopy<A>)
+ | ^^^^^^^^^ the trait `Copy` is not implemented for `A`
+ |
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-enum-fields.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> {
+ | ^^^^ required by this bound in `IsCopy`
+help: consider restricting type parameter `A`
+ |
+LL | enum SomeEnum<A: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-fn-where-clause.rs b/src/test/ui/wf/wf-fn-where-clause.rs
new file mode 100644
index 000000000..adae53613
--- /dev/null
+++ b/src/test/ui/wf/wf-fn-where-clause.rs
@@ -0,0 +1,20 @@
+// Test that we check where-clauses on fn items.
+
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+fn foo<T,U>() where T: ExtraCopy<U> //~ ERROR E0277
+{
+}
+
+fn bar() where Vec<dyn Copy>:, {}
+//~^ ERROR E0277
+//~| ERROR E0038
+
+struct Vec<T> {
+ t: T,
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr
new file mode 100644
index 000000000..2aec641e7
--- /dev/null
+++ b/src/test/ui/wf/wf-fn-where-clause.stderr
@@ -0,0 +1,49 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-fn-where-clause.rs:8:24
+ |
+LL | fn foo<T,U>() where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-fn-where-clause.rs:6:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | fn foo<T,U>() where T: ExtraCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time
+ --> $DIR/wf-fn-where-clause.rs:12:16
+ |
+LL | fn bar() where Vec<dyn Copy>:, {}
+ | ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)`
+note: required by a bound in `Vec`
+ --> $DIR/wf-fn-where-clause.rs:16:12
+ |
+LL | struct Vec<T> {
+ | ^ required by this bound in `Vec`
+help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
+ --> $DIR/wf-fn-where-clause.rs:16:12
+ |
+LL | struct Vec<T> {
+ | ^ this could be changed to `T: ?Sized`...
+LL | t: T,
+ | - ...if indirection were used here: `Box<T>`
+
+error[E0038]: the trait `Copy` cannot be made into an object
+ --> $DIR/wf-fn-where-clause.rs:12:16
+ |
+LL | fn bar() where Vec<dyn Copy>:, {}
+ | ^^^^^^^^^^^^^ `Copy` cannot be made into an object
+ |
+ = note: the trait cannot be made into an object because it requires `Self: Sized`
+ = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0277.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.rs b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs
new file mode 100644
index 000000000..b9d956c05
--- /dev/null
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs
@@ -0,0 +1,18 @@
+pub trait Unsatisfied {}
+
+#[repr(transparent)]
+pub struct Bar<T: Unsatisfied>(T);
+
+pub trait Foo {
+ type Assoc;
+}
+
+extern "C" {
+ pub fn lint_me() -> <() as Foo>::Assoc;
+ //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277]
+
+ pub fn lint_me_aswell() -> Bar<u32>;
+ //~^ ERROR: the trait bound `u32: Unsatisfied` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
new file mode 100644
index 000000000..b03023b5f
--- /dev/null
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+ --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
+ |
+LL | pub fn lint_me() -> <() as Foo>::Assoc;
+ | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+
+error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
+ --> $DIR/wf-foreign-fn-decl-ret.rs:14:32
+ |
+LL | pub fn lint_me_aswell() -> Bar<u32>;
+ | ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-foreign-fn-decl-ret.rs:4:19
+ |
+LL | pub struct Bar<T: Unsatisfied>(T);
+ | ^^^^^^^^^^^ required by this bound in `Bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-impl-associated-type-region.rs b/src/test/ui/wf/wf-impl-associated-type-region.rs
new file mode 100644
index 000000000..1bf8d3663
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-associated-type-region.rs
@@ -0,0 +1,14 @@
+// Check that we require that associated types in an impl are well-formed.
+
+
+
+pub trait Foo<'a> {
+ type Bar;
+}
+
+impl<'a, T> Foo<'a> for T {
+ type Bar = &'a T; //~ ERROR E0309
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-impl-associated-type-region.stderr b/src/test/ui/wf/wf-impl-associated-type-region.stderr
new file mode 100644
index 000000000..b9d4857a3
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-associated-type-region.stderr
@@ -0,0 +1,14 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/wf-impl-associated-type-region.rs:10:16
+ |
+LL | type Bar = &'a T;
+ | ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Foo<'a> for T {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/wf/wf-impl-associated-type-trait.rs b/src/test/ui/wf/wf-impl-associated-type-trait.rs
new file mode 100644
index 000000000..84e628e21
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-associated-type-trait.rs
@@ -0,0 +1,22 @@
+// Check that we require that associated types in an impl are well-formed.
+
+
+#![allow(dead_code)]
+
+pub trait MyHash { }
+
+pub struct MySet<T:MyHash> {
+ data: Vec<T>
+}
+
+pub trait Foo {
+ type Bar;
+}
+
+impl<T> Foo for T {
+ type Bar = MySet<T>;
+ //~^ ERROR the trait bound `T: MyHash` is not satisfied
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-impl-associated-type-trait.stderr b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
new file mode 100644
index 000000000..bdf8bba5e
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: MyHash` is not satisfied
+ --> $DIR/wf-impl-associated-type-trait.rs:17:16
+ |
+LL | type Bar = MySet<T>;
+ | ^^^^^^^^ the trait `MyHash` is not implemented for `T`
+ |
+note: required by a bound in `MySet`
+ --> $DIR/wf-impl-associated-type-trait.rs:8:20
+ |
+LL | pub struct MySet<T:MyHash> {
+ | ^^^^^^ required by this bound in `MySet`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: MyHash> Foo for T {
+ | ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-impl-self-type.rs b/src/test/ui/wf/wf-impl-self-type.rs
new file mode 100644
index 000000000..2dd9b4ef0
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-self-type.rs
@@ -0,0 +1,7 @@
+// Tests that we point at the proper location for an error
+// involving the self-type of an impl
+
+trait Foo {}
+impl Foo for Option<[u8]> {} //~ ERROR the size for
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-impl-self-type.stderr b/src/test/ui/wf/wf-impl-self-type.stderr
new file mode 100644
index 000000000..371321793
--- /dev/null
+++ b/src/test/ui/wf/wf-impl-self-type.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/wf-impl-self-type.rs:5:14
+ |
+LL | impl Foo for Option<[u8]> {}
+ | ^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Option`
+ --> $SRC_DIR/core/src/option.rs:LL:COL
+ |
+LL | pub enum Option<T> {
+ | ^ required by this bound in `Option`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-fn-arg.rs b/src/test/ui/wf/wf-in-fn-arg.rs
new file mode 100644
index 000000000..18df72336
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-arg.rs
@@ -0,0 +1,14 @@
+// Check that we enforce WF conditions also for argument types in fn items.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+fn bar<T>(_: &MustBeCopy<T>) //~ ERROR E0277
+{
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr
new file mode 100644
index 000000000..83a4a592a
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-arg.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-in-fn-arg.rs:10:15
+ |
+LL | fn bar<T>(_: &MustBeCopy<T>)
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-fn-arg.rs:6:21
+ |
+LL | struct MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider restricting type parameter `T`
+ |
+LL | fn bar<T: std::marker::Copy>(_: &MustBeCopy<T>)
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-fn-ret.rs b/src/test/ui/wf/wf-in-fn-ret.rs
new file mode 100644
index 000000000..4c9535184
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-ret.rs
@@ -0,0 +1,14 @@
+// Check that we enforce WF conditions also for return types in fn items.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+fn bar<T>() -> MustBeCopy<T> //~ ERROR E0277
+{
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr
new file mode 100644
index 000000000..7eeb97472
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-ret.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-in-fn-ret.rs:10:16
+ |
+LL | fn bar<T>() -> MustBeCopy<T>
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-fn-ret.rs:6:21
+ |
+LL | struct MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider restricting type parameter `T`
+ |
+LL | fn bar<T: std::marker::Copy>() -> MustBeCopy<T>
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-fn-type-arg.rs b/src/test/ui/wf/wf-in-fn-type-arg.rs
new file mode 100644
index 000000000..2917a8aa9
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-arg.rs
@@ -0,0 +1,12 @@
+// Check that we enforce WF conditions also for types in fns.
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+struct Bar<T> {
+ // needs T: Copy
+ x: fn(MustBeCopy<T>) //~ ERROR E0277
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-type-arg.stderr b/src/test/ui/wf/wf-in-fn-type-arg.stderr
new file mode 100644
index 000000000..be5e9d418
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-arg.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-in-fn-type-arg.rs:9:11
+ |
+LL | x: fn(MustBeCopy<T>)
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-fn-type-arg.rs:3:21
+ |
+LL | struct MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider restricting type parameter `T`
+ |
+LL | struct Bar<T: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-fn-type-ret.rs b/src/test/ui/wf/wf-in-fn-type-ret.rs
new file mode 100644
index 000000000..ab8e697e3
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-ret.rs
@@ -0,0 +1,12 @@
+// Check that we enforce WF conditions also for types in fns.
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+struct Foo<T> {
+ // needs T: 'static
+ x: fn() -> MustBeCopy<T> //~ ERROR E0277
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-type-ret.stderr b/src/test/ui/wf/wf-in-fn-type-ret.stderr
new file mode 100644
index 000000000..8fcfcb0b2
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-ret.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-in-fn-type-ret.rs:9:16
+ |
+LL | x: fn() -> MustBeCopy<T>
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-fn-type-ret.rs:3:21
+ |
+LL | struct MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider restricting type parameter `T`
+ |
+LL | struct Foo<T: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-fn-type-static.rs b/src/test/ui/wf/wf-in-fn-type-static.rs
new file mode 100644
index 000000000..73071dd23
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-static.rs
@@ -0,0 +1,22 @@
+// Check that we enforce WF conditions related to regions also for
+// types in fns.
+
+#![allow(dead_code)]
+
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+struct Foo<T> {
+ // needs T: 'static
+ x: fn() -> &'static T //~ ERROR E0310
+}
+
+struct Bar<T> {
+ // needs T: Copy
+ x: fn(&'static T) //~ ERROR E0310
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-type-static.stderr b/src/test/ui/wf/wf-in-fn-type-static.stderr
new file mode 100644
index 000000000..73fbb9ca6
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-type-static.stderr
@@ -0,0 +1,25 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/wf-in-fn-type-static.rs:13:8
+ |
+LL | x: fn() -> &'static T
+ | ^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | struct Foo<T: 'static> {
+ | +++++++++
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/wf-in-fn-type-static.rs:18:8
+ |
+LL | x: fn(&'static T)
+ | ^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | struct Bar<T: 'static> {
+ | +++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/wf/wf-in-fn-where-clause.rs b/src/test/ui/wf/wf-in-fn-where-clause.rs
new file mode 100644
index 000000000..e55295a3b
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-where-clause.rs
@@ -0,0 +1,15 @@
+// Check that we enforce WF conditions also for where clauses in fn items.
+
+
+#![allow(dead_code)]
+
+trait MustBeCopy<T:Copy> {
+}
+
+fn bar<T,U>()
+ where T: MustBeCopy<U> //~ ERROR E0277
+{
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr
new file mode 100644
index 000000000..160a73840
--- /dev/null
+++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-in-fn-where-clause.rs:10:14
+ |
+LL | where T: MustBeCopy<U>
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-fn-where-clause.rs:6:20
+ |
+LL | trait MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | where T: MustBeCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
new file mode 100644
index 000000000..4fcf8f403
--- /dev/null
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
@@ -0,0 +1,17 @@
+// Regression test for #80468.
+
+#![crate_type = "lib"]
+
+pub trait Trait {}
+
+#[repr(transparent)]
+pub struct Wrapper<T: Trait>(T);
+
+#[repr(transparent)]
+pub struct Ref<'a>(&'a u8);
+
+impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here
+
+extern "C" {
+ pub fn repro(_: Wrapper<Ref>); //~ ERROR: incompatible lifetime on type
+}
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
new file mode 100644
index 000000000..94f6dc266
--- /dev/null
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
@@ -0,0 +1,37 @@
+error[E0726]: implicit elided lifetime not allowed here
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:16
+ |
+LL | impl Trait for Ref {}
+ | ^^^ expected lifetime parameter
+ |
+ = note: assuming a `'static` lifetime...
+help: indicate the anonymous lifetime
+ |
+LL | impl Trait for Ref<'_> {}
+ | ++++
+
+error: incompatible lifetime on type
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
+ |
+LL | pub fn repro(_: Wrapper<Ref>);
+ | ^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
+ |
+LL | pub struct Wrapper<T: Trait>(T);
+ | ^^^^^ introduces a `'static` lifetime requirement
+note: the anonymous lifetime as defined here...
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:29
+ |
+LL | pub fn repro(_: Wrapper<Ref>);
+ | ^^^
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1
+ |
+LL | impl Trait for Ref {}
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0726`.
diff --git a/src/test/ui/wf/wf-in-obj-type-static.rs b/src/test/ui/wf/wf-in-obj-type-static.rs
new file mode 100644
index 000000000..1ad2fd1ed
--- /dev/null
+++ b/src/test/ui/wf/wf-in-obj-type-static.rs
@@ -0,0 +1,18 @@
+// Check that we enforce WF conditions also for types in fns.
+
+
+#![allow(dead_code)]
+
+trait Object<T> { }
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+struct Foo<T> {
+ // needs T: 'static
+ x: dyn Object<&'static T> //~ ERROR E0310
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-obj-type-static.stderr b/src/test/ui/wf/wf-in-obj-type-static.stderr
new file mode 100644
index 000000000..c3ad42dd5
--- /dev/null
+++ b/src/test/ui/wf/wf-in-obj-type-static.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/wf-in-obj-type-static.rs:14:8
+ |
+LL | x: dyn Object<&'static T>
+ | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | struct Foo<T: 'static> {
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/wf/wf-in-obj-type-trait.rs b/src/test/ui/wf/wf-in-obj-type-trait.rs
new file mode 100644
index 000000000..170fad55f
--- /dev/null
+++ b/src/test/ui/wf/wf-in-obj-type-trait.rs
@@ -0,0 +1,14 @@
+// Check that we enforce WF conditions also for types in fns.
+
+trait Object<T> { }
+
+struct MustBeCopy<T:Copy> {
+ t: T
+}
+
+struct Bar<T> {
+ // needs T: Copy
+ x: dyn Object<MustBeCopy<T>> //~ ERROR E0277
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-in-obj-type-trait.stderr b/src/test/ui/wf/wf-in-obj-type-trait.stderr
new file mode 100644
index 000000000..f556b678e
--- /dev/null
+++ b/src/test/ui/wf/wf-in-obj-type-trait.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-in-obj-type-trait.rs:11:19
+ |
+LL | x: dyn Object<MustBeCopy<T>>
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `MustBeCopy`
+ --> $DIR/wf-in-obj-type-trait.rs:5:21
+ |
+LL | struct MustBeCopy<T:Copy> {
+ | ^^^^ required by this bound in `MustBeCopy`
+help: consider restricting type parameter `T`
+ |
+LL | struct Bar<T: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.rs b/src/test/ui/wf/wf-inherent-impl-method-where-clause.rs
new file mode 100644
index 000000000..eb50fc010
--- /dev/null
+++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.rs
@@ -0,0 +1,17 @@
+// Test that we check where-clauses on inherent impl methods.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+struct Foo<T,U>(T,U);
+
+impl<T,U> Foo<T,U> {
+ fn foo(self) where T: ExtraCopy<U> //~ ERROR E0277
+ {}
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
new file mode 100644
index 000000000..e723d1ba7
--- /dev/null
+++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-inherent-impl-method-where-clause.rs:12:27
+ |
+LL | fn foo(self) where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-inherent-impl-method-where-clause.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider restricting type parameter `U`
+ |
+LL | impl<T,U: std::marker::Copy> Foo<T,U> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.rs b/src/test/ui/wf/wf-inherent-impl-where-clause.rs
new file mode 100644
index 000000000..ac194fb13
--- /dev/null
+++ b/src/test/ui/wf/wf-inherent-impl-where-clause.rs
@@ -0,0 +1,16 @@
+// Test that we check where-clauses on inherent impls.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+struct Foo<T,U>(T,U);
+
+impl<T,U> Foo<T,U> where T: ExtraCopy<U> //~ ERROR E0277
+{
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
new file mode 100644
index 000000000..39e0d348e
--- /dev/null
+++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-inherent-impl-where-clause.rs:11:29
+ |
+LL | impl<T,U> Foo<T,U> where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-inherent-impl-where-clause.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | impl<T,U> Foo<T,U> where T: ExtraCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-misc-methods-issue-28609.rs b/src/test/ui/wf/wf-misc-methods-issue-28609.rs
new file mode 100644
index 000000000..050f866e1
--- /dev/null
+++ b/src/test/ui/wf/wf-misc-methods-issue-28609.rs
@@ -0,0 +1,74 @@
+// check that misc. method calls are well-formed
+
+use std::marker::PhantomData;
+use std::ops::{Deref, Shl};
+
+#[derive(Copy, Clone)]
+struct S<'a, 'b: 'a> {
+ marker: PhantomData<&'a &'b ()>,
+ bomb: Option<&'b u32>
+}
+
+type S2<'a> = S<'a, 'a>;
+
+impl<'a, 'b> S<'a, 'b> {
+ fn transmute_inherent(&self, a: &'b u32) -> &'a u32 {
+ a
+ }
+}
+
+fn return_dangling_pointer_inherent(s: S2) -> &u32 {
+ let s = s;
+ s.transmute_inherent(&mut 42) //~ ERROR cannot return value referencing temporary value
+}
+
+impl<'a, 'b> Deref for S<'a, 'b> {
+ type Target = &'a u32;
+ fn deref(&self) -> &&'a u32 {
+ self.bomb.as_ref().unwrap()
+ }
+}
+
+fn return_dangling_pointer_coerce(s: S2) -> &u32 {
+ let four = 4;
+ let mut s = s;
+ s.bomb = Some(&four);
+ &s //~ ERROR cannot return value referencing local variable `four`
+}
+
+fn return_dangling_pointer_unary_op(s: S2) -> &u32 {
+ let four = 4;
+ let mut s = s;
+ s.bomb = Some(&four);
+ &*s //~ ERROR cannot return value referencing local variable `four`
+}
+
+impl<'a, 'b> Shl<&'b u32> for S<'a, 'b> {
+ type Output = &'a u32;
+ fn shl(self, t: &'b u32) -> &'a u32 { t }
+}
+
+fn return_dangling_pointer_binary_op(s: S2) -> &u32 {
+ let s = s;
+ s << &mut 3 //~ ERROR cannot return value referencing temporary value
+}
+
+fn return_dangling_pointer_method(s: S2) -> &u32 {
+ let s = s;
+ s.shl(&mut 3) //~ ERROR cannot return value referencing temporary value
+}
+
+fn return_dangling_pointer_ufcs(s: S2) -> &u32 {
+ let s = s;
+ S2::shl(s, &mut 3) //~ ERROR cannot return value referencing temporary value
+}
+
+fn main() {
+ let s = S { marker: PhantomData, bomb: None };
+ let _inherent_dp = return_dangling_pointer_inherent(s);
+ let _coerce_dp = return_dangling_pointer_coerce(s);
+ let _unary_dp = return_dangling_pointer_unary_op(s);
+ let _binary_dp = return_dangling_pointer_binary_op(s);
+ let _method_dp = return_dangling_pointer_method(s);
+ let _ufcs_dp = return_dangling_pointer_ufcs(s);
+}
diff --git a/src/test/ui/wf/wf-misc-methods-issue-28609.stderr b/src/test/ui/wf/wf-misc-methods-issue-28609.stderr
new file mode 100644
index 000000000..fc5898434
--- /dev/null
+++ b/src/test/ui/wf/wf-misc-methods-issue-28609.stderr
@@ -0,0 +1,55 @@
+error[E0515]: cannot return value referencing temporary value
+ --> $DIR/wf-misc-methods-issue-28609.rs:22:5
+ |
+LL | s.transmute_inherent(&mut 42)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^--^
+ | | |
+ | | temporary value created here
+ | returns a value referencing data owned by the current function
+
+error[E0515]: cannot return value referencing local variable `four`
+ --> $DIR/wf-misc-methods-issue-28609.rs:36:5
+ |
+LL | s.bomb = Some(&four);
+ | ----- `four` is borrowed here
+LL | &s
+ | ^^ returns a value referencing data owned by the current function
+
+error[E0515]: cannot return value referencing local variable `four`
+ --> $DIR/wf-misc-methods-issue-28609.rs:43:5
+ |
+LL | s.bomb = Some(&four);
+ | ----- `four` is borrowed here
+LL | &*s
+ | ^^^ returns a value referencing data owned by the current function
+
+error[E0515]: cannot return value referencing temporary value
+ --> $DIR/wf-misc-methods-issue-28609.rs:53:5
+ |
+LL | s << &mut 3
+ | ^^^^^^^^^^-
+ | | |
+ | | temporary value created here
+ | returns a value referencing data owned by the current function
+
+error[E0515]: cannot return value referencing temporary value
+ --> $DIR/wf-misc-methods-issue-28609.rs:58:5
+ |
+LL | s.shl(&mut 3)
+ | ^^^^^^^^^^^-^
+ | | |
+ | | temporary value created here
+ | returns a value referencing data owned by the current function
+
+error[E0515]: cannot return value referencing temporary value
+ --> $DIR/wf-misc-methods-issue-28609.rs:63:5
+ |
+LL | S2::shl(s, &mut 3)
+ | ^^^^^^^^^^^^^^^^-^
+ | | |
+ | | temporary value created here
+ | returns a value referencing data owned by the current function
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/wf/wf-object-safe.rs b/src/test/ui/wf/wf-object-safe.rs
new file mode 100644
index 000000000..42e691755
--- /dev/null
+++ b/src/test/ui/wf/wf-object-safe.rs
@@ -0,0 +1,10 @@
+// Check that object-safe traits are not WF when used as object types.
+// Issue #21953.
+
+trait A {
+ fn foo(&self, _x: &Self);
+}
+
+fn main() {
+ let _x: &dyn A; //~ ERROR E0038
+}
diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr
new file mode 100644
index 000000000..64969fbe3
--- /dev/null
+++ b/src/test/ui/wf/wf-object-safe.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `A` cannot be made into an object
+ --> $DIR/wf-object-safe.rs:9:13
+ |
+LL | let _x: &dyn A;
+ | ^^^^^^ `A` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-object-safe.rs:5:23
+ |
+LL | trait A {
+ | - this trait cannot be made into an object...
+LL | fn foo(&self, _x: &Self);
+ | ^^^^^ ...because method `foo` references the `Self` type in this parameter
+ = help: consider moving `foo` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs
new file mode 100644
index 000000000..85a332e24
--- /dev/null
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs
@@ -0,0 +1,22 @@
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+trait Trait<'a, T> {
+ type Out;
+}
+
+impl<'a, T> Trait<'a, T> for usize {
+ type Out = &'a fn(T); //~ ERROR `T` may not live long enough
+}
+
+struct Foo<'a,T> {
+ f: &'a fn(T),
+}
+
+trait Baz<T> { }
+
+impl<'a, T> Trait<'a, T> for u32 {
+ type Out = &'a dyn Baz<T>; //~ ERROR `T` may not live long enough
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
new file mode 100644
index 000000000..4d4d8b2ab
--- /dev/null
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
@@ -0,0 +1,25 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:9:16
+ |
+LL | type Out = &'a fn(T);
+ | ^^^^^^^^^ ...so that the reference type `&'a fn(T)` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Trait<'a, T> for usize {
+ | ++++
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:16
+ |
+LL | type Out = &'a dyn Baz<T>;
+ | ^^^^^^^^^^^^^^ ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<'a, T: 'a> Trait<'a, T> for u32 {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs
new file mode 100644
index 000000000..d0167c8c2
--- /dev/null
+++ b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs
@@ -0,0 +1,31 @@
+// rust-lang/rust#58158: We have special-case code to deal with case
+// when a type is both packed and needs drop glue, (we move the fields
+// out of their potentially unaligned locations before dropping them,
+// which requires they be Sized; see PR #44884).
+//
+// So, we need to check if a given type needs drop-glue. That requires
+// that we actually know that the concrete type, and we guard against
+// the type having unknown parts (i.e. type variables) by ICE'ing in
+// that scenario.
+//
+// But in a case where we have a projection (`Type as Trait::Assoc`)
+// where `Type` does not actually implement `Trait`, we of course
+// cannot have a concrete type, because there is no impl to look up
+// the concrete type for the associated type `Assoc`.
+//
+// So, this test is just making sure that in such a case that we do
+// not immediately ICE, and instead allow the underlying type error to
+// surface.
+
+pub struct Matrix<S>(S);
+pub struct DefaultAllocator;
+
+pub trait Allocator { type Buffer; }
+
+// impl Allocator for DefaultAllocator { type Buffer = (); }
+
+#[repr(packed)]
+struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>);
+//~^ ERROR the trait bound `DefaultAllocator: Allocator` is not satisfied
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr
new file mode 100644
index 000000000..e460cdcd3
--- /dev/null
+++ b/src/test/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `DefaultAllocator: Allocator` is not satisfied
+ --> $DIR/wf-packed-on-proj-of-type-as-unimpl-trait.rs:28:12
+ |
+LL | struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `DefaultAllocator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-static-method.rs b/src/test/ui/wf/wf-static-method.rs
new file mode 100644
index 000000000..7ff195230
--- /dev/null
+++ b/src/test/ui/wf/wf-static-method.rs
@@ -0,0 +1,59 @@
+// check that static methods don't get to assume their trait-ref
+// is well-formed.
+// FIXME(#27579): this is just a bug. However, our checking with
+// static inherent methods isn't quite working - need to
+// fix that before removing the check.
+
+trait Foo<'a, 'b, T>: Sized {
+ fn make_me() -> Self { loop {} }
+ fn static_evil(u: &'b u32) -> &'a u32;
+}
+
+struct Evil<'a, 'b: 'a>(Option<&'a &'b ()>);
+
+impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
+ fn make_me() -> Self { }
+ fn static_evil(u: &'b u32) -> &'a u32 {
+ u
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+struct IndirectEvil<'a, 'b: 'a>(Option<&'a &'b ()>);
+
+impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
+ fn make_me() -> Self { IndirectEvil(None) }
+ fn static_evil(u: &'b u32) -> &'a u32 {
+ let me = Self::make_me();
+ //~^ ERROR lifetime may not live long enough
+ loop {} // (`me` could be used for the lifetime transmute).
+ }
+}
+
+impl<'a, 'b> Evil<'a, 'b> {
+ fn inherent_evil(u: &'b u32) -> &'a u32 {
+ u
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+// while static methods don't get to *assume* this, we still
+// *check* that they hold.
+
+fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ <()>::static_evil(b)
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ <IndirectEvil>::static_evil(b)
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ <Evil>::inherent_evil(b)
+ //~^ ERROR lifetime may not live long enough
+}
+
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr
new file mode 100644
index 000000000..161609a5f
--- /dev/null
+++ b/src/test/ui/wf/wf-static-method.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:17:9
+ |
+LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | u
+ | ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:27:18
+ |
+LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let me = Self::make_me();
+ | ^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:35:9
+ |
+LL | impl<'a, 'b> Evil<'a, 'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | fn inherent_evil(u: &'b u32) -> &'a u32 {
+LL | u
+ | ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:44:5
+ |
+LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <()>::static_evil(b)
+ | ^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:49:5
+ |
+LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <IndirectEvil>::static_evil(b)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:54:5
+ |
+LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <Evil>::inherent_evil(b)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/wf/wf-static-type.rs b/src/test/ui/wf/wf-static-type.rs
new file mode 100644
index 000000000..1c35e1daf
--- /dev/null
+++ b/src/test/ui/wf/wf-static-type.rs
@@ -0,0 +1,14 @@
+// Test that we check the types of statics are well-formed.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> { t: T }
+struct NotCopy;
+
+static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+//~^ ERROR E0277
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-static-type.stderr b/src/test/ui/wf/wf-static-type.stderr
new file mode 100644
index 000000000..4ae69cf2e
--- /dev/null
+++ b/src/test/ui/wf/wf-static-type.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
+ --> $DIR/wf-static-type.rs:10:13
+ |
+LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
+ |
+ = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-static-type.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> { t: T }
+ | ^^^^ required by this bound in `IsCopy`
+help: consider annotating `NotCopy` with `#[derive(Copy)]`
+ |
+LL | #[derive(Copy)]
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-struct-bound.rs b/src/test/ui/wf/wf-struct-bound.rs
new file mode 100644
index 000000000..6e558ca8f
--- /dev/null
+++ b/src/test/ui/wf/wf-struct-bound.rs
@@ -0,0 +1,16 @@
+// Test that we check struct bounds for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+struct SomeStruct<T,U>
+ where T: ExtraCopy<U> //~ ERROR E0277
+{
+ data: (T,U)
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr
new file mode 100644
index 000000000..6248e3e4e
--- /dev/null
+++ b/src/test/ui/wf/wf-struct-bound.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-struct-bound.rs:10:14
+ |
+LL | where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-struct-bound.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | where T: ExtraCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-struct-field.rs b/src/test/ui/wf/wf-struct-field.rs
new file mode 100644
index 000000000..63f8b4382
--- /dev/null
+++ b/src/test/ui/wf/wf-struct-field.rs
@@ -0,0 +1,16 @@
+// Test that we check struct fields for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> {
+ value: T
+}
+
+struct SomeStruct<A> {
+ data: IsCopy<A> //~ ERROR E0277
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-struct-field.stderr b/src/test/ui/wf/wf-struct-field.stderr
new file mode 100644
index 000000000..78a8da860
--- /dev/null
+++ b/src/test/ui/wf/wf-struct-field.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `A: Copy` is not satisfied
+ --> $DIR/wf-struct-field.rs:12:11
+ |
+LL | data: IsCopy<A>
+ | ^^^^^^^^^ the trait `Copy` is not implemented for `A`
+ |
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-struct-field.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> {
+ | ^^^^ required by this bound in `IsCopy`
+help: consider restricting type parameter `A`
+ |
+LL | struct SomeStruct<A: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.rs b/src/test/ui/wf/wf-trait-associated-type-bound.rs
new file mode 100644
index 000000000..2f20e65e5
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-bound.rs
@@ -0,0 +1,14 @@
+// Test that we check associated type bounds for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+trait SomeTrait<T> {
+ type Type1: ExtraCopy<T>; //~ ERROR E0277
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
new file mode 100644
index 000000000..829770017
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-trait-associated-type-bound.rs:10:17
+ |
+LL | type Type1: ExtraCopy<T>;
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-trait-associated-type-bound.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider restricting type parameter `T`
+ |
+LL | trait SomeTrait<T: std::marker::Copy> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-associated-type-region.rs b/src/test/ui/wf/wf-trait-associated-type-region.rs
new file mode 100644
index 000000000..0dfc9f098
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-region.rs
@@ -0,0 +1,14 @@
+// Test that we check associated type default values for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait SomeTrait<'a> {
+ type Type1;
+ type Type2 = &'a Self::Type1;
+ //~^ ERROR E0309
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-associated-type-region.stderr b/src/test/ui/wf/wf-trait-associated-type-region.stderr
new file mode 100644
index 000000000..6e2cc8aba
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-region.stderr
@@ -0,0 +1,12 @@
+error[E0309]: the associated type `<Self as SomeTrait<'a>>::Type1` may not live long enough
+ --> $DIR/wf-trait-associated-type-region.rs:9:18
+ |
+LL | type Type2 = &'a Self::Type1;
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
+ = note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/wf/wf-trait-associated-type-trait.rs b/src/test/ui/wf/wf-trait-associated-type-trait.rs
new file mode 100644
index 000000000..d67e110ed
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-trait.rs
@@ -0,0 +1,16 @@
+// Test that we check associated type default values for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+struct IsCopy<T:Copy> { x: T }
+
+trait SomeTrait {
+ type Type1;
+ type Type2 = (IsCopy<Self::Type1>, bool);
+ //~^ ERROR E0277
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-associated-type-trait.stderr b/src/test/ui/wf/wf-trait-associated-type-trait.stderr
new file mode 100644
index 000000000..a73c3a2ae
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-associated-type-trait.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `<Self as SomeTrait>::Type1: Copy` is not satisfied
+ --> $DIR/wf-trait-associated-type-trait.rs:11:19
+ |
+LL | type Type2 = (IsCopy<Self::Type1>, bool);
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `<Self as SomeTrait>::Type1`
+ |
+note: required by a bound in `IsCopy`
+ --> $DIR/wf-trait-associated-type-trait.rs:7:17
+ |
+LL | struct IsCopy<T:Copy> { x: T }
+ | ^^^^ required by this bound in `IsCopy`
+help: consider further restricting the associated type
+ |
+LL | trait SomeTrait where <Self as SomeTrait>::Type1: Copy {
+ | ++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-bound.rs b/src/test/ui/wf/wf-trait-bound.rs
new file mode 100644
index 000000000..62a1eb5b0
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-bound.rs
@@ -0,0 +1,15 @@
+// Test that we check supertrait bounds for WFedness.
+
+#![feature(associated_type_defaults)]
+
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+trait SomeTrait<T,U>
+ where T: ExtraCopy<U> //~ ERROR E0277
+{
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr
new file mode 100644
index 000000000..bace3e3ef
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-bound.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: Copy` is not satisfied
+ --> $DIR/wf-trait-bound.rs:10:14
+ |
+LL | where T: ExtraCopy<U>
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `U`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-trait-bound.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider further restricting type parameter `U`
+ |
+LL | where T: ExtraCopy<U>, U: std::marker::Copy
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.rs b/src/test/ui/wf/wf-trait-default-fn-arg.rs
new file mode 100644
index 000000000..64fc35aeb
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-arg.rs
@@ -0,0 +1,19 @@
+// Check that we test WF conditions for fn arguments. Because the
+// current code is so goofy, this is only a warning for now.
+
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+struct Bar<T:Eq+?Sized> { value: Box<T> }
+
+trait Foo {
+ fn bar(&self, x: &Bar<Self>) {
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+ }
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
new file mode 100644
index 000000000..8c3d0568f
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-default-fn-arg.rs:11:23
+ |
+LL | fn bar(&self, x: &Bar<Self>) {
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-default-fn-arg.rs:8:14
+ |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar(&self, x: &Bar<Self>) where Self: Eq {
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.rs b/src/test/ui/wf/wf-trait-default-fn-ret.rs
new file mode 100644
index 000000000..2103dae8d
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-ret.rs
@@ -0,0 +1,19 @@
+// Check that we test WF conditions for fn arguments. Because the
+// current code is so goofy, this is only a warning for now.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+struct Bar<T:Eq+?Sized> { value: Box<T> }
+
+trait Foo {
+ fn bar(&self) -> Bar<Self> {
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+ loop { }
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.stderr b/src/test/ui/wf/wf-trait-default-fn-ret.stderr
new file mode 100644
index 000000000..6422e862d
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-ret.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-default-fn-ret.rs:11:22
+ |
+LL | fn bar(&self) -> Bar<Self> {
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-default-fn-ret.rs:8:14
+ |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar(&self) -> Bar<Self> where Self: Eq {
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.rs b/src/test/ui/wf/wf-trait-default-fn-where-clause.rs
new file mode 100644
index 000000000..ded97214f
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.rs
@@ -0,0 +1,19 @@
+// Check that we test WF conditions for fn arguments. Because the
+// current code is so goofy, this is only a warning for now.
+
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+trait Bar<T:Eq+?Sized> { }
+
+trait Foo {
+ fn bar<A>(&self) where A: Bar<Self> {
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+ }
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr
new file mode 100644
index 000000000..f260d5750
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-default-fn-where-clause.rs:11:31
+ |
+LL | fn bar<A>(&self) where A: Bar<Self> {
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-default-fn-where-clause.rs:8:13
+ |
+LL | trait Bar<T:Eq+?Sized> { }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar<A>(&self) where A: Bar<Self>, Self: Eq {
+ | ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-fn-arg.rs b/src/test/ui/wf/wf-trait-fn-arg.rs
new file mode 100644
index 000000000..044569942
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-arg.rs
@@ -0,0 +1,16 @@
+// Check that we test WF conditions for fn arguments in a trait definition.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+struct Bar<T:Eq+?Sized> { value: Box<T> }
+
+trait Foo {
+ fn bar(&self, x: &Bar<Self>);
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr
new file mode 100644
index 000000000..3bd1f4892
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-arg.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-fn-arg.rs:10:23
+ |
+LL | fn bar(&self, x: &Bar<Self>);
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-fn-arg.rs:7:14
+ |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar(&self, x: &Bar<Self>) where Self: Eq;
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-fn-ret.rs b/src/test/ui/wf/wf-trait-fn-ret.rs
new file mode 100644
index 000000000..f49e43087
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-ret.rs
@@ -0,0 +1,16 @@
+// Check that we test WF conditions for fn return types in a trait definition.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+struct Bar<T:Eq+?Sized> { value: Box<T> }
+
+trait Foo {
+ fn bar(&self) -> &Bar<Self>;
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr
new file mode 100644
index 000000000..a59ba3400
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-ret.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-fn-ret.rs:10:22
+ |
+LL | fn bar(&self) -> &Bar<Self>;
+ | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-fn-ret.rs:7:14
+ |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar(&self) -> &Bar<Self> where Self: Eq;
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.rs b/src/test/ui/wf/wf-trait-fn-where-clause.rs
new file mode 100644
index 000000000..1d2427ff9
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-where-clause.rs
@@ -0,0 +1,17 @@
+// Check that we test WF conditions for fn where clauses in a trait definition.
+
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+struct Bar<T:Eq+?Sized> { value: Box<T> }
+
+trait Foo {
+ fn bar(&self) where Self: Sized, Bar<Self>: Copy;
+ //~^ ERROR E0277
+ //
+ // Here, Eq ought to be implemented.
+}
+
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr
new file mode 100644
index 000000000..d064f7fc5
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `Self: Eq` is not satisfied
+ --> $DIR/wf-trait-fn-where-clause.rs:10:49
+ |
+LL | fn bar(&self) where Self: Sized, Bar<Self>: Copy;
+ | ^^^^ the trait `Eq` is not implemented for `Self`
+ |
+note: required by a bound in `Bar`
+ --> $DIR/wf-trait-fn-where-clause.rs:7:14
+ |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+ | ^^ required by this bound in `Bar`
+help: consider further restricting `Self`
+ |
+LL | fn bar(&self) where Self: Sized, Bar<Self>: Copy, Self: Eq;
+ | ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-trait-superbound.rs b/src/test/ui/wf/wf-trait-superbound.rs
new file mode 100644
index 000000000..8905a8820
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-superbound.rs
@@ -0,0 +1,12 @@
+// Test that we check supertrait bounds for WFedness.
+
+#![feature(associated_type_defaults)]
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+trait ExtraCopy<T:Copy> { }
+
+trait SomeTrait<T>: ExtraCopy<T> { //~ ERROR E0277
+}
+
+fn main() { }
diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr
new file mode 100644
index 000000000..cd49243a4
--- /dev/null
+++ b/src/test/ui/wf/wf-trait-superbound.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/wf-trait-superbound.rs:9:21
+ |
+LL | trait SomeTrait<T>: ExtraCopy<T> {
+ | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `ExtraCopy`
+ --> $DIR/wf-trait-superbound.rs:7:19
+ |
+LL | trait ExtraCopy<T:Copy> { }
+ | ^^^^ required by this bound in `ExtraCopy`
+help: consider restricting type parameter `T`
+ |
+LL | trait SomeTrait<T: std::marker::Copy>: ExtraCopy<T> {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.rs b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs
new file mode 100644
index 000000000..c8731a8ec
--- /dev/null
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs
@@ -0,0 +1,29 @@
+// Check that we do not allow coercions to object
+// unsafe trait objects in match arms
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+struct R;
+
+impl Trait for R {}
+
+fn opt() -> Option<()> {
+ Some(())
+}
+
+fn main() {
+ match opt() {
+ Some(()) => &S,
+ None => &R, //~ ERROR E0308
+ }
+ let t: &dyn Trait = match opt() { //~ ERROR E0038
+ Some(()) => &S, //~ ERROR E0038
+ None => &R,
+ };
+}
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
new file mode 100644
index 000000000..6d141a58e
--- /dev/null
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -0,0 +1,54 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/wf-unsafe-trait-obj-match.rs:23:17
+ |
+LL | / match opt() {
+LL | | Some(()) => &S,
+ | | -- this is found to be of type `&S`
+LL | | None => &R,
+ | | ^^ expected struct `S`, found struct `R`
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+ = note: expected reference `&S`
+ found reference `&R`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-unsafe-trait-obj-match.rs:26:21
+ |
+LL | Some(()) => &S,
+ | ^^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-unsafe-trait-obj-match.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+ = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+ --> $DIR/wf-unsafe-trait-obj-match.rs:25:25
+ |
+LL | let t: &dyn Trait = match opt() {
+ | _________________________^
+LL | | Some(()) => &S,
+LL | | None => &R,
+LL | | };
+ | |_____^ `Trait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/wf-unsafe-trait-obj-match.rs:6:14
+ |
+LL | trait Trait: Sized {}
+ | ----- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&R`
+ = note: required by cast to type `&dyn Trait`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0308.
+For more information about an error, try `rustc --explain E0038`.