about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-21 20:16:36 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-21 20:16:36 +0000
commitca57832db636fedeeb529a1cc1feab0befef2ab0 (patch)
treee14e400a20af862b72e6565b3e9c1f6f5e3eeb1c /src/test
parent7fe6f36224e92db6fbde952e0b7e50863161f6ee (diff)
Add more regression tests
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() {}