about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-28 18:05:16 +0000
committerbors <bors@rust-lang.org>2023-08-28 18:05:16 +0000
commit93dd62024113acb782812189d01e8e239da150e7 (patch)
tree6b5165d61e81d17a754ba5da1fb334a38315a3b8 /tests
parent9f48a8544799c65a597302886d5143456fcb340f (diff)
parentf8e0dcbf5627d3e1a70a4d1d6bd1101d5b24f1e3 (diff)
downloadrust-93dd62024113acb782812189d01e8e239da150e7.tar.gz
rust-93dd62024113acb782812189d01e8e239da150e7.zip
Auto merge of #114489 - compiler-errors:rpitit-capture-all, r=oli-obk
Make RPITITs capture all in-scope lifetimes

Much like #114616, this implements the lang team decision from this T-lang meeting on [opaque captures strategy moving forward](https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ?view). This will be RFC'd soon, but given that RPITITs are a nightly feature, this shouldn't necessarily be blocked on that.

We unconditionally capture all lifetimes in RPITITs -- impl is not as simple as #114616, since we still need to duplicate RPIT lifetimes to make sure we reify any late-bound lifetimes in scope.

Closes #112194
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr14
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.rs38
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.stderr61
-rw-r--r--tests/ui/impl-trait/in-trait/variance.rs20
-rw-r--r--tests/ui/impl-trait/in-trait/variance.stderr26
-rw-r--r--tests/ui/impl-trait/variance.rs16
-rw-r--r--tests/ui/impl-trait/variance.stderr26
9 files changed, 149 insertions, 70 deletions
diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs
index dd35b9a2d8a..9a231e59b09 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.rs
+++ b/tests/ui/impl-trait/in-trait/object-safety.rs
@@ -19,4 +19,5 @@ fn main() {
     //~| ERROR the trait `Foo` cannot be made into an object
     let s = i.baz();
     //~^ ERROR the trait `Foo` cannot be made into an object
+    //~| ERROR the trait `Foo` cannot be made into an object
 }
diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr
index 4a3b3b11465..0170dc5d0fc 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.stderr
@@ -14,6 +14,21 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:20:15
+   |
+LL |     let s = i.baz();
+   |               ^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:7:22
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> impl Debug;
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+   = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety.rs:20:13
    |
 LL |     let s = i.baz();
@@ -44,6 +59,6 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
    = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
new file mode 100644
index 00000000000..186580f5756
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
@@ -0,0 +1,14 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/signature-mismatch.rs:77:10
+   |
+LL |         &'a self,
+   |         -------- this parameter and the return type are declared with different lifetimes...
+...
+LL |     ) -> impl Future<Output = Vec<u8>> {
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          |
+   |          ...but data from `buff` is returned here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0623`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
index 1d63a6f3ce2..c84a3b8f46b 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
@@ -1,4 +1,6 @@
 // edition:2021
+// revisions: success failure
+//[success] check-pass
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
@@ -11,16 +13,25 @@ impl<T> Captures<'_> for T {}
 trait Captures2<'a, 'b> {}
 impl<T> Captures2<'_, '_> for T {}
 
-pub trait AsyncTrait {
+trait AsyncTrait {
+    #[cfg(success)]
     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
+
+    #[cfg(success)]
     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
+
+    #[cfg(success)]
     fn async_fn_multiple<'a>(&'a self, buff: &[u8])
-        -> impl Future<Output = Vec<u8>> + Captures<'a>;
+    -> impl Future<Output = Vec<u8>> + Captures<'a>;
+
+    #[cfg(failure)]
     fn async_fn_reduce_outlive<'a, T>(
         &'a self,
         buff: &[u8],
         t: T,
     ) -> impl Future<Output = Vec<u8>> + 'a;
+
+    #[cfg(success)]
     fn async_fn_reduce<'a, T>(
         &'a self,
         buff: &[u8],
@@ -31,38 +42,49 @@ pub trait AsyncTrait {
 pub struct Struct;
 
 impl AsyncTrait for Struct {
+    // Does not capture more lifetimes that trait def'n, since trait def'n
+    // implicitly captures all in-scope lifetimes.
+    #[cfg(success)]
     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-        //~^ ERROR return type captures more lifetimes than trait definition
         async move { buff.to_vec() }
     }
 
+    // Does not capture more lifetimes that trait def'n, since trait def'n
+    // implicitly captures all in-scope lifetimes.
+    #[cfg(success)]
     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-        //~^ ERROR return type captures more lifetimes than trait definition
         async move { buff.to_vec() }
     }
 
+    // Does not capture more lifetimes that trait def'n, since trait def'n
+    // implicitly captures all in-scope lifetimes.
+    #[cfg(success)]
     fn async_fn_multiple<'a, 'b>(
         &'a self,
         buff: &'b [u8],
     ) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
-        //~^ ERROR return type captures more lifetimes than trait definition
         async move { buff.to_vec() }
     }
 
+    // This error message is awkward, but `impl Future<Output = Vec<u8>>`
+    // cannot outlive `'a` (from the trait signature) because it captures
+    // both `T` and `'b`.
+    #[cfg(failure)]
     fn async_fn_reduce_outlive<'a, 'b, T>(
         &'a self,
         buff: &'b [u8],
         t: T,
     ) -> impl Future<Output = Vec<u8>> {
-        //~^ ERROR the parameter type `T` may not live long enough
+        //[failure]~^ ERROR lifetime mismatch
         async move {
             let _t = t;
             vec![]
         }
     }
 
-    // OK: We remove the `Captures<'a>`, providing a guarantee that we don't capture `'a`,
-    // but we still fulfill the `Captures<'a>` trait bound.
+    // Does not capture fewer lifetimes that trait def'n (not that it matters),
+    // since impl also captures all in-scope lifetimes.
+    #[cfg(success)]
     fn async_fn_reduce<'a, 'b, T>(&'a self, buff: &'b [u8], t: T) -> impl Future<Output = Vec<u8>> {
         async move {
             let _t = t;
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.stderr
deleted file mode 100644
index 616f1ac35a9..00000000000
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:34:47
-   |
-LL |     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                 -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:15:40
-   |
-LL |     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:39:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                       -- this lifetime was captured     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:16:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:47:10
-   |
-LL |     fn async_fn_multiple<'a, 'b>(
-   |                              -- this lifetime was captured
-...
-LL |     ) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:18:12
-   |
-LL |         -> impl Future<Output = Vec<u8>> + Captures<'a>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + Captures2<'a, 'b>`
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/signature-mismatch.rs:56:10
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future<Output = Vec<u8>>` will meet its required lifetime bounds...
-   |
-note: ...that is required by this bound
-  --> $DIR/signature-mismatch.rs:23:42
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> + 'a;
-   |                                          ^^
-help: consider adding an explicit lifetime bound...
-   |
-LL |     fn async_fn_reduce_outlive<'a, 'b, T: 'a>(
-   |                                         ++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs
new file mode 100644
index 00000000000..f8e4ab88c19
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.rs
@@ -0,0 +1,20 @@
+#![feature(rustc_attrs, return_position_impl_trait_in_trait)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+trait Foo<'i> {
+    fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+    //~^ [o, *, *, o, o]
+    // Self, 'i, 'a, 'i_duplicated, 'a_duplicated
+
+    fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
+
+    fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
+
+    fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/variance.stderr b/tests/ui/impl-trait/in-trait/variance.stderr
new file mode 100644
index 00000000000..8cae5a92f0d
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.stderr
@@ -0,0 +1,26 @@
+error: [o, *, *, o, o]
+  --> $DIR/variance.rs:9:44
+   |
+LL |     fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+   |                                            ^^^^^^^^^^
+
+error: [o, *, *, o, o]
+  --> $DIR/variance.rs:13:44
+   |
+LL |     fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: [o, *, o, o]
+  --> $DIR/variance.rs:15:48
+   |
+LL |     fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                                ^^^^^^^^^^
+
+error: [o, *, o, o]
+  --> $DIR/variance.rs:17:48
+   |
+LL |     fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs
new file mode 100644
index 00000000000..d6212f8f393
--- /dev/null
+++ b/tests/ui/impl-trait/variance.rs
@@ -0,0 +1,16 @@
+#![feature(rustc_attrs)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+fn not_captured_early<'a: 'a>() -> impl Sized {} //~ [*]
+
+fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
+
+fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //~ []
+
+fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]
+
+fn main() {}
diff --git a/tests/ui/impl-trait/variance.stderr b/tests/ui/impl-trait/variance.stderr
new file mode 100644
index 00000000000..64473675410
--- /dev/null
+++ b/tests/ui/impl-trait/variance.stderr
@@ -0,0 +1,26 @@
+error: [*]
+  --> $DIR/variance.rs:8:36
+   |
+LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
+   |                                    ^^^^^^^^^^
+
+error: [*, o]
+  --> $DIR/variance.rs:10:32
+   |
+LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: []
+  --> $DIR/variance.rs:12:40
+   |
+LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                        ^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:14:36
+   |
+LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+