about summary refs log tree commit diff
path: root/tests/ui/traits/bound
diff options
context:
space:
mode:
authorAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-05 09:13:28 +0100
committerAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-11 09:32:08 +0000
commitcf2dff2b1e3fa55fa5415d524200070d0d7aacfe (patch)
tree40a88d9a46aaf3e8870676eb2538378b75a263eb /tests/ui/traits/bound
parentca855e6e42787ecd062d81d53336fe6788ef51a9 (diff)
downloadrust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.tar.gz
rust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.zip
Move /src/test to /tests
Diffstat (limited to 'tests/ui/traits/bound')
-rw-r--r--tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs11
-rw-r--r--tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr20
-rw-r--r--tests/ui/traits/bound/auxiliary/crate_a1.rs9
-rw-r--r--tests/ui/traits/bound/auxiliary/crate_a2.rs13
-rw-r--r--tests/ui/traits/bound/auxiliary/on_structs_and_enums_xc.rs13
-rw-r--r--tests/ui/traits/bound/basic.rs25
-rw-r--r--tests/ui/traits/bound/generic_trait.rs30
-rw-r--r--tests/ui/traits/bound/impl-comparison-duplicates.rs16
-rw-r--r--tests/ui/traits/bound/in-arc.rs108
-rw-r--r--tests/ui/traits/bound/multiple.rs9
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait.rs13
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait.stderr34
-rw-r--r--tests/ui/traits/bound/not-on-struct.rs38
-rw-r--r--tests/ui/traits/bound/not-on-struct.stderr175
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-in-fns.rs20
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr27
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-in-impls.rs25
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr15
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-locals.rs17
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-locals.stderr27
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-rpass.rs21
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-static.rs15
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-static.stderr15
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-xc.rs14
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-xc.stderr27
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-xc1.rs15
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-xc1.stderr27
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums.rs43
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums.stderr99
-rw-r--r--tests/ui/traits/bound/recursion.rs20
-rw-r--r--tests/ui/traits/bound/same-crate-name.rs55
-rw-r--r--tests/ui/traits/bound/same-crate-name.stderr75
-rw-r--r--tests/ui/traits/bound/sugar.rs19
-rw-r--r--tests/ui/traits/bound/sugar.stderr19
34 files changed, 1109 insertions, 0 deletions
diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs
new file mode 100644
index 00000000000..f9a93476411
--- /dev/null
+++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs
@@ -0,0 +1,11 @@
+fn strip_lf(s: &str) -> &str {
+    s.strip_suffix(b'\n').unwrap_or(s)
+    //~^ ERROR expected a `FnMut<(char,)>` closure, found `u8`
+    //~| NOTE expected an `FnMut<(char,)>` closure, found `u8`
+    //~| HELP the trait `FnMut<(char,)>` is not implemented for `u8`
+    //~| HELP the following other types implement trait `Pattern<'a>`:
+    //~| NOTE required for `u8` to implement `Pattern<'_>`
+
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
new file mode 100644
index 00000000000..ce9ab2d811a
--- /dev/null
+++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
@@ -0,0 +1,20 @@
+error[E0277]: expected a `FnMut<(char,)>` closure, found `u8`
+  --> $DIR/assoc-fn-bound-root-obligation.rs:2:7
+   |
+LL |     s.strip_suffix(b'\n').unwrap_or(s)
+   |       ^^^^^^^^^^^^ expected an `FnMut<(char,)>` closure, found `u8`
+   |
+   = help: the trait `FnMut<(char,)>` is not implemented for `u8`
+   = help: the following other types implement trait `Pattern<'a>`:
+             &'b String
+             &'b [char; N]
+             &'b [char]
+             &'b str
+             &'c &'b str
+             [char; N]
+             char
+   = note: required for `u8` to implement `Pattern<'_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/auxiliary/crate_a1.rs b/tests/ui/traits/bound/auxiliary/crate_a1.rs
new file mode 100644
index 00000000000..6aa010258eb
--- /dev/null
+++ b/tests/ui/traits/bound/auxiliary/crate_a1.rs
@@ -0,0 +1,9 @@
+pub trait Bar {}
+
+pub fn try_foo(x: impl Bar) {}
+
+pub struct ImplementsTraitForUsize<T> {
+    _marker: std::marker::PhantomData<T>,
+}
+
+impl Bar for ImplementsTraitForUsize<usize> {}
diff --git a/tests/ui/traits/bound/auxiliary/crate_a2.rs b/tests/ui/traits/bound/auxiliary/crate_a2.rs
new file mode 100644
index 00000000000..d6057db5e63
--- /dev/null
+++ b/tests/ui/traits/bound/auxiliary/crate_a2.rs
@@ -0,0 +1,13 @@
+pub struct Foo;
+
+pub trait Bar {}
+
+impl Bar for Foo {}
+
+pub struct DoesNotImplementTrait;
+
+pub struct ImplementsWrongTraitConditionally<T> {
+    _marker: std::marker::PhantomData<T>,
+}
+
+impl Bar for ImplementsWrongTraitConditionally<isize> {}
diff --git a/tests/ui/traits/bound/auxiliary/on_structs_and_enums_xc.rs b/tests/ui/traits/bound/auxiliary/on_structs_and_enums_xc.rs
new file mode 100644
index 00000000000..7e9592eee2c
--- /dev/null
+++ b/tests/ui/traits/bound/auxiliary/on_structs_and_enums_xc.rs
@@ -0,0 +1,13 @@
+pub trait Trait {
+    fn dummy(&self) { }
+}
+
+pub struct Foo<T:Trait> {
+    pub x: T,
+}
+
+pub enum Bar<T:Trait> {
+    ABar(isize),
+    BBar(T),
+    CBar(usize),
+}
diff --git a/tests/ui/traits/bound/basic.rs b/tests/ui/traits/bound/basic.rs
new file mode 100644
index 00000000000..8c8a7eb7d9d
--- /dev/null
+++ b/tests/ui/traits/bound/basic.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unconditional_recursion)]
+
+// pretty-expanded FIXME #23616
+
+trait Foo {
+}
+
+fn b(_x: Box<dyn Foo+Send>) {
+}
+
+fn c(x: Box<dyn Foo+Sync+Send>) {
+    e(x);
+}
+
+fn d(x: Box<dyn Foo+Send>) {
+    e(x);
+}
+
+fn e(x: Box<dyn Foo>) {
+    e(x);
+}
+
+pub fn main() { }
diff --git a/tests/ui/traits/bound/generic_trait.rs b/tests/ui/traits/bound/generic_trait.rs
new file mode 100644
index 00000000000..18382bb59a4
--- /dev/null
+++ b/tests/ui/traits/bound/generic_trait.rs
@@ -0,0 +1,30 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+trait connection {
+    fn read(&self) -> isize;
+}
+
+trait connection_factory<C:connection> {
+    fn create(&self) -> C;
+}
+
+type my_connection = ();
+type my_connection_factory = ();
+
+impl connection for () {
+    fn read(&self) -> isize { 43 }
+}
+
+impl connection_factory<my_connection> for my_connection_factory {
+    fn create(&self) -> my_connection { () }
+}
+
+pub fn main() {
+    let factory = ();
+    let connection = factory.create();
+    let result = connection.read();
+    assert_eq!(result, 43);
+}
diff --git a/tests/ui/traits/bound/impl-comparison-duplicates.rs b/tests/ui/traits/bound/impl-comparison-duplicates.rs
new file mode 100644
index 00000000000..de6c2afa2bb
--- /dev/null
+++ b/tests/ui/traits/bound/impl-comparison-duplicates.rs
@@ -0,0 +1,16 @@
+// run-pass
+// Tests that type parameter bounds on an implementation need not match the
+// trait exactly, as long as the implementation doesn't demand *more* bounds
+// than the trait.
+
+// pretty-expanded FIXME #23616
+
+trait A {
+    fn foo<T: Eq + Ord>(&self);
+}
+
+impl A for isize {
+    fn foo<T: Ord>(&self) {} // Ord implies Eq, so this is ok.
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/in-arc.rs b/tests/ui/traits/bound/in-arc.rs
new file mode 100644
index 00000000000..a1492c0b982
--- /dev/null
+++ b/tests/ui/traits/bound/in-arc.rs
@@ -0,0 +1,108 @@
+// run-pass
+#![allow(unused_must_use)]
+// Tests that a heterogeneous list of existential `dyn` types can be put inside an Arc
+// and shared between threads as long as all types fulfill Send.
+
+// ignore-emscripten no threads support
+
+use std::sync::Arc;
+use std::sync::mpsc::channel;
+use std::thread;
+
+trait Pet {
+    fn name(&self, blk: Box<dyn FnMut(&str)>);
+    fn num_legs(&self) -> usize;
+    fn of_good_pedigree(&self) -> bool;
+}
+
+struct Catte {
+    num_whiskers: usize,
+    name: String,
+}
+
+struct Dogge {
+    bark_decibels: usize,
+    tricks_known: usize,
+    name: String,
+}
+
+struct Goldfyshe {
+    swim_speed: usize,
+    name: String,
+}
+
+impl Pet for Catte {
+    fn name(&self, mut blk: Box<dyn FnMut(&str)>) { blk(&self.name) }
+    fn num_legs(&self) -> usize { 4 }
+    fn of_good_pedigree(&self) -> bool { self.num_whiskers >= 4 }
+}
+impl Pet for Dogge {
+    fn name(&self, mut blk: Box<dyn FnMut(&str)>) { blk(&self.name) }
+    fn num_legs(&self) -> usize { 4 }
+    fn of_good_pedigree(&self) -> bool {
+        self.bark_decibels < 70 || self.tricks_known > 20
+    }
+}
+impl Pet for Goldfyshe {
+    fn name(&self, mut blk: Box<dyn FnMut(&str)>) { blk(&self.name) }
+    fn num_legs(&self) -> usize { 0 }
+    fn of_good_pedigree(&self) -> bool { self.swim_speed >= 500 }
+}
+
+pub fn main() {
+    let catte = Catte { num_whiskers: 7, name: "alonzo_church".to_string() };
+    let dogge1 = Dogge {
+        bark_decibels: 100,
+        tricks_known: 42,
+        name: "alan_turing".to_string(),
+    };
+    let dogge2 = Dogge {
+        bark_decibels: 55,
+        tricks_known: 11,
+        name: "albert_einstein".to_string(),
+    };
+    let fishe = Goldfyshe {
+        swim_speed: 998,
+        name: "alec_guinness".to_string(),
+    };
+    let arc = Arc::new(vec![
+        Box::new(catte)  as Box<dyn Pet+Sync+Send>,
+        Box::new(dogge1) as Box<dyn Pet+Sync+Send>,
+        Box::new(fishe)  as Box<dyn Pet+Sync+Send>,
+        Box::new(dogge2) as Box<dyn Pet+Sync+Send>]);
+    let (tx1, rx1) = channel();
+    let arc1 = arc.clone();
+    let t1 = thread::spawn(move|| { check_legs(arc1); tx1.send(()); });
+    let (tx2, rx2) = channel();
+    let arc2 = arc.clone();
+    let t2 = thread::spawn(move|| { check_names(arc2); tx2.send(()); });
+    let (tx3, rx3) = channel();
+    let arc3 = arc.clone();
+    let t3 = thread::spawn(move|| { check_pedigree(arc3); tx3.send(()); });
+    rx1.recv();
+    rx2.recv();
+    rx3.recv();
+    t1.join();
+    t2.join();
+    t3.join();
+}
+
+fn check_legs(arc: Arc<Vec<Box<dyn Pet+Sync+Send>>>) {
+    let mut legs = 0;
+    for pet in arc.iter() {
+        legs += pet.num_legs();
+    }
+    assert!(legs == 12);
+}
+fn check_names(arc: Arc<Vec<Box<dyn Pet+Sync+Send>>>) {
+    for pet in arc.iter() {
+        pet.name(Box::new(|name| {
+            assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
+        }))
+    }
+}
+fn check_pedigree(arc: Arc<Vec<Box<dyn Pet+Sync+Send>>>) {
+    for pet in arc.iter() {
+        assert!(pet.of_good_pedigree());
+    }
+}
diff --git a/tests/ui/traits/bound/multiple.rs b/tests/ui/traits/bound/multiple.rs
new file mode 100644
index 00000000000..868b334070b
--- /dev/null
+++ b/tests/ui/traits/bound/multiple.rs
@@ -0,0 +1,9 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+fn f<T:PartialEq + PartialOrd>(_: T) {
+}
+
+pub fn main() {
+    f(3);
+}
diff --git a/tests/ui/traits/bound/not-on-bare-trait.rs b/tests/ui/traits/bound/not-on-bare-trait.rs
new file mode 100644
index 00000000000..daf18c6702e
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-bare-trait.rs
@@ -0,0 +1,13 @@
+trait Foo {
+    fn dummy(&self) {}
+}
+
+// This should emit the less confusing error, not the more confusing one.
+
+fn foo(_x: Foo + Send) {
+    //~^ ERROR the size for values of type
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
new file mode 100644
index 00000000000..36b08a7d309
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -0,0 +1,34 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/not-on-bare-trait.rs:7:12
+   |
+LL | fn foo(_x: Foo + Send) {
+   |            ^^^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: use `dyn`
+   |
+LL | fn foo(_x: dyn Foo + Send) {
+   |            +++
+
+error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
+  --> $DIR/not-on-bare-trait.rs:7:8
+   |
+LL | fn foo(_x: Foo + Send) {
+   |        ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
+   = help: unsized fn params are gated as an unstable feature
+help: you can use `impl Trait` as the argument type
+   |
+LL | fn foo(_x: impl Foo + Send) {
+   |            ++++
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL | fn foo(_x: &Foo + Send) {
+   |            +
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/not-on-struct.rs b/tests/ui/traits/bound/not-on-struct.rs
new file mode 100644
index 00000000000..8633e9d7a4c
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-struct.rs
@@ -0,0 +1,38 @@
+// We don't need those errors. Ideally we would silence them, but to do so we need to move the
+// lint from being an early-lint during parsing to a late-lint, because it needs to be aware of
+// the types involved.
+#![allow(bare_trait_objects)]
+
+struct Foo;
+
+fn foo(_x: Box<Foo + Send>) { } //~ ERROR expected trait, found struct `Foo`
+
+type TypeAlias<T> = Box<dyn Vec<T>>; //~ ERROR expected trait, found struct `Vec`
+
+struct A;
+fn a() -> A + 'static { //~ ERROR expected trait, found
+    A
+}
+fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) { //~ ERROR expected trait, found
+    panic!()
+}
+fn c() -> 'static + A { //~ ERROR expected trait, found
+    A
+}
+fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) { //~ ERROR expected trait, found
+    panic!()
+}
+fn e() -> 'static + A + 'static { //~ ERROR expected trait, found
+//~^ ERROR only a single explicit lifetime bound is permitted
+    A
+}
+fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) { //~ ERROR expected trait, found
+//~^ ERROR only a single explicit lifetime bound is permitted
+    panic!()
+}
+struct Traitor;
+trait Trait {}
+fn g() -> Traitor + 'static { //~ ERROR expected trait, found struct `Traitor`
+    A
+}
+fn main() {}
diff --git a/tests/ui/traits/bound/not-on-struct.stderr b/tests/ui/traits/bound/not-on-struct.stderr
new file mode 100644
index 00000000000..2de35dc7fc3
--- /dev/null
+++ b/tests/ui/traits/bound/not-on-struct.stderr
@@ -0,0 +1,175 @@
+error[E0226]: only a single explicit lifetime bound is permitted
+  --> $DIR/not-on-struct.rs:25:25
+   |
+LL | fn e() -> 'static + A + 'static {
+   |                         ^^^^^^^
+
+error[E0226]: only a single explicit lifetime bound is permitted
+  --> $DIR/not-on-struct.rs:29:53
+   |
+LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) {
+   |                                                     ^^
+
+error[E0404]: expected trait, found struct `Foo`
+  --> $DIR/not-on-struct.rs:8:16
+   |
+LL | fn foo(_x: Box<Foo + Send>) { }
+   |                ^^^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:8:22
+   |
+LL | fn foo(_x: Box<Foo + Send>) { }
+   |                ---   ^^^^ ...because of this bound
+   |                |
+   |                expected this type to be a trait...
+
+error[E0404]: expected trait, found struct `Vec`
+  --> $DIR/not-on-struct.rs:10:29
+   |
+LL | type TypeAlias<T> = Box<dyn Vec<T>>;
+   |                             ^^^^^^ not a trait
+
+error[E0404]: expected trait, found struct `A`
+  --> $DIR/not-on-struct.rs:13:11
+   |
+LL | fn a() -> A + 'static {
+   |           ^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:13:15
+   |
+LL | fn a() -> A + 'static {
+   |           -   ^^^^^^^ ...because of this bound
+   |           |
+   |           expected this type to be a trait...
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn a() -> A + 'static {
+LL + fn a() -> A {
+   |
+
+error[E0404]: expected trait, found enum `Result`
+  --> $DIR/not-on-struct.rs:16:34
+   |
+LL | fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) {
+   |                                  ^^^^^^^^^^^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:16:48
+   |
+LL | fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) {
+   |                                  -----------   ^^ ...because of this bound
+   |                                  |
+   |                                  expected this type to be a trait...
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn b<'a,T,E>(iter: Iterator<Item=Result<T,E> + 'a>) {
+LL + fn b<'a,T,E>(iter: Iterator<Item=Result<T,E>>) {
+   |
+
+error[E0404]: expected trait, found struct `A`
+  --> $DIR/not-on-struct.rs:19:21
+   |
+LL | fn c() -> 'static + A {
+   |                     ^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:19:11
+   |
+LL | fn c() -> 'static + A {
+   |           ^^^^^^^   - expected this type to be a trait...
+   |           |
+   |           ...because of this bound
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn c() -> 'static + A {
+LL + fn c() -> A {
+   |
+
+error[E0404]: expected trait, found enum `Result`
+  --> $DIR/not-on-struct.rs:22:39
+   |
+LL | fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) {
+   |                                       ^^^^^^^^^^^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:22:34
+   |
+LL | fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) {
+   |                                  ^^   ----------- expected this type to be a trait...
+   |                                  |
+   |                                  ...because of this bound
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn d<'a,T,E>(iter: Iterator<Item='a + Result<T,E>>) {
+LL + fn d<'a,T,E>(iter: Iterator<Item=Result<T,E>>) {
+   |
+
+error[E0404]: expected trait, found struct `A`
+  --> $DIR/not-on-struct.rs:25:21
+   |
+LL | fn e() -> 'static + A + 'static {
+   |                     ^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:25:11
+   |
+LL | fn e() -> 'static + A + 'static {
+   |           ^^^^^^^   -   ^^^^^^^ ...because of these bounds
+   |                     |
+   |                     expected this type to be a trait...
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn e() -> 'static + A + 'static {
+LL + fn e() -> A {
+   |
+
+error[E0404]: expected trait, found enum `Result`
+  --> $DIR/not-on-struct.rs:29:39
+   |
+LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) {
+   |                                       ^^^^^^^^^^^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:29:34
+   |
+LL | fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) {
+   |                                  ^^   -----------   ^^ ...because of these bounds
+   |                                       |
+   |                                       expected this type to be a trait...
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn f<'a,T,E>(iter: Iterator<Item='a + Result<T,E> + 'a>) {
+LL + fn f<'a,T,E>(iter: Iterator<Item=Result<T,E>>) {
+   |
+
+error[E0404]: expected trait, found struct `Traitor`
+  --> $DIR/not-on-struct.rs:35:11
+   |
+LL | trait Trait {}
+   | ----------- similarly named trait `Trait` defined here
+LL | fn g() -> Traitor + 'static {
+   |           ^^^^^^^ not a trait
+   |
+help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way
+  --> $DIR/not-on-struct.rs:35:21
+   |
+LL | fn g() -> Traitor + 'static {
+   |           -------   ^^^^^^^ ...because of this bound
+   |           |
+   |           expected this type to be a trait...
+help: if you meant to use a type and not a trait here, remove the bounds
+   |
+LL - fn g() -> Traitor + 'static {
+LL + fn g() -> Traitor {
+   |
+help: a trait with a similar name exists
+   |
+LL | fn g() -> Trait + 'static {
+   |           ~~~~~
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0226, E0404.
+For more information about an error, try `rustc --explain E0226`.
diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-fns.rs b/tests/ui/traits/bound/on-structs-and-enums-in-fns.rs
new file mode 100644
index 00000000000..6a6fcf5301d
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-in-fns.rs
@@ -0,0 +1,20 @@
+trait Trait {}
+
+struct Foo<T:Trait> {
+    x: T,
+}
+
+enum Bar<T:Trait> {
+    ABar(isize),
+    BBar(T),
+    CBar(usize),
+}
+
+fn explode(x: Foo<u32>) {}
+//~^ ERROR E0277
+
+fn kaboom(y: Bar<f32>) {}
+//~^ ERROR E0277
+
+fn main() {
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr
new file mode 100644
index 00000000000..61237a63e32
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `u32: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-in-fns.rs:13:15
+   |
+LL | fn explode(x: Foo<u32>) {}
+   |               ^^^^^^^^ the trait `Trait` is not implemented for `u32`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-in-fns.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error[E0277]: the trait bound `f32: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-in-fns.rs:16:14
+   |
+LL | fn kaboom(y: Bar<f32>) {}
+   |              ^^^^^^^^ the trait `Trait` is not implemented for `f32`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/on-structs-and-enums-in-fns.rs:7:12
+   |
+LL | enum Bar<T:Trait> {
+   |            ^^^^^ 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/tests/ui/traits/bound/on-structs-and-enums-in-impls.rs b/tests/ui/traits/bound/on-structs-and-enums-in-impls.rs
new file mode 100644
index 00000000000..d379499521c
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-in-impls.rs
@@ -0,0 +1,25 @@
+trait Trait {}
+
+struct Foo<T:Trait> {
+    x: T,
+}
+
+enum Bar<T:Trait> {
+    ABar(isize),
+    BBar(T),
+    CBar(usize),
+}
+
+trait PolyTrait<T>
+{
+    fn whatever(&self, t: T) {}
+}
+
+struct Struct;
+
+impl PolyTrait<Foo<u16>> for Struct {
+//~^ ERROR E0277
+}
+
+fn main() {
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr
new file mode 100644
index 00000000000..8a43742260b
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u16: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-in-impls.rs:20:6
+   |
+LL | impl PolyTrait<Foo<u16>> for Struct {
+   |      ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u16`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-in-impls.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.rs b/tests/ui/traits/bound/on-structs-and-enums-locals.rs
new file mode 100644
index 00000000000..60ba343bb0a
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-locals.rs
@@ -0,0 +1,17 @@
+trait Trait {
+    fn dummy(&self) { }
+}
+
+struct Foo<T:Trait> {
+    x: T,
+}
+
+fn main() {
+    let foo = Foo {
+        x: 3
+    //~^ ERROR E0277
+    };
+
+    let baz: Foo<usize> = loop { };
+    //~^ ERROR E0277
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr
new file mode 100644
index 00000000000..20bbe69c059
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-locals.rs:15:14
+   |
+LL |     let baz: Foo<usize> = loop { };
+   |              ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-locals.rs:5:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error[E0277]: the trait bound `{integer}: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-locals.rs:11:12
+   |
+LL |         x: 3
+   |            ^ the trait `Trait` is not implemented for `{integer}`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-locals.rs:5:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/on-structs-and-enums-rpass.rs b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs
new file mode 100644
index 00000000000..4dc4fecc91f
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+// pretty-expanded FIXME #23616
+
+trait U {}
+trait T<X: U> { fn get(self) -> X; }
+
+trait S2<Y: U> {
+    fn m(x: Box<dyn T<Y>+'static>) {}
+}
+
+struct St<X: U> {
+    f: Box<dyn T<X>+'static>,
+}
+
+impl<X: U> St<X> {
+    fn blah() {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.rs b/tests/ui/traits/bound/on-structs-and-enums-static.rs
new file mode 100644
index 00000000000..df3f8b8a599
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-static.rs
@@ -0,0 +1,15 @@
+trait Trait {
+    fn dummy(&self) { }
+}
+
+struct Foo<T:Trait> {
+    x: T,
+}
+
+static X: Foo<usize> = Foo {
+//~^ ERROR E0277
+    x: 1,
+};
+
+fn main() {
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr
new file mode 100644
index 00000000000..fda734e8571
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-static.rs:9:11
+   |
+LL | static X: Foo<usize> = Foo {
+   |           ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-static.rs:5:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc.rs b/tests/ui/traits/bound/on-structs-and-enums-xc.rs
new file mode 100644
index 00000000000..94316d24040
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-xc.rs
@@ -0,0 +1,14 @@
+// aux-build:on_structs_and_enums_xc.rs
+
+extern crate on_structs_and_enums_xc;
+
+use on_structs_and_enums_xc::{Bar, Foo, Trait};
+
+fn explode(x: Foo<usize>) {}
+//~^ ERROR E0277
+
+fn kaboom(y: Bar<f32>) {}
+//~^ ERROR E0277
+
+fn main() {
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr
new file mode 100644
index 00000000000..5064b60bfd5
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-xc.rs:7:15
+   |
+LL | fn explode(x: Foo<usize>) {}
+   |               ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18
+   |
+LL | pub struct Foo<T:Trait> {
+   |                  ^^^^^ required by this bound in `Foo`
+
+error[E0277]: the trait bound `f32: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-xc.rs:10:14
+   |
+LL | fn kaboom(y: Bar<f32>) {}
+   |              ^^^^^^^^ the trait `Trait` is not implemented for `f32`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
+   |
+LL | pub enum Bar<T:Trait> {
+   |                ^^^^^ 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/tests/ui/traits/bound/on-structs-and-enums-xc1.rs b/tests/ui/traits/bound/on-structs-and-enums-xc1.rs
new file mode 100644
index 00000000000..5ef35b513e0
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.rs
@@ -0,0 +1,15 @@
+// aux-build:on_structs_and_enums_xc.rs
+
+extern crate on_structs_and_enums_xc;
+
+use on_structs_and_enums_xc::{Bar, Foo, Trait};
+
+fn main() {
+    let foo = Foo {
+        x: 3
+    //~^ ERROR E0277
+    };
+    let bar: Bar<f64> = return;
+    //~^ ERROR E0277
+    let _ = bar;
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr
new file mode 100644
index 00000000000..3fb5decb723
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `f64: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-xc1.rs:12:14
+   |
+LL |     let bar: Bar<f64> = return;
+   |              ^^^^^^^^ the trait `Trait` is not implemented for `f64`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
+   |
+LL | pub enum Bar<T:Trait> {
+   |                ^^^^^ required by this bound in `Bar`
+
+error[E0277]: the trait bound `{integer}: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-xc1.rs:9:12
+   |
+LL |         x: 3
+   |            ^ the trait `Trait` is not implemented for `{integer}`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18
+   |
+LL | pub struct Foo<T:Trait> {
+   |                  ^^^^^ required by this bound in `Foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/on-structs-and-enums.rs b/tests/ui/traits/bound/on-structs-and-enums.rs
new file mode 100644
index 00000000000..024084fa724
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums.rs
@@ -0,0 +1,43 @@
+trait Trait {}
+
+struct Foo<T:Trait> {
+    x: T,
+}
+
+enum Bar<T:Trait> {
+    ABar(isize),
+    BBar(T),
+    CBar(usize),
+}
+
+impl<T> Foo<T> {
+//~^ ERROR `T: Trait` is not satisfied
+    fn uhoh() {}
+}
+
+struct Baz {
+    a: Foo<isize>, //~ ERROR E0277
+}
+
+enum Boo {
+    Quux(Bar<usize>), //~ ERROR E0277
+}
+
+struct Badness<U> {
+    b: Foo<U>, //~ ERROR E0277
+}
+
+enum MoreBadness<V> {
+    EvenMoreBadness(Bar<V>), //~ ERROR E0277
+}
+
+struct TupleLike(
+    Foo<i32>, //~ ERROR E0277
+);
+
+enum Enum {
+    DictionaryLike { field: Bar<u8> }, //~ ERROR E0277
+}
+
+fn main() {
+}
diff --git a/tests/ui/traits/bound/on-structs-and-enums.stderr b/tests/ui/traits/bound/on-structs-and-enums.stderr
new file mode 100644
index 00000000000..fe05b86344b
--- /dev/null
+++ b/tests/ui/traits/bound/on-structs-and-enums.stderr
@@ -0,0 +1,99 @@
+error[E0277]: the trait bound `T: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:13:9
+   |
+LL | impl<T> Foo<T> {
+   |         ^^^^^^ the trait `Trait` is not implemented for `T`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: Trait> Foo<T> {
+   |       +++++++
+
+error[E0277]: the trait bound `isize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:19:8
+   |
+LL |     a: Foo<isize>,
+   |        ^^^^^^^^^^ the trait `Trait` is not implemented for `isize`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:23:10
+   |
+LL |     Quux(Bar<usize>),
+   |          ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/on-structs-and-enums.rs:7:12
+   |
+LL | enum Bar<T:Trait> {
+   |            ^^^^^ required by this bound in `Bar`
+
+error[E0277]: the trait bound `U: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:27:8
+   |
+LL |     b: Foo<U>,
+   |        ^^^^^^ the trait `Trait` is not implemented for `U`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+help: consider restricting type parameter `U`
+   |
+LL | struct Badness<U: Trait> {
+   |                 +++++++
+
+error[E0277]: the trait bound `V: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:31:21
+   |
+LL |     EvenMoreBadness(Bar<V>),
+   |                     ^^^^^^ the trait `Trait` is not implemented for `V`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/on-structs-and-enums.rs:7:12
+   |
+LL | enum Bar<T:Trait> {
+   |            ^^^^^ required by this bound in `Bar`
+help: consider restricting type parameter `V`
+   |
+LL | enum MoreBadness<V: Trait> {
+   |                   +++++++
+
+error[E0277]: the trait bound `i32: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:35:5
+   |
+LL |     Foo<i32>,
+   |     ^^^^^^^^ the trait `Trait` is not implemented for `i32`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums.rs:3:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+
+error[E0277]: the trait bound `u8: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums.rs:39:29
+   |
+LL |     DictionaryLike { field: Bar<u8> },
+   |                             ^^^^^^^ the trait `Trait` is not implemented for `u8`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/on-structs-and-enums.rs:7:12
+   |
+LL | enum Bar<T:Trait> {
+   |            ^^^^^ required by this bound in `Bar`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/recursion.rs b/tests/ui/traits/bound/recursion.rs
new file mode 100644
index 00000000000..0023ff654e8
--- /dev/null
+++ b/tests/ui/traits/bound/recursion.rs
@@ -0,0 +1,20 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+trait I { fn i(&self) -> Self; }
+
+trait A<T:I> {
+    fn id(x:T) -> T { x.i() }
+}
+
+trait J<T> { fn j(&self) -> T; }
+
+trait B<T:J<T>> {
+    fn id(x:T) -> T { x.j() }
+}
+
+trait C {
+    fn id<T:J<T>>(x:T) -> T { x.j() }
+}
+
+pub fn main() { }
diff --git a/tests/ui/traits/bound/same-crate-name.rs b/tests/ui/traits/bound/same-crate-name.rs
new file mode 100644
index 00000000000..8d646a41459
--- /dev/null
+++ b/tests/ui/traits/bound/same-crate-name.rs
@@ -0,0 +1,55 @@
+// aux-build:crate_a1.rs
+// aux-build:crate_a2.rs
+
+// Issue 22750
+// This tests the extra help message reported when a trait bound
+// is not met but the struct implements a trait with the same path.
+
+fn main() {
+    let foo = {
+        extern crate crate_a2 as a;
+        a::Foo
+    };
+
+    let implements_no_traits = {
+        extern crate crate_a2 as a;
+        a::DoesNotImplementTrait
+    };
+
+    let other_variant_implements_mismatched_trait = {
+        extern crate crate_a2 as a;
+        a::ImplementsWrongTraitConditionally { _marker: std::marker::PhantomData::<isize> }
+    };
+
+    let other_variant_implements_correct_trait = {
+        extern crate crate_a1 as a;
+        a::ImplementsTraitForUsize { _marker: std::marker::PhantomData::<isize> }
+    };
+
+    {
+        extern crate crate_a1 as a;
+        a::try_foo(foo);
+        //~^ ERROR E0277
+        //~| trait impl with same name found
+        //~| perhaps two different versions of crate `crate_a2`
+
+        // We don't want to see the "version mismatch" help message here
+        // because `implements_no_traits` has no impl for `Foo`
+        a::try_foo(implements_no_traits);
+        //~^ ERROR E0277
+
+        // We don't want to see the "version mismatch" help message here
+        // because `other_variant_implements_mismatched_trait`
+        // does not have an impl for its `<isize>` variant,
+        // only for its `<usize>` variant.
+        a::try_foo(other_variant_implements_mismatched_trait);
+        //~^ ERROR E0277
+
+        // We don't want to see the "version mismatch" help message here
+        // because `ImplementsTraitForUsize` only has
+        // impls for the correct trait where the path is not misleading.
+        a::try_foo(other_variant_implements_correct_trait);
+        //~^ ERROR E0277
+        //~| the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize<usize>`
+    }
+}
diff --git a/tests/ui/traits/bound/same-crate-name.stderr b/tests/ui/traits/bound/same-crate-name.stderr
new file mode 100644
index 00000000000..f66cad77fcd
--- /dev/null
+++ b/tests/ui/traits/bound/same-crate-name.stderr
@@ -0,0 +1,75 @@
+error[E0277]: the trait bound `Foo: main::a::Bar` is not satisfied
+  --> $DIR/same-crate-name.rs:31:20
+   |
+LL |         a::try_foo(foo);
+   |         ---------- ^^^ the trait `main::a::Bar` is not implemented for `Foo`
+   |         |
+   |         required by a bound introduced by this call
+   |
+help: trait impl with same name found
+  --> $DIR/auxiliary/crate_a2.rs:5:1
+   |
+LL | impl Bar for Foo {}
+   | ^^^^^^^^^^^^^^^^
+   = note: perhaps two different versions of crate `crate_a2` are being used?
+   = help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize<usize>`
+note: required by a bound in `try_foo`
+  --> $DIR/auxiliary/crate_a1.rs:3:24
+   |
+LL | pub fn try_foo(x: impl Bar) {}
+   |                        ^^^ required by this bound in `try_foo`
+
+error[E0277]: the trait bound `DoesNotImplementTrait: main::a::Bar` is not satisfied
+  --> $DIR/same-crate-name.rs:38:20
+   |
+LL |         a::try_foo(implements_no_traits);
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `DoesNotImplementTrait`
+   |         |
+   |         required by a bound introduced by this call
+   |
+   = help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize<usize>`
+note: required by a bound in `try_foo`
+  --> $DIR/auxiliary/crate_a1.rs:3:24
+   |
+LL | pub fn try_foo(x: impl Bar) {}
+   |                        ^^^ required by this bound in `try_foo`
+
+error[E0277]: the trait bound `ImplementsWrongTraitConditionally<isize>: main::a::Bar` is not satisfied
+  --> $DIR/same-crate-name.rs:45:20
+   |
+LL |         a::try_foo(other_variant_implements_mismatched_trait);
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally<isize>`
+   |         |
+   |         required by a bound introduced by this call
+   |
+help: trait impl with same name found
+  --> $DIR/auxiliary/crate_a2.rs:13:1
+   |
+LL | impl Bar for ImplementsWrongTraitConditionally<isize> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: perhaps two different versions of crate `crate_a2` are being used?
+   = help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize<usize>`
+note: required by a bound in `try_foo`
+  --> $DIR/auxiliary/crate_a1.rs:3:24
+   |
+LL | pub fn try_foo(x: impl Bar) {}
+   |                        ^^^ required by this bound in `try_foo`
+
+error[E0277]: the trait bound `ImplementsTraitForUsize<isize>: main::a::Bar` is not satisfied
+  --> $DIR/same-crate-name.rs:51:20
+   |
+LL |         a::try_foo(other_variant_implements_correct_trait);
+   |         ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize<isize>`
+   |         |
+   |         required by a bound introduced by this call
+   |
+   = help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize<usize>`
+note: required by a bound in `try_foo`
+  --> $DIR/auxiliary/crate_a1.rs:3:24
+   |
+LL | pub fn try_foo(x: impl Bar) {}
+   |                        ^^^ required by this bound in `try_foo`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/bound/sugar.rs b/tests/ui/traits/bound/sugar.rs
new file mode 100644
index 00000000000..65b6f6faa42
--- /dev/null
+++ b/tests/ui/traits/bound/sugar.rs
@@ -0,0 +1,19 @@
+// Tests for "default" bounds inferred for traits with no bounds list.
+
+trait Foo {}
+
+fn a(_x: Box<dyn Foo + Send>) {
+}
+
+fn b(_x: &'static (dyn Foo + 'static)) {
+}
+
+fn c(x: Box<dyn Foo + Sync>) {
+    a(x); //~ ERROR mismatched types
+}
+
+fn d(x: &'static (dyn Foo + Sync)) {
+    b(x);
+}
+
+fn main() {}
diff --git a/tests/ui/traits/bound/sugar.stderr b/tests/ui/traits/bound/sugar.stderr
new file mode 100644
index 00000000000..b67648c7b04
--- /dev/null
+++ b/tests/ui/traits/bound/sugar.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/sugar.rs:12:7
+   |
+LL |     a(x);
+   |     - ^ expected trait `Foo + Send`, found trait `Foo + Sync`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `Box<(dyn Foo + Send + 'static)>`
+              found struct `Box<(dyn Foo + Sync + 'static)>`
+note: function defined here
+  --> $DIR/sugar.rs:5:4
+   |
+LL | fn a(_x: Box<dyn Foo + Send>) {
+   |    ^ -----------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.