about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-12-04 13:04:38 -0500
committerNiko Matsakis <niko@alum.mit.edu>2017-12-15 10:27:51 -0500
commit85e1d4749e5ba14ff89073f5812974ec8fdbffd4 (patch)
tree5442f2b3f0f5dc1e885c09bfdb50bdfcc95cf2c2 /src/test
parent5804637a81a8e5216fbbf2e3e7c0a7bdca9c99de (diff)
downloadrust-85e1d4749e5ba14ff89073f5812974ec8fdbffd4.tar.gz
rust-85e1d4749e5ba14ff89073f5812974ec8fdbffd4.zip
propagate type tests from closure to closure creators
Currently, we only propagate type tests that exclude all regions from
the type.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs66
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr58
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs96
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr191
4 files changed, 411 insertions, 0 deletions
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs
new file mode 100644
index 00000000000..6b23c82c771
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs
@@ -0,0 +1,66 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::fmt::Debug;
+
+fn with_signature<'a, T, F>(x: Box<T>, op: F) -> Box<dyn Debug + 'a>
+    where F: FnOnce(Box<T>) -> Box<dyn Debug + 'a>
+{
+    op(x)
+}
+
+#[rustc_regions]
+fn no_region<'a, T>(x: Box<T>) -> Box<dyn Debug + 'a>
+where
+    T: Debug,
+{
+    // Here, the closure winds up being required to prove that `T:
+    // 'a`.  In principle, it could know that, except that it is
+    // type-checked in a fully generic way, and hence it winds up with
+    // a propagated requirement that `T: '_#2`, where `'_#2` appears
+    // in the return type. The caller makes the mapping from `'_#2` to
+    // `'a` (and subsequently reports an error).
+
+    with_signature(x, |y| y)
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR failed type test
+}
+
+fn correct_region<'a, T>(x: Box<T>) -> Box<Debug + 'a>
+where
+    T: 'a + Debug,
+{
+    x
+}
+
+fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<Debug + 'a>
+where
+    T: 'b + Debug,
+{
+    x
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR failed type test
+}
+
+fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<Debug + 'a>
+where
+    T: 'b + Debug,
+    'b: 'a,
+{
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
new file mode 100644
index 00000000000..721896a93ff
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -0,0 +1,58 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:37:27
+   |
+37 |     with_signature(x, |y| y)
+   |                           ^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:53:5
+   |
+53 |     x
+   |     ^
+
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:37:23
+   |
+37 |     with_signature(x, |y| y)
+   |                       ^^^^^
+   |
+   = note: defining type: DefId(0/1:14 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<std::fmt::Debug + '_#2r>
+           ]
+   = note: number of external vids: 3
+   = note: where T: '_#2r
+
+error: failed type test: TypeTest { generic_kind: T/#1, lower_bound: '_#4r, point: bb0[5], span: $DIR/ty-param-closure-outlives-from-return-type.rs:37:23: 37:28, test: IsOutlivedByAnyRegionIn(['_#2r]) }
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:37:23
+   |
+37 |     with_signature(x, |y| y)
+   |                       ^^^^^
+
+note: No external requirements
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:1
+   |
+26 | / fn no_region<'a, T>(x: Box<T>) -> Box<dyn Debug + 'a>
+27 | | where
+28 | |     T: Debug,
+29 | | {
+...  |
+39 | |     //~| ERROR failed type test
+40 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:5 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: failed type test: TypeTest { generic_kind: T/#2, lower_bound: '_#4r, point: bb0[3], span: $DIR/ty-param-closure-outlives-from-return-type.rs:53:5: 53:6, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) }
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:53:5
+   |
+53 |     x
+   |     ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
new file mode 100644
index 00000000000..54f7b4fa50d
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
@@ -0,0 +1,96 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can propagate `T: 'a` obligations to our caller.  See
+// `correct_region` for an explanation of how this test is setup; it's
+// somewhat intricate.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+fn with_signature<'a, T, F>(a: Cell<&'a ()>, b: T, op: F)
+where
+    F: FnOnce(Cell<&'a ()>, T),
+{
+    op(a, b)
+}
+
+fn require<'a, T>(_a: &Cell<&'a ()>, _b: &T)
+where
+    T: 'a,
+{
+}
+
+#[rustc_regions]
+fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
+    with_signature(a, b, |x, y| {
+        //~^ ERROR failed type test
+        //
+        // See `correct_region`, which explains the point of this
+        // test.  The only difference is that, in the case of this
+        // function, there is no where clause *anywhere*, and hence we
+        // get an error (but reported by the closure creator).
+        require(&x, &y)
+        //~^ WARNING not reporting region error due to -Znll
+    })
+}
+
+#[rustc_regions]
+fn correct_region<'a, T>(a: Cell<&'a ()>, b: T)
+where
+    T: 'a,
+{
+    with_signature(a, b, |x, y| {
+        // Key point of this test:
+        //
+        // The *closure* is being type-checked with all of its free
+        // regions "universalized". In particular, it does not know
+        // that `x` has the type `Cell<&'a ()>`, but rather treats it
+        // as if the type of `x` is `Cell<&'A ()>`, where `'A` is some
+        // fresh, independent region distinct from the `'a` which
+        // appears in the environment. The call to `require` here
+        // forces us then to prove that `T: 'A`, but the closure
+        // cannot do it on its own. It has to surface this requirement
+        // to its creator (which knows that `'a == 'A`).
+        require(&x, &y)
+    })
+}
+
+#[rustc_regions]
+fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
+where
+    T: 'b,
+{
+    with_signature(a, b, |x, y| {
+        //~^ ERROR failed type test
+        // See `correct_region`
+        require(&x, &y)
+        //~^ WARNING not reporting region error due to -Znll
+    })
+}
+
+#[rustc_regions]
+fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
+where
+    T: 'b,
+    'b: 'a,
+{
+    with_signature(a, b, |x, y| {
+        // See `correct_region`
+        require(&x, &y)
+    })
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
new file mode 100644
index 00000000000..748333badce
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -0,0 +1,191 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:45:9
+   |
+45 |         require(&x, &y)
+   |         ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:79:9
+   |
+79 |         require(&x, &y)
+   |         ^^^^^^^
+
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26
+   |
+38 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+39 | |         //~^ ERROR failed type test
+40 | |         //
+41 | |         // See `correct_region`, which explains the point of this
+...  |
+46 | |         //~^ WARNING not reporting region error due to -Znll
+47 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:16 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#1r ()>, T))
+           ]
+   = note: number of external vids: 2
+   = note: where T: '_#1r
+
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:55:26
+   |
+55 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+56 | |         // Key point of this test:
+57 | |         //
+58 | |         // The *closure* is being type-checked with all of its free
+...  |
+67 | |         require(&x, &y)
+68 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:19 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+   = note: number of external vids: 3
+   = note: where T: '_#2r
+
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
+   |
+76 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+77 | |         //~^ ERROR failed type test
+78 | |         // See `correct_region`
+79 | |         require(&x, &y)
+80 | |         //~^ WARNING not reporting region error due to -Znll
+81 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+   = note: number of external vids: 3
+   = note: where T: '_#2r
+
+note: External requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:90:26
+   |
+90 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+91 | |         // See `correct_region`
+92 | |         require(&x, &y)
+93 | |     })
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:27 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+   = note: number of external vids: 4
+   = note: where T: '_#3r
+
+error: failed type test: TypeTest { generic_kind: T/#0, lower_bound: '_#3r, point: bb0[5], span: $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26: 47:6, test: IsOutlivedByAnyRegionIn(['_#2r]) }
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26
+   |
+38 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+39 | |         //~^ ERROR failed type test
+40 | |         //
+41 | |         // See `correct_region`, which explains the point of this
+...  |
+46 | |         //~^ WARNING not reporting region error due to -Znll
+47 | |     })
+   | |_____^
+
+note: No external requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:37:1
+   |
+37 | / fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
+38 | |     with_signature(a, b, |x, y| {
+39 | |         //~^ ERROR failed type test
+40 | |         //
+...  |
+47 | |     })
+48 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:6 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]) with substs [
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:51:1
+   |
+51 | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T)
+52 | | where
+53 | |     T: 'a,
+54 | | {
+...  |
+68 | |     })
+69 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:7 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: failed type test: TypeTest { generic_kind: T/#1, lower_bound: '_#5r, point: bb0[5], span: $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26: 81:6, test: IsOutlivedByAnyRegionIn(['_#1r, '_#3r]) }
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
+   |
+76 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+77 | |         //~^ ERROR failed type test
+78 | |         // See `correct_region`
+79 | |         require(&x, &y)
+80 | |         //~^ WARNING not reporting region error due to -Znll
+81 | |     })
+   | |_____^
+
+note: No external requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1
+   |
+72 | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
+73 | | where
+74 | |     T: 'b,
+75 | | {
+...  |
+81 | |     })
+82 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:85:1
+   |
+85 | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
+86 | | where
+87 | |     T: 'b,
+88 | |     'b: 'a,
+...  |
+93 | |     })
+94 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+error: aborting due to 2 previous errors
+