summaryrefslogtreecommitdiffstats
path: root/tests/ui/traits/bound
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/traits/bound
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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 000000000..f9a934764
--- /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 000000000..ce9ab2d81
--- /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 000000000..6aa010258
--- /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 000000000..d6057db5e
--- /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 000000000..7e9592eee
--- /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 000000000..8c8a7eb7d
--- /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 000000000..18382bb59
--- /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 000000000..de6c2afa2
--- /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 000000000..a1492c0b9
--- /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 000000000..868b33407
--- /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 000000000..daf18c670
--- /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 000000000..36b08a7d3
--- /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 000000000..8633e9d7a
--- /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 000000000..2de35dc7f
--- /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 000000000..6a6fcf530
--- /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 000000000..61237a63e
--- /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 000000000..d37949952
--- /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 000000000..8a4374226
--- /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 000000000..60ba343bb
--- /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 000000000..20bbe69c0
--- /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 000000000..4dc4fecc9
--- /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 000000000..df3f8b8a5
--- /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 000000000..fda734e85
--- /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 000000000..94316d240
--- /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 000000000..5064b60bf
--- /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 000000000..5ef35b513
--- /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 000000000..3fb5decb7
--- /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 000000000..024084fa7
--- /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 000000000..fe05b8634
--- /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 000000000..0023ff654
--- /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 000000000..8d646a414
--- /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 000000000..f66cad77f
--- /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 000000000..65b6f6faa
--- /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 000000000..b67648c7b
--- /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`.