about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-11-29 22:43:15 +0100
committerGitHub <noreply@github.com>2022-11-29 22:43:15 +0100
commit3617adfaee29c698713f1c4b6b62d9438c985d46 (patch)
tree340c6440851415df24b458dac7e078726e1c0b97 /src/test
parente0098a5cc3a87d857e597af824d0ce1ed1ad85e0 (diff)
parentca57832db636fedeeb529a1cc1feab0befef2ab0 (diff)
downloadrust-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')
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs38
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/self_implication.rs38
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() {}