about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-05-13 21:57:20 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2019-05-13 21:57:20 +0100
commit36fd00e81cd4af2c83839f0c0b96dc20663710c5 (patch)
treec7f99803eec4de638df8bb7804b9272ea172ef71 /src
parenta9ec99f4201ec33026a468ef1289f98a95b4d71a (diff)
downloadrust-36fd00e81cd4af2c83839f0c0b96dc20663710c5.tar.gz
rust-36fd00e81cd4af2c83839f0c0b96dc20663710c5.zip
Allow late bound regions in existential types
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/writeback.rs7
-rw-r--r--src/test/ui/existential_types/issue-60655-latebound-regions.rs30
2 files changed, 35 insertions, 2 deletions
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index ecb8e09ec24..13baf667808 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -466,6 +466,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
             let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
             let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id);
 
+            debug_assert!(!instantiated_ty.has_escaping_bound_vars());
+
             let generics = self.tcx().generics_of(def_id);
 
             let definition_ty = if generics.parent.is_some() {
@@ -524,8 +526,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                     },
                     lt_op: |region| {
                         match region {
-                            // ignore static regions
-                            ty::ReStatic => region,
+                            // Skip static and bound regions: they don't
+                            // require substitution.
+                            ty::ReStatic | ty::ReLateBound(..) => region,
                             _ => {
                                 trace!("checking {:?}", region);
                                 for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) {
diff --git a/src/test/ui/existential_types/issue-60655-latebound-regions.rs b/src/test/ui/existential_types/issue-60655-latebound-regions.rs
new file mode 100644
index 00000000000..a4fe8650129
--- /dev/null
+++ b/src/test/ui/existential_types/issue-60655-latebound-regions.rs
@@ -0,0 +1,30 @@
+// Test that existential types are allowed to contain late-bound regions.
+
+// compile-pass
+// edition:2018
+
+#![feature(async_await, existential_type)]
+
+use std::future::Future;
+
+pub existential type Func: Sized;
+
+// Late bound region should be allowed to escape the function, since it's bound
+// in the type.
+fn null_function_ptr() -> Func {
+    None::<for<'a> fn(&'a ())>
+}
+
+async fn async_nop(_: &u8) {}
+
+pub existential type ServeFut: Future<Output=()>;
+
+// Late bound regions occur in the generator witness type here.
+fn serve() -> ServeFut {
+    async move {
+        let x = 5;
+        async_nop(&x).await
+    }
+}
+
+fn main() {}