diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-11-29 22:43:15 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-29 22:43:15 +0100 |
| commit | 3617adfaee29c698713f1c4b6b62d9438c985d46 (patch) | |
| tree | 340c6440851415df24b458dac7e078726e1c0b97 /src/test | |
| parent | e0098a5cc3a87d857e597af824d0ce1ed1ad85e0 (diff) | |
| parent | ca57832db636fedeeb529a1cc1feab0befef2ab0 (diff) | |
| download | rust-3617adfaee29c698713f1c4b6b62d9438c985d46.tar.gz rust-3617adfaee29c698713f1c4b6b62d9438c985d46.zip | |
Rollup merge of #103876 - oli-obk:tait_implications, r=lcnr
type alias impl trait: add tests showing that hidden type only outlives lifetimes that occur in bounds fixes #103642 https://github.com/rust-lang/rust/pull/102417 only made sure that hidden types cannot outlive lifetimes other than the ones mentioned on bounds, but didn't allow us to actually infer anything from that. cc `@aliemjay`
Diffstat (limited to 'src/test')
4 files changed, 117 insertions, 0 deletions
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs new file mode 100644 index 00000000000..ee9bce15d34 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call() -> Self::Output; +} + +impl<'a> Callable for &'a () { + type Output = impl Sized; + fn call() -> Self::Output {} +} + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn want_static<T: 'static>(_: T) {} + +fn test2<'a>() { + want_static(<&'a () as Callable>::call()); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs new file mode 100644 index 00000000000..ae21a9134a4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs @@ -0,0 +1,38 @@ +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call(x: Self) -> Self::Output; +} + +trait PlusOne { + fn plus_one(&mut self); +} + +impl<'a> PlusOne for &'a mut i32 { + fn plus_one(&mut self) { + **self += 1; + } +} + +impl<T: PlusOne> Callable for T { + type Output = impl PlusOne; + fn call(t: T) -> Self::Output { t } +} + +fn test<'a>(y: &'a mut i32) -> impl PlusOne { + <&'a mut i32 as Callable>::call(y) + //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds +} + +fn main() { + let mut z = 42; + let mut thing = test(&mut z); + let mut thing2 = test(&mut z); + thing.plus_one(); + assert_eq!(z, 43); + thing2.plus_one(); + assert_eq!(z, 44); + thing.plus_one(); + assert_eq!(z, 45); +} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr new file mode 100644 index 00000000000..0ed8a703b6d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr @@ -0,0 +1,16 @@ +error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds + --> $DIR/imply_bounds_from_bounds_param.rs:24:5 + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { + | -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here +LL | <&'a mut i32 as Callable>::call(y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/type-alias-impl-trait/self_implication.rs b/src/test/ui/type-alias-impl-trait/self_implication.rs new file mode 100644 index 00000000000..4e805ee308f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self_implication.rs @@ -0,0 +1,38 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +fn foo() { + struct Foo<'a> { + x: &'a mut u8, + } + impl<'a> Foo<'a> { + fn foo(&self) -> impl Sized {} + } + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn bar() { + struct Foo<'a> { + x: &'a mut u8, + } + + // desugared + type FooX<'a> = impl Sized; + impl<'a> Foo<'a> { + fn foo(&self) -> FooX<'a> {} + } + + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn main() {} |
