summaryrefslogtreecommitdiffstats
path: root/src/test/ui/trivial-bounds
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr46
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr46
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs71
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs23
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs13
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr19
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs33
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr28
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs23
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr17
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs58
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr46
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs27
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr22
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs14
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr16
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs74
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr95
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-leak-copy.rs12
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr9
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-leak.rs31
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-leak.stderr48
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-lint.rs40
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-lint.stderr50
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-object.rs18
25 files changed, 879 insertions, 0 deletions
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr
new file mode 100644
index 000000000..40829f537
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr
@@ -0,0 +1,46 @@
+warning: trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:20:29
+ |
+LL | for<'any> &'any mut (): Clone,
+ | ^^^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:28:21
+ |
+LL | struct S where i32: Foo;
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:31:28
+ |
+LL | impl Foo for () where i32: Foo {
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:40:19
+ |
+LL | fn f() where i32: Foo {
+ | ^^^
+
+warning: trait bound &'static str: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:48:28
+ |
+LL | fn g() where &'static str: Foo {
+ | ^^^
+
+warning: trait bound String: Neg does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:57:13
+ |
+LL | String: ::std::ops::Neg<Output = String>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: trait bound i32: Iterator does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:65:10
+ |
+LL | i32: Iterator,
+ | ^^^^^^^^
+
+warning: 7 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr
new file mode 100644
index 000000000..40829f537
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr
@@ -0,0 +1,46 @@
+warning: trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:20:29
+ |
+LL | for<'any> &'any mut (): Clone,
+ | ^^^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:28:21
+ |
+LL | struct S where i32: Foo;
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:31:28
+ |
+LL | impl Foo for () where i32: Foo {
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:40:19
+ |
+LL | fn f() where i32: Foo {
+ | ^^^
+
+warning: trait bound &'static str: Foo does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:48:28
+ |
+LL | fn g() where &'static str: Foo {
+ | ^^^
+
+warning: trait bound String: Neg does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:57:13
+ |
+LL | String: ::std::ops::Neg<Output = String>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: trait bound i32: Iterator does not depend on any type or lifetime parameters
+ --> $DIR/issue-73021-impossible-inline.rs:65:10
+ |
+LL | i32: Iterator,
+ | ^^^^^^^^
+
+warning: 7 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs
new file mode 100644
index 000000000..ab6677e91
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs
@@ -0,0 +1,71 @@
+// build-pass
+// revisions: no-opt inline
+// [inline]compile-flags: -Zmir-opt-level=3 --emit=mir
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+trait Foo {
+ fn test(&self);
+}
+
+fn foo<'a>(s: &'a mut ())
+where
+ &'a mut (): Foo,
+{
+ s.test();
+}
+
+fn clone(it: &mut ()) -> &mut ()
+where
+ for<'any> &'any mut (): Clone,
+ //~^ WARN trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+{
+ it.clone()
+}
+
+fn generic_function<X: Foo>(x: X) {}
+
+struct S where i32: Foo;
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+
+impl Foo for () where i32: Foo {
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+ fn test(&self) {
+ 3i32.test();
+ Foo::test(&4i32);
+ generic_function(5i32);
+ }
+}
+
+fn f() where i32: Foo {
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+ let s = S;
+ 3i32.test();
+ Foo::test(&4i32);
+ generic_function(5i32);
+}
+
+fn g() where &'static str: Foo {
+//~^ WARN trait bound &'static str: Foo does not depend on any type or lifetime parameters
+ "Foo".test();
+ Foo::test(&"Foo");
+ generic_function("Foo");
+}
+
+fn use_op(s: String) -> String
+where
+ String: ::std::ops::Neg<Output = String>,
+//~^ WARN trait bound String: Neg does not depend on any type or lifetime parameters
+{
+ -s
+}
+
+fn use_for()
+where
+ i32: Iterator,
+//~^ WARN trait bound i32: Iterator does not depend on any type or lifetime parameters
+{
+ for _ in 2i32 {}
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs
new file mode 100644
index 000000000..69eee66e6
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs
@@ -0,0 +1,23 @@
+// check-pass
+// compile-flags: --emit=mir,link
+// Force mir to be emitted, to ensure that const
+// propagation doesn't ICE on a function
+// with an 'impossible' body. See issue #67696
+// Inconsistent bounds with trait implementations
+
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+trait A {
+ fn foo(&self) -> Self where Self: Copy;
+}
+
+impl A for str {
+ fn foo(&self) -> Self where Self: Copy { *"" }
+}
+
+impl A for i32 {
+ fn foo(&self) -> Self { 3 }
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs
new file mode 100644
index 000000000..b1ff23fd0
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs
@@ -0,0 +1,13 @@
+// Check that reborrows are still illegal with Copy mutable references
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+ *t //~ ERROR
+}
+
+fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+ {*t} //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
new file mode 100644
index 000000000..aac119afd
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
@@ -0,0 +1,19 @@
+error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
+ --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:6:5
+ |
+LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+ | --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
+LL | *t
+ | ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
+ --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6
+ |
+LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
+ | --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
+LL | {*t}
+ | ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
new file mode 100644
index 000000000..3416503b8
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
@@ -0,0 +1,33 @@
+// check-pass
+// Check tautalogically false `Copy` bounds
+#![feature(trivial_bounds)]
+
+fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds
+ is_copy(&t);
+ let x = t;
+ drop(t);
+ t
+}
+
+fn copy_out_string(t: &String) -> String where String: Copy { //~ WARNING trivial_bounds
+ *t
+}
+
+fn copy_string_with_param<T>(x: String) where String: Copy { //~ WARNING trivial_bounds
+ let y = x;
+ let z = x;
+}
+
+// Check that no reborrowing occurs
+fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
+ //~^ WARNING trivial_bounds
+ is_copy(t);
+ let x = *t;
+ drop(x);
+ x
+}
+
+fn is_copy<T: Copy>(t: &T) {}
+
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
new file mode 100644
index 000000000..1e2662389
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
@@ -0,0 +1,28 @@
+warning: trait bound String: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51
+ |
+LL | fn copy_string(t: String) -> String where String: Copy {
+ | ^^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound String: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56
+ |
+LL | fn copy_out_string(t: &String) -> String where String: Copy {
+ | ^^^^
+
+warning: trait bound String: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55
+ |
+LL | fn copy_string_with_param<T>(x: String) where String: Copy {
+ | ^^^^
+
+warning: trait bound for<'b> &'b mut i32: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76
+ |
+LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
+ | ^^^^
+
+warning: 4 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs
new file mode 100644
index 000000000..e0f299630
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs
@@ -0,0 +1,23 @@
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+struct B;
+
+trait A {
+ type X;
+ fn get_x() -> Self::X;
+}
+
+impl A for B {
+ type X = u8;
+ fn get_x() -> u8 { 0 }
+}
+
+fn global_bound_is_hidden() -> u8
+where
+ B: A<X = i32>
+{
+ B::get_x() //~ ERROR
+}
+
+fn main () {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr
new file mode 100644
index 000000000..26679e713
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+ --> $DIR/trivial-bounds-inconsistent-projection-error.rs:20:5
+ |
+LL | fn global_bound_is_hidden() -> u8
+ | -- expected `u8` because of return type
+...
+LL | B::get_x()
+ | ^^^^^^^^^^ expected `u8`, found `i32`
+ |
+help: you can convert an `i32` to a `u8` and panic if the converted value doesn't fit
+ |
+LL | B::get_x().try_into().unwrap()
+ | ++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs
new file mode 100644
index 000000000..b13956673
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs
@@ -0,0 +1,58 @@
+// run-pass
+// Check that global bounds result in the expected choice of associated type
+
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+struct B;
+
+trait A {
+ type X;
+ fn get_x() -> Self::X;
+}
+
+impl A for B {
+ type X = u8;
+ fn get_x() -> u8 { 0 }
+}
+
+fn underspecified_bound() -> u8
+where
+ B: A //~ WARNING trivial_bounds
+{
+ B::get_x()
+}
+
+fn inconsistent_bound() -> i32
+where
+ B: A<X = i32> //~ WARNING trivial_bounds
+{
+ B::get_x()
+}
+
+fn redundant_bound() -> u8
+where
+ B: A<X = u8> //~ WARNING trivial_bounds
+{
+ B::get_x()
+}
+
+fn inconsistent_dup_bound() -> i32
+where
+ B: A<X = i32> + A
+ //~^ WARNING trivial_bounds
+ //~| WARNING trivial_bounds
+{
+ B::get_x()
+}
+
+fn redundant_dup_bound() -> u8
+where
+ B: A<X = u8> + A
+ //~^ WARNING trivial_bounds
+ //~| WARNING trivial_bounds
+{
+ B::get_x()
+}
+
+fn main () {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr
new file mode 100644
index 000000000..ddc13c512
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr
@@ -0,0 +1,46 @@
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:21:8
+ |
+LL | B: A
+ | ^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:28:8
+ |
+LL | B: A<X = i32>
+ | ^^^^^^^^^^
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:35:8
+ |
+LL | B: A<X = u8>
+ | ^^^^^^^^^
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:42:8
+ |
+LL | B: A<X = i32> + A
+ | ^^^^^^^^^^
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:42:21
+ |
+LL | B: A<X = i32> + A
+ | ^
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:51:8
+ |
+LL | B: A<X = u8> + A
+ | ^^^^^^^^^
+
+warning: trait bound B: A does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:51:20
+ |
+LL | B: A<X = u8> + A
+ | ^
+
+warning: 7 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs
new file mode 100644
index 000000000..bfa083655
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs
@@ -0,0 +1,27 @@
+// run-pass
+// Check tautalogically false `Sized` bounds
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+trait A {}
+
+impl A for i32 {}
+
+struct T<X: ?Sized> {
+ x: X,
+}
+
+struct S(str, str) where str: Sized;
+//~^ WARNING Sized does not depend on any type or lifetime
+
+fn unsized_local() where for<'a> T<dyn A + 'a>: Sized {
+ //~^ WARNING Sized does not depend on any type or lifetime
+ let x: T<dyn A> = *(Box::new(T { x: 1 }) as Box<T<dyn A>>);
+}
+
+fn return_str() -> str where str: Sized {
+ //~^ WARNING Sized does not depend on any type or lifetime
+ *"Sized".to_string().into_boxed_str()
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr
new file mode 100644
index 000000000..cf24d811c
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr
@@ -0,0 +1,22 @@
+warning: trait bound str: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-sized.rs:14:31
+ |
+LL | struct S(str, str) where str: Sized;
+ | ^^^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound for<'a> T<(dyn A + 'a)>: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-sized.rs:17:49
+ |
+LL | fn unsized_local() where for<'a> T<dyn A + 'a>: Sized {
+ | ^^^^^
+
+warning: trait bound str: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-sized.rs:22:35
+ |
+LL | fn return_str() -> str where str: Sized {
+ | ^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs
new file mode 100644
index 000000000..9efa22b10
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs
@@ -0,0 +1,14 @@
+// run-pass
+// Test that inconsistent bounds are used in well-formedness checks
+#![feature(trivial_bounds)]
+
+use std::fmt::Debug;
+
+pub fn foo() where Vec<str>: Debug, str: Copy {
+ //~^ WARNING Debug does not depend on any type or lifetime
+ //~| WARNING Copy does not depend on any type or lifetime
+ let x = vec![*"1"];
+ println!("{:?}", x);
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr
new file mode 100644
index 000000000..8f58a99a8
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr
@@ -0,0 +1,16 @@
+warning: trait bound Vec<str>: Debug does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-well-formed.rs:7:30
+ |
+LL | pub fn foo() where Vec<str>: Debug, str: Copy {
+ | ^^^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound str: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent-well-formed.rs:7:42
+ |
+LL | pub fn foo() where Vec<str>: Debug, str: Copy {
+ | ^^^^
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs
new file mode 100644
index 000000000..7148f5d6d
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs
@@ -0,0 +1,74 @@
+// run-pass
+
+// Check that tautalogically false bounds are accepted, and are used
+// in type inference.
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+pub trait Foo {
+ fn test(&self);
+}
+
+fn generic_function<X: Foo>(x: X) {}
+
+enum E where i32: Foo { V } //~ WARNING trivial_bounds
+
+struct S where i32: Foo; //~ WARNING trivial_bounds
+
+trait T where i32: Foo {} //~ WARNING trivial_bounds
+
+union U where i32: Foo { f: i32 } //~ WARNING trivial_bounds
+
+type Y where i32: Foo = ();
+//~^ WARNING type_alias_bounds
+//~| WARNING trivial_bounds
+
+impl Foo for () where i32: Foo { //~ WARNING trivial_bounds
+ fn test(&self) {
+ 3i32.test();
+ Foo::test(&4i32);
+ generic_function(5i32);
+ }
+}
+
+fn f() where i32: Foo { //~ WARNING trivial_bounds
+ let s = S;
+ 3i32.test();
+ Foo::test(&4i32);
+ generic_function(5i32);
+}
+
+fn g() where &'static str: Foo { //~ WARNING trivial_bounds
+ "Foo".test();
+ Foo::test(&"Foo");
+ generic_function("Foo");
+}
+
+trait A {}
+
+impl A for i32 {}
+
+struct Dst<X: ?Sized> {
+ x: X,
+}
+
+struct TwoStrs(str, str) where str: Sized; //~ WARNING trivial_bounds
+
+fn unsized_local() where for<'a> Dst<dyn A + 'a>: Sized { //~ WARNING trivial_bounds
+ let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);
+}
+
+fn return_str() -> str where str: Sized { //~ WARNING trivial_bounds
+ *"Sized".to_string().into_boxed_str()
+}
+
+fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
+ //~^ WARNING trivial_bounds
+ -s
+}
+
+fn use_for() where i32: Iterator { //~ WARNING trivial_bounds
+ for _ in 2i32 {}
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
new file mode 100644
index 000000000..d66e46887
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
@@ -0,0 +1,95 @@
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:14:19
+ |
+LL | enum E where i32: Foo { V }
+ | ^^^
+ |
+ = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:16:21
+ |
+LL | struct S where i32: Foo;
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:18:20
+ |
+LL | trait T where i32: Foo {}
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:20:20
+ |
+LL | union U where i32: Foo { f: i32 }
+ | ^^^
+
+warning: where clauses are not enforced in type aliases
+ --> $DIR/trivial-bounds-inconsistent.rs:22:14
+ |
+LL | type Y where i32: Foo = ();
+ | ^^^^^^^^
+ |
+ = note: `#[warn(type_alias_bounds)]` on by default
+help: the clause will not be checked when the type alias is used, and should be removed
+ |
+LL - type Y where i32: Foo = ();
+LL + type Y = ();
+ |
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:22:19
+ |
+LL | type Y where i32: Foo = ();
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:26:28
+ |
+LL | impl Foo for () where i32: Foo {
+ | ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:34:19
+ |
+LL | fn f() where i32: Foo {
+ | ^^^
+
+warning: trait bound &'static str: Foo does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:41:28
+ |
+LL | fn g() where &'static str: Foo {
+ | ^^^
+
+warning: trait bound str: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:55:37
+ |
+LL | struct TwoStrs(str, str) where str: Sized;
+ | ^^^^^
+
+warning: trait bound for<'a> Dst<(dyn A + 'a)>: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:57:51
+ |
+LL | fn unsized_local() where for<'a> Dst<dyn A + 'a>: Sized {
+ | ^^^^^
+
+warning: trait bound str: Sized does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:61:35
+ |
+LL | fn return_str() -> str where str: Sized {
+ | ^^^^^
+
+warning: trait bound String: Neg does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:65:46
+ |
+LL | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: trait bound i32: Iterator does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-inconsistent.rs:70:25
+ |
+LL | fn use_for() where i32: Iterator {
+ | ^^^^^^^^
+
+warning: 14 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.rs b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.rs
new file mode 100644
index 000000000..cecc0b2da
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.rs
@@ -0,0 +1,12 @@
+// Check that false Copy bounds don't leak
+#![feature(trivial_bounds)]
+
+fn copy_out_string(t: &String) -> String where String: Copy {
+ *t
+}
+
+fn move_out_string(t: &String) -> String {
+ *t //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr
new file mode 100644
index 000000000..b3ec3cd8d
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of `*t` which is behind a shared reference
+ --> $DIR/trivial-bounds-leak-copy.rs:9:5
+ |
+LL | *t
+ | ^^ move occurs because `*t` has type `String`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.rs b/src/test/ui/trivial-bounds/trivial-bounds-leak.rs
new file mode 100644
index 000000000..249051d80
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.rs
@@ -0,0 +1,31 @@
+// Check that false bounds don't leak
+#![feature(trivial_bounds)]
+
+pub trait Foo {
+ fn test(&self);
+}
+
+fn return_str() -> str where str: Sized {
+ *"Sized".to_string().into_boxed_str()
+}
+
+fn cant_return_str() -> str { //~ ERROR
+ *"Sized".to_string().into_boxed_str()
+}
+
+fn my_function() where i32: Foo
+{
+ 3i32.test();
+ Foo::test(&4i32);
+ generic_function(5i32);
+}
+
+fn foo() {
+ 3i32.test(); //~ ERROR
+ Foo::test(&4i32); //~ ERROR
+ generic_function(5i32); //~ ERROR
+}
+
+fn generic_function<T: Foo>(t: T) {}
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
new file mode 100644
index 000000000..02c5d5d24
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
@@ -0,0 +1,48 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/trivial-bounds-leak.rs:12:25
+ |
+LL | fn cant_return_str() -> str {
+ | ^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `str`
+ = note: the return type of a function must have a statically known size
+
+error[E0599]: no method named `test` found for type `i32` in the current scope
+ --> $DIR/trivial-bounds-leak.rs:24:10
+ |
+LL | 3i32.test();
+ | ^^^^ method not found in `i32`
+ |
+ = help: items from traits can only be used if the trait is implemented and in scope
+note: `Foo` defines an item `test`, perhaps you need to implement it
+ --> $DIR/trivial-bounds-leak.rs:4:1
+ |
+LL | pub trait Foo {
+ | ^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `i32: Foo` is not satisfied
+ --> $DIR/trivial-bounds-leak.rs:25:15
+ |
+LL | Foo::test(&4i32);
+ | --------- ^^^^^ the trait `Foo` is not implemented for `i32`
+ | |
+ | required by a bound introduced by this call
+
+error[E0277]: the trait bound `i32: Foo` is not satisfied
+ --> $DIR/trivial-bounds-leak.rs:26:22
+ |
+LL | generic_function(5i32);
+ | ---------------- ^^^^ the trait `Foo` is not implemented for `i32`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `generic_function`
+ --> $DIR/trivial-bounds-leak.rs:29:24
+ |
+LL | fn generic_function<T: Foo>(t: T) {}
+ | ^^^ required by this bound in `generic_function`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-lint.rs b/src/test/ui/trivial-bounds/trivial-bounds-lint.rs
new file mode 100644
index 000000000..078578372
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-lint.rs
@@ -0,0 +1,40 @@
+#![feature(trivial_bounds)]
+#![allow(unused)]
+#![deny(trivial_bounds)]
+
+struct A where i32: Copy; //~ ERROR
+
+trait X<T: Copy> {}
+
+trait Y<T>: Copy {}
+
+trait Z {
+ type S: Copy;
+}
+
+// Check only the bound the user writes trigger the lint
+fn trivial_elaboration<T>() where T: X<i32> + Z<S = i32>, i32: Y<T> {} // OK
+
+fn global_param() where i32: X<()> {} //~ ERROR
+
+// Should only error on the trait bound, not the implicit
+// projection bound <i32 as Z>::S == i32.
+fn global_projection() where i32: Z<S = i32> {} //~ ERROR
+
+impl A {
+ fn new() -> A { A }
+}
+
+// Lifetime bounds should be linted as well
+fn global_lifetimes() where i32: 'static, &'static str: 'static {}
+//~^ ERROR
+//~| ERROR
+
+fn local_lifetimes<'a>() where i32: 'a, &'a str: 'a {} // OK
+
+fn global_outlives() where 'static: 'static {} //~ ERROR
+
+// Check that each bound is checked individually
+fn mixed_bounds<T: Copy>() where i32: X<T> + Copy {} //~ ERROR
+
+fn main() {}
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr
new file mode 100644
index 000000000..20e0ddfc2
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr
@@ -0,0 +1,50 @@
+error: trait bound i32: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:5:21
+ |
+LL | struct A where i32: Copy;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/trivial-bounds-lint.rs:3:9
+ |
+LL | #![deny(trivial_bounds)]
+ | ^^^^^^^^^^^^^^
+
+error: trait bound i32: X<()> does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:18:30
+ |
+LL | fn global_param() where i32: X<()> {}
+ | ^^^^^
+
+error: trait bound i32: Z does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:22:35
+ |
+LL | fn global_projection() where i32: Z<S = i32> {}
+ | ^^^^^^^^^^
+
+error: lifetime bound i32: 'static does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:29:34
+ |
+LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {}
+ | ^^^^^^^
+
+error: lifetime bound &'static str: 'static does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:29:57
+ |
+LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {}
+ | ^^^^^^^
+
+error: lifetime bound 'static: 'static does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:35:37
+ |
+LL | fn global_outlives() where 'static: 'static {}
+ | ^^^^^^^
+
+error: trait bound i32: Copy does not depend on any type or lifetime parameters
+ --> $DIR/trivial-bounds-lint.rs:38:46
+ |
+LL | fn mixed_bounds<T: Copy>() where i32: X<T> + Copy {}
+ | ^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-object.rs b/src/test/ui/trivial-bounds/trivial-bounds-object.rs
new file mode 100644
index 000000000..f5feeea7c
--- /dev/null
+++ b/src/test/ui/trivial-bounds/trivial-bounds-object.rs
@@ -0,0 +1,18 @@
+// run-pass
+// Check that the object bound dyn A + 'a: A is preferred over the
+// where clause bound dyn A + 'static: A.
+
+#![allow(unused)]
+
+trait A {
+ fn test(&self);
+}
+
+fn foo(x: &dyn A)
+where
+ dyn A + 'static: A, // Using this bound would lead to a lifetime error.
+{
+ x.test();
+}
+
+fn main () {}