about summary refs log tree commit diff
path: root/src/test/ui/impl-trait
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-05-01 21:15:01 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2019-05-02 18:56:56 +0100
commitd72f4de659341c281021ddd42c15705a63370bda (patch)
tree6f0afbbffb2fcf277fdee13b489d59b8e68d2608 /src/test/ui/impl-trait
parent6cc24f26036b28fb3366de86efe3da6c4464057a (diff)
downloadrust-d72f4de659341c281021ddd42c15705a63370bda.tar.gz
rust-d72f4de659341c281021ddd42c15705a63370bda.zip
Constrain all regions in the concrete type for an opaque type
Diffstat (limited to 'src/test/ui/impl-trait')
-rw-r--r--src/test/ui/impl-trait/can-return-unconstrained-closure.rs19
-rw-r--r--src/test/ui/impl-trait/issue-55608-captures-empty-region.rs4
-rw-r--r--src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr11
-rw-r--r--src/test/ui/impl-trait/issue-57464-unexpected-regions.rs22
4 files changed, 43 insertions, 13 deletions
diff --git a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs
new file mode 100644
index 00000000000..a982b176ecd
--- /dev/null
+++ b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs
@@ -0,0 +1,19 @@
+// Test that we are special casing "outlives" for opaque types.
+//
+// The return type of a closure is not required to outlive the closure. As such
+// the following code would not compile if we used a standard outlives check
+// when checking the return type, because the return type of the closure would
+// be `&ReEmpty i32`, and we don't allow `ReEmpty` to occur in the concrete
+// type used for an opaque type.
+//
+// However, opaque types are special cased to include check all regions in the
+// concrete type against the bound, which forces the return type to be
+// `&'static i32` here.
+
+// compile-pass
+
+fn make_identity() -> impl Sized {
+    |x: &'static i32| x
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs
index 7ebc348996f..50646edd61a 100644
--- a/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs
+++ b/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs
@@ -1,9 +1,9 @@
 // This used to ICE because it creates an `impl Trait` that captures a
 // hidden empty region.
 
-#![feature(conservative_impl_trait)]
+// compile-pass
 
-fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+fn server() -> impl FilterBase2 {
     segment2(|| { loop { } }).map2(|| "")
 }
 
diff --git a/src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr b/src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr
deleted file mode 100644
index 6311a7f0067..00000000000
--- a/src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/issue-55608-captures-empty-region.rs:6:16
-   |
-LL | fn server() -> impl FilterBase2 {
-   |                ^^^^^^^^^^^^^^^^
-   |
-   = note: hidden type `Map2<[closure@$DIR/issue-55608-captures-empty-region.rs:7:36: 7:41]>` captures an empty lifetime
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
new file mode 100644
index 00000000000..29e271c68ec
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
@@ -0,0 +1,22 @@
+// Regression test for issue 57464.
+//
+// Closure are (surprisingly) allowed to outlive their signature. As such it
+// was possible to end up with `ReScope`s appearing in the concrete type of an
+// opaque type. As all regions are now required to outlive the bound in an
+// opaque type we avoid the issue here.
+
+// compile-pass
+
+struct A<F>(F);
+
+unsafe impl <'a, 'b, F: Fn(&'a i32) -> &'b i32> Send for A<F> {}
+
+fn wrapped_closure() -> impl Sized {
+    let f = |x| x;
+    f(&0);
+    A(f)
+}
+
+fn main() {
+    let x: Box<dyn Send> = Box::new(wrapped_closure());
+}