about summary refs log tree commit diff
path: root/src/test/ui/nll
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-01-12 14:55:23 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2019-01-19 16:30:45 +0000
commit65fe2516346f10dc8d670e9fdfbd4e4f99a5b34b (patch)
tree58eca1afd783b7c256d0918893e3fcb1309c3dcb /src/test/ui/nll
parented871cb368f6b72dde644b0c21e0f9e62dba1810 (diff)
downloadrust-65fe2516346f10dc8d670e9fdfbd4e4f99a5b34b.tar.gz
rust-65fe2516346f10dc8d670e9fdfbd4e4f99a5b34b.zip
Handle lifetime annotations in unreachable code
We  equate the type in the annotation with the inferred type first so
that we have a fully inferred type to perform the well-formedness check
on.
Diffstat (limited to 'src/test/ui/nll')
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/wf-unreachable.rs54
-rw-r--r--src/test/ui/nll/ty-outlives/wf-unreachable.stderr73
-rw-r--r--src/test/ui/nll/user-annotations/downcast-infer.rs11
5 files changed, 140 insertions, 2 deletions
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
index acb978b5d5a..597b096dbe6 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
@@ -2,7 +2,7 @@ error[E0309]: the associated type `<T as MyTrait<'_>>::Output` may not live long
   --> $DIR/projection-where-clause-env-wrong-bound.rs:17:5
    |
 LL |     bar::<T::Output>() //~ ERROR may not live long enough
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
 
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
index 2d171a98789..3c2ac474778 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
@@ -2,7 +2,7 @@ error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/projection-where-clause-none.rs:16:5
    |
 LL |     bar::<T::Output>() //~ ERROR the parameter type `T` may not live long enough
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `T: 'a`...
 
diff --git a/src/test/ui/nll/ty-outlives/wf-unreachable.rs b/src/test/ui/nll/ty-outlives/wf-unreachable.rs
new file mode 100644
index 00000000000..a2e3ab41614
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/wf-unreachable.rs
@@ -0,0 +1,54 @@
+// Test that we check that user type annotations are well-formed, even in dead
+// code.
+
+#![feature(nll)]
+
+fn uninit<'a>() {
+    return;
+    let x: &'static &'a ();                         //~ ERROR lifetime may not live long enough
+}
+
+fn var_type<'a>() {
+    return;
+    let x: &'static &'a () = &&();                  //~ ERROR lifetime may not live long enough
+}
+
+fn uninit_infer<'a>() {
+    let x: &'static &'a _;                          //~ ERROR lifetime may not live long enough
+    x = && ();
+}
+
+fn infer<'a>() {
+    return;
+    let x: &'static &'a _ = &&();                   //~ ERROR lifetime may not live long enough
+}
+
+fn uninit_no_var<'a>() {
+    return;
+    let _: &'static &'a ();                         //~ ERROR lifetime may not live long enough
+}
+
+fn no_var<'a>() {
+    return;
+    let _: &'static &'a () = &&();                  //~ ERROR lifetime may not live long enough
+}
+
+fn infer_no_var<'a>() {
+    return;
+    let _: &'static &'a _ = &&();                   //~ ERROR lifetime may not live long enough
+}
+
+trait X<'a, 'b> {}
+
+struct C<'a, 'b, T: X<'a, 'b>>(T, &'a (), &'b ());
+
+impl X<'_, '_> for i32 {}
+impl<'a> X<'a, 'a> for () {}
+
+// This type annotation is not well-formed because we substitute `()` for `_`.
+fn required_substs<'a>() {
+    return;
+    let _: C<'static, 'a, _> = C((), &(), &());     //~ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/wf-unreachable.stderr b/src/test/ui/nll/ty-outlives/wf-unreachable.stderr
new file mode 100644
index 00000000000..14642a1e615
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/wf-unreachable.stderr
@@ -0,0 +1,73 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:8:12
+   |
+LL | fn uninit<'a>() {
+   |           -- lifetime `'a` defined here
+LL |     return;
+LL |     let x: &'static &'a ();                         //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:13:12
+   |
+LL | fn var_type<'a>() {
+   |             -- lifetime `'a` defined here
+LL |     return;
+LL |     let x: &'static &'a () = &&();                  //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:17:12
+   |
+LL | fn uninit_infer<'a>() {
+   |                 -- lifetime `'a` defined here
+LL |     let x: &'static &'a _;                          //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:23:12
+   |
+LL | fn infer<'a>() {
+   |          -- lifetime `'a` defined here
+LL |     return;
+LL |     let x: &'static &'a _ = &&();                   //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:28:12
+   |
+LL | fn uninit_no_var<'a>() {
+   |                  -- lifetime `'a` defined here
+LL |     return;
+LL |     let _: &'static &'a ();                         //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:33:12
+   |
+LL | fn no_var<'a>() {
+   |           -- lifetime `'a` defined here
+LL |     return;
+LL |     let _: &'static &'a () = &&();                  //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:38:12
+   |
+LL | fn infer_no_var<'a>() {
+   |                 -- lifetime `'a` defined here
+LL |     return;
+LL |     let _: &'static &'a _ = &&();                   //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/wf-unreachable.rs:51:12
+   |
+LL | fn required_substs<'a>() {
+   |                    -- lifetime `'a` defined here
+LL |     return;
+LL |     let _: C<'static, 'a, _> = C((), &(), &());     //~ ERROR lifetime may not live long enough
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/nll/user-annotations/downcast-infer.rs b/src/test/ui/nll/user-annotations/downcast-infer.rs
new file mode 100644
index 00000000000..23b76bb1964
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/downcast-infer.rs
@@ -0,0 +1,11 @@
+// compile-pass
+
+// Check that we don't try to downcast `_` when type-checking the annotation.
+fn main() {
+    let x = Some(Some(Some(1)));
+
+    match x {
+        Some::<Option<_>>(Some(Some(v))) => (),
+        _ => (),
+    }
+}