diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/traits/trait-upcasting | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/traits/trait-upcasting')
27 files changed, 1401 insertions, 0 deletions
diff --git a/tests/ui/traits/trait-upcasting/basic.rs b/tests/ui/traits/trait-upcasting/basic.rs new file mode 100644 index 000000000..570ec5160 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/basic.rs @@ -0,0 +1,86 @@ +// run-pass + +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs new file mode 100644 index 000000000..eae5cf8d5 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/correct-supertrait-substitution.rs @@ -0,0 +1,38 @@ +// run-pass +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs new file mode 100644 index 000000000..511e41562 --- /dev/null +++ b/tests/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/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr new file mode 100644 index 000000000..15faab16a --- /dev/null +++ b/tests/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/tests/ui/traits/trait-upcasting/diamond.rs b/tests/ui/traits/trait-upcasting/diamond.rs new file mode 100644 index 000000000..a4f81c464 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/diamond.rs @@ -0,0 +1,114 @@ +// run-pass + +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/invalid-upcast.rs b/tests/ui/traits/trait-upcasting/invalid-upcast.rs new file mode 100644 index 000000000..e634bbd5a --- /dev/null +++ b/tests/ui/traits/trait-upcasting/invalid-upcast.rs @@ -0,0 +1,86 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/invalid-upcast.stderr b/tests/ui/traits/trait-upcasting/invalid-upcast.stderr new file mode 100644 index 000000000..3aa21ee3d --- /dev/null +++ b/tests/ui/traits/trait-upcasting/invalid-upcast.stderr @@ -0,0 +1,168 @@ +error[E0308]: mismatched types + --> $DIR/invalid-upcast.rs:53: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:55: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:57: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:60: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:62: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:64: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:66: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:69: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:71: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:73: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:75: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:78: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:80: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:82: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:84: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/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs new file mode 100644 index 000000000..b672963ae --- /dev/null +++ b/tests/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/lifetime.rs b/tests/ui/traits/trait-upcasting/lifetime.rs new file mode 100644 index 000000000..9825158c2 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/lifetime.rs @@ -0,0 +1,94 @@ +// run-pass + +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs new file mode 100644 index 000000000..d62418756 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs @@ -0,0 +1,27 @@ +#![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 { + //~^ ERROR `(dyn B + 'a)` implements `Deref` with supertrait `A` as target + //~| WARN this was previously accepted by the compiler but is being phased out; + + type Target = dyn A; + fn deref(&self) -> &Self::Target { + todo!() + } +} + +fn take_a(_: &dyn A) {} + +fn whoops(b: &dyn B) { + take_a(b) +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr new file mode 100644 index 000000000..4533b1163 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr @@ -0,0 +1,19 @@ +error: `(dyn B + 'a)` implements `Deref` with supertrait `A` as target + --> $DIR/migrate-lint-deny.rs:11:1 + | +LL | impl<'a> Deref for dyn 'a + B { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | type Target = dyn A; + | -------------------- target type is set here + | + = 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> +note: the lint level is defined here + --> $DIR/migrate-lint-deny.rs:1:9 + | +LL | #![deny(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs new file mode 100644 index 000000000..2e53a00a9 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs @@ -0,0 +1,21 @@ +// check-fail +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr new file mode 100644 index 000000000..0ad18be03 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/multiple-occurrence-ambiguousity.rs:20: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/tests/ui/traits/trait-upcasting/replace-vptr.rs b/tests/ui/traits/trait-upcasting/replace-vptr.rs new file mode 100644 index 000000000..9ccfc9306 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/replace-vptr.rs @@ -0,0 +1,48 @@ +// run-pass + +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/struct.rs b/tests/ui/traits/trait-upcasting/struct.rs new file mode 100644 index 000000000..a3e416969 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/struct.rs @@ -0,0 +1,173 @@ +// run-pass + +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/subtrait-method.rs b/tests/ui/traits/trait-upcasting/subtrait-method.rs new file mode 100644 index 000000000..136d15af0 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/subtrait-method.rs @@ -0,0 +1,69 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/subtrait-method.stderr b/tests/ui/traits/trait-upcasting/subtrait-method.stderr new file mode 100644 index 000000000..918159e84 --- /dev/null +++ b/tests/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:55:9 + | +LL | bar.c(); + | ^ help: there is a method 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:27:1 + | +LL | trait Baz: Bar { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:59:9 + | +LL | foo.b(); + | ^ help: there is a method 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:17:1 + | +LL | trait Bar: Foo { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:61:9 + | +LL | foo.c(); + | ^ help: there is a method 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:27:1 + | +LL | trait Baz: Bar { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:65:9 + | +LL | foo.b(); + | ^ help: there is a method 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:17:1 + | +LL | trait Bar: Foo { + | ^^^^^^^^^^^^^^ + +error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope + --> $DIR/subtrait-method.rs:67:9 + | +LL | foo.c(); + | ^ help: there is a method 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:27: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/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs new file mode 100644 index 000000000..6bc9f4a75 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -0,0 +1,26 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr new file mode 100644 index 000000000..fe269d8e9 --- /dev/null +++ b/tests/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:16: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:16: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/tests/ui/traits/trait-upcasting/type-checking-test-2.rs b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs new file mode 100644 index 000000000..36b11dffd --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs @@ -0,0 +1,31 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr new file mode 100644 index 000000000..ef007d5cb --- /dev/null +++ b/tests/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:19: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:19: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:25: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:25: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/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr new file mode 100644 index 000000000..e6cb6a753 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr @@ -0,0 +1,18 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-3.rs:11: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:16: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/tests/ui/traits/trait-upcasting/type-checking-test-3.rs b/tests/ui/traits/trait-upcasting/type-checking-test-3.rs new file mode 100644 index 000000000..b2db3a127 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-3.rs @@ -0,0 +1,20 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr new file mode 100644 index 000000000..e6cb6a753 --- /dev/null +++ b/tests/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:11: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:16: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/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr new file mode 100644 index 000000000..8d506e580 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:15: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:20: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:26: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:31: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:36: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:44: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 + diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs new file mode 100644 index 000000000..f40c48f0d --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -0,0 +1,48 @@ +#![feature(trait_upcasting)] + +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/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr new file mode 100644 index 000000000..8d506e580 --- /dev/null +++ b/tests/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:15: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:20: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:26: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:31: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:36: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:44: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 + |