diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/traits/trait-upcasting | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/traits/trait-upcasting')
27 files changed, 1395 insertions, 0 deletions
diff --git a/src/test/ui/traits/trait-upcasting/basic.rs b/src/test/ui/traits/trait-upcasting/basic.rs new file mode 100644 index 000000000..484a222bc --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/basic.rs @@ -0,0 +1,87 @@ +// run-pass + +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar: Foo { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Baz: Bar { + fn c(&self) -> i32 { + 30 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Baz for i32 { + fn c(&self) -> i32 { + 300 + } +} + +fn main() { + let baz: &dyn Baz = &1; + let _: &dyn std::fmt::Debug = baz; + assert_eq!(*baz, 1); + assert_eq!(baz.a(), 100); + assert_eq!(baz.b(), 200); + assert_eq!(baz.c(), 300); + assert_eq!(baz.z(), 11); + assert_eq!(baz.y(), 12); + assert_eq!(baz.w(), 21); + + let bar: &dyn Bar = baz; + let _: &dyn std::fmt::Debug = bar; + assert_eq!(*bar, 1); + assert_eq!(bar.a(), 100); + assert_eq!(bar.b(), 200); + assert_eq!(bar.z(), 11); + assert_eq!(bar.y(), 12); + assert_eq!(bar.w(), 21); + + let foo: &dyn Foo = baz; + let _: &dyn std::fmt::Debug = foo; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); + + let foo: &dyn Foo = bar; + let _: &dyn std::fmt::Debug = foo; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); +} diff --git a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs new file mode 100644 index 000000000..8d0a9ef0a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs @@ -0,0 +1,39 @@ +// run-pass +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {} +trait Bar<T: Default + ToString> { + fn bar(&self) -> String { + T::default().to_string() + } +} + +struct S1; + +impl Bar<i32> for S1 {} +impl Foo<i32> for S1 {} + +struct S2; +impl Bar<i32> for S2 {} +impl Bar<bool> for S2 {} +impl Foo<bool> for S2 {} + +fn test1(x: &dyn Foo<i32>) { + let s = x as &dyn Bar<i32>; + assert_eq!("0", &s.bar().to_string()); +} + +fn test2(x: &dyn Foo<bool>) { + let p = x as &dyn Bar<i32>; + assert_eq!("0", &p.bar().to_string()); + let q = x as &dyn Bar<bool>; + assert_eq!("false", &q.bar().to_string()); +} + +fn main() { + let s1 = S1; + test1(&s1); + let s2 = S2; + test2(&s2); +} diff --git a/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.rs b/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.rs new file mode 100644 index 000000000..511e41562 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.rs @@ -0,0 +1,13 @@ +trait A: B + A {} +//~^ ERROR cycle detected when computing the super predicates of `A` [E0391] + +trait B {} + +impl A for () {} + +impl B for () {} + +fn main() { + let a: Box<dyn A> = Box::new(()); + let _b: Box<dyn B> = a; +} diff --git a/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr b/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr new file mode 100644 index 000000000..15faab16a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr @@ -0,0 +1,21 @@ +error[E0391]: cycle detected when computing the super predicates of `A` + --> $DIR/cyclic-trait-resolution.rs:1:1 + | +LL | trait A: B + A {} + | ^^^^^^^^^^^^^^ + | +note: ...which requires computing the super traits of `A`... + --> $DIR/cyclic-trait-resolution.rs:1:14 + | +LL | trait A: B + A {} + | ^ + = note: ...which again requires computing the super predicates of `A`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cyclic-trait-resolution.rs:1:1 + | +LL | trait A: B + A {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/traits/trait-upcasting/diamond.rs b/src/test/ui/traits/trait-upcasting/diamond.rs new file mode 100644 index 000000000..e4e23c1a2 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/diamond.rs @@ -0,0 +1,115 @@ +// run-pass + +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar1: Foo { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Bar2: Foo { + fn c(&self) -> i32 { + 30 + } + + fn v(&self) -> i32 { + 31 + } +} + +trait Baz: Bar1 + Bar2 { + fn d(&self) -> i32 { + 40 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar1 for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Bar2 for i32 { + fn c(&self) -> i32 { + 300 + } +} + +impl Baz for i32 { + fn d(&self) -> i32 { + 400 + } +} + +fn main() { + let baz: &dyn Baz = &1; + let _: &dyn std::fmt::Debug = baz; + assert_eq!(*baz, 1); + assert_eq!(baz.a(), 100); + assert_eq!(baz.b(), 200); + assert_eq!(baz.c(), 300); + assert_eq!(baz.d(), 400); + assert_eq!(baz.z(), 11); + assert_eq!(baz.y(), 12); + assert_eq!(baz.w(), 21); + assert_eq!(baz.v(), 31); + + let bar1: &dyn Bar1 = baz; + let _: &dyn std::fmt::Debug = bar1; + assert_eq!(*bar1, 1); + assert_eq!(bar1.a(), 100); + assert_eq!(bar1.b(), 200); + assert_eq!(bar1.z(), 11); + assert_eq!(bar1.y(), 12); + assert_eq!(bar1.w(), 21); + + let bar2: &dyn Bar2 = baz; + let _: &dyn std::fmt::Debug = bar2; + assert_eq!(*bar2, 1); + assert_eq!(bar2.a(), 100); + assert_eq!(bar2.c(), 300); + assert_eq!(bar2.z(), 11); + assert_eq!(bar2.y(), 12); + assert_eq!(bar2.v(), 31); + + let foo: &dyn Foo = baz; + let _: &dyn std::fmt::Debug = foo; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + + let foo: &dyn Foo = bar1; + let _: &dyn std::fmt::Debug = foo; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + + let foo: &dyn Foo = bar2; + let _: &dyn std::fmt::Debug = foo; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); +} diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs new file mode 100644 index 000000000..240224504 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs @@ -0,0 +1,87 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Baz { + fn c(&self) -> i32 { + 30 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Baz for i32 { + fn c(&self) -> i32 { + 300 + } +} + +fn main() { + let baz: &dyn Baz = &1; + let _: &dyn std::fmt::Debug = baz; + //~^ ERROR mismatched types [E0308] + let _: &dyn Send = baz; + //~^ ERROR mismatched types [E0308] + let _: &dyn Sync = baz; + //~^ ERROR mismatched types [E0308] + + let bar: &dyn Bar = baz; + //~^ ERROR mismatched types [E0308] + let _: &dyn std::fmt::Debug = bar; + //~^ ERROR mismatched types [E0308] + let _: &dyn Send = bar; + //~^ ERROR mismatched types [E0308] + let _: &dyn Sync = bar; + //~^ ERROR mismatched types [E0308] + + let foo: &dyn Foo = baz; + //~^ ERROR mismatched types [E0308] + let _: &dyn std::fmt::Debug = foo; + //~^ ERROR mismatched types [E0308] + let _: &dyn Send = foo; + //~^ ERROR mismatched types [E0308] + let _: &dyn Sync = foo; + //~^ ERROR mismatched types [E0308] + + let foo: &dyn Foo = bar; + //~^ ERROR mismatched types [E0308] + let _: &dyn std::fmt::Debug = foo; + //~^ ERROR mismatched types [E0308] + let _: &dyn Send = foo; + //~^ ERROR mismatched types [E0308] + let _: &dyn Sync = foo; + //~^ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr new file mode 100644 index 000000000..b4530ed0c --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr @@ -0,0 +1,168 @@ +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:54:35 + | +LL | let _: &dyn std::fmt::Debug = baz; + | -------------------- ^^^ expected trait `Debug`, found trait `Baz` + | | + | expected due to this + | + = note: expected reference `&dyn Debug` + found reference `&dyn Baz` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:56:24 + | +LL | let _: &dyn Send = baz; + | --------- ^^^ expected trait `Send`, found trait `Baz` + | | + | expected due to this + | + = note: expected reference `&dyn Send` + found reference `&dyn Baz` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:58:24 + | +LL | let _: &dyn Sync = baz; + | --------- ^^^ expected trait `Sync`, found trait `Baz` + | | + | expected due to this + | + = note: expected reference `&dyn Sync` + found reference `&dyn Baz` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:61:25 + | +LL | let bar: &dyn Bar = baz; + | -------- ^^^ expected trait `Bar`, found trait `Baz` + | | + | expected due to this + | + = note: expected reference `&dyn Bar` + found reference `&dyn Baz` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:63:35 + | +LL | let _: &dyn std::fmt::Debug = bar; + | -------------------- ^^^ expected trait `Debug`, found trait `Bar` + | | + | expected due to this + | + = note: expected reference `&dyn Debug` + found reference `&dyn Bar` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:65:24 + | +LL | let _: &dyn Send = bar; + | --------- ^^^ expected trait `Send`, found trait `Bar` + | | + | expected due to this + | + = note: expected reference `&dyn Send` + found reference `&dyn Bar` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:67:24 + | +LL | let _: &dyn Sync = bar; + | --------- ^^^ expected trait `Sync`, found trait `Bar` + | | + | expected due to this + | + = note: expected reference `&dyn Sync` + found reference `&dyn Bar` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:70:25 + | +LL | let foo: &dyn Foo = baz; + | -------- ^^^ expected trait `Foo`, found trait `Baz` + | | + | expected due to this + | + = note: expected reference `&dyn Foo` + found reference `&dyn Baz` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:72:35 + | +LL | let _: &dyn std::fmt::Debug = foo; + | -------------------- ^^^ expected trait `Debug`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Debug` + found reference `&dyn Foo` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:74:24 + | +LL | let _: &dyn Send = foo; + | --------- ^^^ expected trait `Send`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Send` + found reference `&dyn Foo` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:76:24 + | +LL | let _: &dyn Sync = foo; + | --------- ^^^ expected trait `Sync`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Sync` + found reference `&dyn Foo` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:79:25 + | +LL | let foo: &dyn Foo = bar; + | -------- ^^^ expected trait `Foo`, found trait `Bar` + | | + | expected due to this + | + = note: expected reference `&dyn Foo` + found reference `&dyn Bar` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:81:35 + | +LL | let _: &dyn std::fmt::Debug = foo; + | -------------------- ^^^ expected trait `Debug`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Debug` + found reference `&dyn Foo` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:83:24 + | +LL | let _: &dyn Send = foo; + | --------- ^^^ expected trait `Send`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Send` + found reference `&dyn Foo` + +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:85:24 + | +LL | let _: &dyn Sync = foo; + | --------- ^^^ expected trait `Sync`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Sync` + found reference `&dyn Foo` + +error: aborting due to 15 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs new file mode 100644 index 000000000..6d8800254 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +struct Test { + func: Box<dyn FnMut() + 'static>, +} + +fn main() { + let closure: Box<dyn Fn() + 'static> = Box::new(|| ()); + let mut test = Box::new(Test { func: closure }); + (test.func)(); +} diff --git a/src/test/ui/traits/trait-upcasting/lifetime.rs b/src/test/ui/traits/trait-upcasting/lifetime.rs new file mode 100644 index 000000000..f029a6f08 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/lifetime.rs @@ -0,0 +1,95 @@ +// run-pass + +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar: Foo { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Baz: Bar { + fn c(&self) -> i32 { + 30 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Baz for i32 { + fn c(&self) -> i32 { + 300 + } +} + +// Note: upcast lifetime means a shorter lifetime. +fn upcast_baz<'a: 'b, 'b, T>(v: Box<dyn Baz + 'a>, _l: &'b T) -> Box<dyn Baz + 'b> { + v +} +fn upcast_bar<'a: 'b, 'b, T>(v: Box<dyn Bar + 'a>, _l: &'b T) -> Box<dyn Bar + 'b> { + v +} +fn upcast_foo<'a: 'b, 'b, T>(v: Box<dyn Foo + 'a>, _l: &'b T) -> Box<dyn Foo + 'b> { + v +} + +fn main() { + let v = Box::new(1); + let l = &(); // dummy lifetime (shorter than `baz`) + + let baz: Box<dyn Baz> = v.clone(); + let u = upcast_baz(baz, &l); + assert_eq!(*u, 1); + assert_eq!(u.a(), 100); + assert_eq!(u.b(), 200); + assert_eq!(u.c(), 300); + + let baz: Box<dyn Baz> = v.clone(); + let bar: Box<dyn Bar> = baz; + let u = upcast_bar(bar, &l); + assert_eq!(*u, 1); + assert_eq!(u.a(), 100); + assert_eq!(u.b(), 200); + + let baz: Box<dyn Baz> = v.clone(); + let foo: Box<dyn Foo> = baz; + let u = upcast_foo(foo, &l); + assert_eq!(*u, 1); + assert_eq!(u.a(), 100); + + let baz: Box<dyn Baz> = v.clone(); + let bar: Box<dyn Bar> = baz; + let foo: Box<dyn Foo> = bar; + let u = upcast_foo(foo, &l); + assert_eq!(*u, 1); + assert_eq!(u.a(), 100); +} diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs new file mode 100644 index 000000000..c67251018 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs @@ -0,0 +1,25 @@ +#![deny(deref_into_dyn_supertrait)] + +extern crate core; + +use core::ops::Deref; + +// issue 89190 +trait A {} +trait B: A {} +impl<'a> Deref for dyn 'a + B { + type Target = dyn A; + fn deref(&self) -> &Self::Target { + todo!() + } +} + +fn take_a(_: &dyn A) {} + +fn whoops(b: &dyn B) { + take_a(b) + //~^ ERROR `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output + //~^^ WARN this was previously accepted by the compiler but is being phased out; +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr new file mode 100644 index 000000000..35af9112a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr @@ -0,0 +1,16 @@ +error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output + --> $DIR/migrate-lint-deny.rs:20:12 + | +LL | take_a(b) + | ^ + | +note: the lint level is defined here + --> $DIR/migrate-lint-deny.rs:1:9 + | +LL | #![deny(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> + +error: aborting due to previous error + diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs new file mode 100644 index 000000000..6986ad621 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs @@ -0,0 +1,22 @@ +// check-fail +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Bar<T> { + fn bar(&self, _: T) {} +} + +trait Foo : Bar<i32> + Bar<u32> { + fn foo(&self, _: ()) {} +} + +struct S; + +impl Bar<i32> for S {} +impl Bar<u32> for S {} +impl Foo for S {} + +fn main() { + let s: &dyn Foo = &S; + let t: &dyn Bar<_> = s; //~ ERROR mismatched types +} diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr new file mode 100644 index 000000000..e9670ad7d --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/multiple-occurence-ambiguousity.rs:21:26 + | +LL | let t: &dyn Bar<_> = s; + | ----------- ^ expected trait `Bar`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Bar<_>` + found reference `&dyn Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/trait-upcasting/replace-vptr.rs b/src/test/ui/traits/trait-upcasting/replace-vptr.rs new file mode 100644 index 000000000..1164e4361 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/replace-vptr.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait A { + fn foo_a(&self); +} + +trait B { + fn foo_b(&self); +} + +trait C: A + B { + fn foo_c(&self); +} + +struct S(i32); + +impl A for S { + fn foo_a(&self) { + unreachable!(); + } +} + +impl B for S { + fn foo_b(&self) { + assert_eq!(42, self.0); + } +} + +impl C for S { + fn foo_c(&self) { + unreachable!(); + } +} + +fn invoke_inner(b: &dyn B) { + b.foo_b(); +} + +fn invoke_outer(c: &dyn C) { + invoke_inner(c); +} + +fn main() { + let s = S(42); + invoke_outer(&s); +} diff --git a/src/test/ui/traits/trait-upcasting/struct.rs b/src/test/ui/traits/trait-upcasting/struct.rs new file mode 100644 index 000000000..0f3cb285b --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/struct.rs @@ -0,0 +1,174 @@ +// run-pass + +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +use std::rc::Rc; +use std::sync::Arc; + +trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar: Foo { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Baz: Bar { + fn c(&self) -> i32 { + 30 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Baz for i32 { + fn c(&self) -> i32 { + 300 + } +} + +fn test_box() { + let v = Box::new(1); + + let baz: Box<dyn Baz> = v.clone(); + assert_eq!(*baz, 1); + assert_eq!(baz.a(), 100); + assert_eq!(baz.b(), 200); + assert_eq!(baz.c(), 300); + assert_eq!(baz.z(), 11); + assert_eq!(baz.y(), 12); + assert_eq!(baz.w(), 21); + + let baz: Box<dyn Baz> = v.clone(); + let bar: Box<dyn Bar> = baz; + assert_eq!(*bar, 1); + assert_eq!(bar.a(), 100); + assert_eq!(bar.b(), 200); + assert_eq!(bar.z(), 11); + assert_eq!(bar.y(), 12); + assert_eq!(bar.w(), 21); + + let baz: Box<dyn Baz> = v.clone(); + let foo: Box<dyn Foo> = baz; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); + + let baz: Box<dyn Baz> = v.clone(); + let bar: Box<dyn Bar> = baz; + let foo: Box<dyn Foo> = bar; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); +} + +fn test_rc() { + let v = Rc::new(1); + + let baz: Rc<dyn Baz> = v.clone(); + assert_eq!(*baz, 1); + assert_eq!(baz.a(), 100); + assert_eq!(baz.b(), 200); + assert_eq!(baz.c(), 300); + assert_eq!(baz.z(), 11); + assert_eq!(baz.y(), 12); + assert_eq!(baz.w(), 21); + + let baz: Rc<dyn Baz> = v.clone(); + let bar: Rc<dyn Bar> = baz; + assert_eq!(*bar, 1); + assert_eq!(bar.a(), 100); + assert_eq!(bar.b(), 200); + assert_eq!(bar.z(), 11); + assert_eq!(bar.y(), 12); + assert_eq!(bar.w(), 21); + + let baz: Rc<dyn Baz> = v.clone(); + let foo: Rc<dyn Foo> = baz; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); + + let baz: Rc<dyn Baz> = v.clone(); + let bar: Rc<dyn Bar> = baz; + let foo: Rc<dyn Foo> = bar; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); +} + +fn test_arc() { + let v = Arc::new(1); + + let baz: Arc<dyn Baz> = v.clone(); + assert_eq!(*baz, 1); + assert_eq!(baz.a(), 100); + assert_eq!(baz.b(), 200); + assert_eq!(baz.c(), 300); + assert_eq!(baz.z(), 11); + assert_eq!(baz.y(), 12); + assert_eq!(baz.w(), 21); + + let baz: Arc<dyn Baz> = v.clone(); + let bar: Arc<dyn Bar> = baz; + assert_eq!(*bar, 1); + assert_eq!(bar.a(), 100); + assert_eq!(bar.b(), 200); + assert_eq!(bar.z(), 11); + assert_eq!(bar.y(), 12); + assert_eq!(bar.w(), 21); + + let baz: Arc<dyn Baz> = v.clone(); + let foo: Arc<dyn Foo> = baz; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); + + let baz: Arc<dyn Baz> = v.clone(); + let bar: Arc<dyn Bar> = baz; + let foo: Arc<dyn Foo> = bar; + assert_eq!(*foo, 1); + assert_eq!(foo.a(), 100); + assert_eq!(foo.z(), 11); + assert_eq!(foo.y(), 12); +} + +fn main() { + test_box(); + test_rc(); + test_arc(); +} diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.rs b/src/test/ui/traits/trait-upcasting/subtrait-method.rs new file mode 100644 index 000000000..3508e1528 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/subtrait-method.rs @@ -0,0 +1,70 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { + fn a(&self) -> i32 { + 10 + } + + fn z(&self) -> i32 { + 11 + } + + fn y(&self) -> i32 { + 12 + } +} + +trait Bar: Foo { + fn b(&self) -> i32 { + 20 + } + + fn w(&self) -> i32 { + 21 + } +} + +trait Baz: Bar { + fn c(&self) -> i32 { + 30 + } +} + +impl Foo for i32 { + fn a(&self) -> i32 { + 100 + } +} + +impl Bar for i32 { + fn b(&self) -> i32 { + 200 + } +} + +impl Baz for i32 { + fn c(&self) -> i32 { + 300 + } +} + +fn main() { + let baz: &dyn Baz = &1; + + let bar: &dyn Bar = baz; + bar.c(); + //~^ ERROR no method named `c` found for reference `&dyn Bar` in the current scope [E0599] + + let foo: &dyn Foo = baz; + foo.b(); + //~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599] + foo.c(); + //~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599] + + let foo: &dyn Foo = bar; + foo.b(); + //~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599] + foo.c(); + //~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599] +} diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr new file mode 100644 index 000000000..8c6901180 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr @@ -0,0 +1,68 @@ +error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope + --> $DIR/subtrait-method.rs:56:9 + | +LL | bar.c(); + | ^ help: there is an associated function with a similar name: `a` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Baz` defines an item `c`, perhaps you need to implement it + --> $DIR/subtrait-method.rs:28:1 + | +LL | trait Baz: Bar { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:60:9 + | +LL | foo.b(); + | ^ help: there is an associated function with a similar name: `a` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bar` defines an item `b`, perhaps you need to implement it + --> $DIR/subtrait-method.rs:18:1 + | +LL | trait Bar: Foo { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:62:9 + | +LL | foo.c(); + | ^ help: there is an associated function with a similar name: `a` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Baz` defines an item `c`, perhaps you need to implement it + --> $DIR/subtrait-method.rs:28:1 + | +LL | trait Baz: Bar { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:66:9 + | +LL | foo.b(); + | ^ help: there is an associated function with a similar name: `a` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bar` defines an item `b`, perhaps you need to implement it + --> $DIR/subtrait-method.rs:18:1 + | +LL | trait Bar: Foo { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:68:9 + | +LL | foo.c(); + | ^ help: there is an associated function with a similar name: `a` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Baz` defines an item `c`, perhaps you need to implement it + --> $DIR/subtrait-method.rs:28:1 + | +LL | trait Baz: Bar { + | ^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs new file mode 100644 index 000000000..79ddedd41 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -0,0 +1,27 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: Bar<i32> + Bar<u32> {} +trait Bar<T> { + fn bar(&self) -> Option<T> { + None + } +} + +fn test_specific(x: &dyn Foo) { + let _ = x as &dyn Bar<i32>; // OK + let _ = x as &dyn Bar<u32>; // OK +} + +fn test_unknown_version(x: &dyn Foo) { + let _ = x as &dyn Bar<_>; // Ambiguous + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied +} + +fn test_infer_version(x: &dyn Foo) { + let a = x as &dyn Bar<_>; // OK + let _: Option<u32> = a.bar(); +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr new file mode 100644 index 000000000..398537211 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr @@ -0,0 +1,23 @@ +error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` + --> $DIR/type-checking-test-1.rs:17:13 + | +LL | let _ = x as &dyn Bar<_>; // Ambiguous + | ^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<_>; // Ambiguous + | + + +error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied + --> $DIR/type-checking-test-1.rs:17:13 + | +LL | let _ = x as &dyn Bar<_>; // Ambiguous + | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` + | + = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0605. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs new file mode 100644 index 000000000..32754c538 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs @@ -0,0 +1,32 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<T>: Bar<i32> + Bar<T> {} +trait Bar<T> { + fn bar(&self) -> Option<T> { + None + } +} + +fn test_specific(x: &dyn Foo<i32>) { + let _ = x as &dyn Bar<i32>; // OK +} + +fn test_specific2(x: &dyn Foo<u32>) { + let _ = x as &dyn Bar<i32>; // OK +} + +fn test_specific3(x: &dyn Foo<i32>) { + let _ = x as &dyn Bar<u32>; // Error + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied +} + +fn test_infer_arg(x: &dyn Foo<u32>) { + let a = x as &dyn Bar<_>; // Ambiguous + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied + let _ = a.bar(); +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr new file mode 100644 index 000000000..93c71f54e --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -0,0 +1,42 @@ +error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>` + --> $DIR/type-checking-test-2.rs:20:13 + | +LL | let _ = x as &dyn Bar<u32>; // Error + | ^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<u32>; // Error + | + + +error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied + --> $DIR/type-checking-test-2.rs:20:13 + | +LL | let _ = x as &dyn Bar<u32>; // Error + | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>` + | + = note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>` + +error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>` + --> $DIR/type-checking-test-2.rs:26:13 + | +LL | let a = x as &dyn Bar<_>; // Ambiguous + | ^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let a = &x as &dyn Bar<_>; // Ambiguous + | + + +error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied + --> $DIR/type-checking-test-2.rs:26:13 + | +LL | let a = x as &dyn Bar<_>; // Ambiguous + | ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>` + | + = note: required for the cast from `&dyn Foo<u32>` to the object type `dyn Bar<_>` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0605. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr new file mode 100644 index 000000000..e48ba709a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-3.rs:13:13 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'a>; // Error + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-3.rs:18:13 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'static>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs new file mode 100644 index 000000000..b3aa2279a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs @@ -0,0 +1,21 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<'a>: Bar<'a> {} +trait Bar<'a> {} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static>; +} + +fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'a>; // Error + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'static>; // Error + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr new file mode 100644 index 000000000..5ad151b50 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr @@ -0,0 +1,18 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-3.rs:12:13 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'a>; // Error + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-3.rs:17:13 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'static>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr new file mode 100644 index 000000000..a3411f40a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr @@ -0,0 +1,33 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:17:13 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'static, 'a>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:22:13 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'a, 'static>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:29:5 + | +LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +... +LL | y.get_b() // ERROR + | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs new file mode 100644 index 000000000..70ccc87fc --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -0,0 +1,49 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<'a>: Bar<'a, 'a> {} +trait Bar<'a, 'b> { + fn get_b(&self) -> Option<&'a u32> { + None + } +} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static, 'static>; +} + +fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'static, 'a>; // Error + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'a, 'static>; // Error + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + let y = x as &dyn Bar<'_, '_>; + y.get_b() // ERROR + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + <_ as Bar>::get_b(x) // ERROR + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + <_ as Bar<'_, '_>>::get_b(x) // ERROR + //~^ ERROR lifetime may not live long enough +} + +fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + let y = x as &dyn Bar<'_, '_>; + y.get_b(); // ERROR + let z = y; + z.get_b() // ERROR + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr new file mode 100644 index 000000000..436129d0b --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:16:13 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'static, 'a>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:21:13 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | -- lifetime `'a` defined here +LL | let _ = x as &dyn Bar<'a, 'static>; // Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:27:5 + | +LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +LL | let y = x as &dyn Bar<'_, '_>; +LL | y.get_b() // ERROR + | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:32:5 + | +LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +LL | <_ as Bar>::get_b(x) // ERROR + | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:37:5 + | +LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:45:5 + | +LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +... +LL | z.get_b() // ERROR + | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 6 previous errors + |