about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-20 03:58:15 +0000
committerbors <bors@rust-lang.org>2017-12-20 03:58:15 +0000
commit588f7db8ef588ea7e349817bb44b4e37bfd92745 (patch)
tree8f533a5308ce9b27e5cbc37d2db8632f786e433a /src/test
parentedbd7d232ee1272285be332b8a38eb47b4c8f5c6 (diff)
parent1816ede386c6dd6e61f50e7b0f9bdba19adc0e24 (diff)
Auto merge of #46733 - nikomatsakis:nll-master-to-rust-master-5, r=arielb1
nll part 5

Next round of changes from the nll-master branch.

Extensions:

- we now propagate ty-region-outlives constraints out of closures and into their creator when necessary
- we fix a few ICEs that can occur by doing liveness analysis (and the resulting normalization) during type-checking
- we handle the implicit region bound that assumes that each type `T` outlives the fn body
- we handle normalization of inputs/outputs in fn signatures

Not included in this PR (will come next):

- handling `impl Trait`
- tracking causal information
- extended errors

r? @arielb1
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/mir_check_cast_closure.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_reify.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_unsafe_fn.rs2
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic.rs24
-rw-r--r--src/test/mir-opt/nll/reborrow-basic.rs8
-rw-r--r--src/test/mir-opt/nll/region-liveness-basic.rs8
-rw-r--r--src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs4
-rw-r--r--src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs4
-rw-r--r--src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs12
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic.rs12
-rw-r--r--src/test/ui/nll/capture-ref-in-struct.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr3
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr5
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr13
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr5
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr45
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr7
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr7
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs60
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr60
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr3
-rw-r--r--src/test/ui/nll/projection-return.rs29
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs68
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr157
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs53
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr26
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.rs106
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr194
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs106
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr204
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs99
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr155
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs135
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr326
-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
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn-body.rs41
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr14
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn.rs51
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn.stderr26
47 files changed, 2436 insertions, 67 deletions
diff --git a/src/test/compile-fail/mir_check_cast_closure.rs b/src/test/compile-fail/mir_check_cast_closure.rs
index be0d4b13741..6562efeb6d8 100644
--- a/src/test/compile-fail/mir_check_cast_closure.rs
+++ b/src/test/compile-fail/mir_check_cast_closure.rs
@@ -14,9 +14,9 @@
 
 fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
     let g: fn(_, _) -> _ = |_x, y| y;
+    //~^ ERROR free region `'b` does not outlive free region `'a`
     g
     //~^ WARNING not reporting region error due to -Znll
-    //~| ERROR free region `'b` does not outlive free region `'a`
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/mir_check_cast_reify.rs b/src/test/compile-fail/mir_check_cast_reify.rs
index 091e0b71b2d..1736aea2d6d 100644
--- a/src/test/compile-fail/mir_check_cast_reify.rs
+++ b/src/test/compile-fail/mir_check_cast_reify.rs
@@ -45,8 +45,8 @@ fn bar<'a>(x: &'a u32) -> &'static u32 {
     // as part of checking the `ReifyFnPointer`.
     let f: fn(_) -> _ = foo;
     //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `'_#1r` does not outlive free region `'static`
     f(x)
-    //~^ ERROR free region `'_#1r` does not outlive free region `'static`
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
index 701a7c6b056..39eafa10040 100644
--- a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
+++ b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
@@ -17,8 +17,8 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
     // in `g`. These are related via the `UnsafeFnPointer` cast.
     let g: unsafe fn(_) -> _ = f;
     //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `'_#1r` does not outlive free region `'static`
     unsafe { g(input) }
-    //~^ ERROR free region `'_#1r` does not outlive free region `'static`
 }
 
 fn main() {}
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs
index f3a57c08840..8feac15d69a 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic.rs
+++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs
@@ -27,17 +27,23 @@ fn main() {
 // END RUST SOURCE
 // START rustc.use_x.nll.0.mir
 // | Free Region Mapping
-// | '_#0r    | Global   | ['_#2r, '_#1r, '_#0r, '_#3r]
-// | '_#1r    | External | ['_#1r]
-// | '_#2r    | External | ['_#2r, '_#1r]
-// | '_#3r    | Local    | ['_#3r]
+// | '_#0r    | Global   | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r]
+// | '_#1r    | External | ['_#1r, '_#4r]
+// | '_#2r    | External | ['_#2r, '_#1r, '_#4r]
+// | '_#3r    | Local    | ['_#4r, '_#3r]
+// | '_#4r    | Local    | ['_#4r]
 // |
 // | Inferred Region Values
-// | '_#0r    | {'_#0r, bb0[0], bb0[1]}
-// | '_#1r    | {'_#1r, bb0[0], bb0[1]}
-// | '_#2r    | {'_#2r, bb0[0], bb0[1]}
-// | '_#3r    | {'_#3r, bb0[0], bb0[1]}
+// | '_#0r    | {'_#0r, bb0[0..=1]}
+// | '_#1r    | {'_#1r, bb0[0..=1]}
+// | '_#2r    | {'_#2r, bb0[0..=1]}
+// | '_#3r    | {'_#3r, bb0[0..=1]}
+// | '_#4r    | {'_#4r, bb0[0..=1]}
+// | '_#5r    | {'_#1r, bb0[0..=1]}
+// | '_#6r    | {'_#2r, bb0[0..=1]}
+// | '_#7r    | {'_#1r, bb0[0..=1]}
+// | '_#8r    | {'_#3r, bb0[0..=1]}
 // |
 // ...
-// fn use_x(_1: &'_#1r mut i32, _2: &'_#2r u32, _3: &'_#1r u32, _4: &'_#3r u32) -> bool {
+// fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
 // END rustc.use_x.nll.0.mir
diff --git a/src/test/mir-opt/nll/reborrow-basic.rs b/src/test/mir-opt/nll/reborrow-basic.rs
index d203472f20c..f69c51c3562 100644
--- a/src/test/mir-opt/nll/reborrow-basic.rs
+++ b/src/test/mir-opt/nll/reborrow-basic.rs
@@ -28,11 +28,11 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#6r    | {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
+// | '_#7r    | {bb0[6..=14]}
 // ...
-// | '_#8r    | {bb0[11], bb0[12], bb0[13], bb0[14]}
+// | '_#9r    | {bb0[11..=14]}
 // ...
-// let _2: &'_#6r mut i32;
+// let _2: &'_#7r mut i32;
 // ...
-// let _4: &'_#8r mut i32;
+// let _4: &'_#9r mut i32;
 // END rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-liveness-basic.rs b/src/test/mir-opt/nll/region-liveness-basic.rs
index c04cedbc04b..e9834305550 100644
--- a/src/test/mir-opt/nll/region-liveness-basic.rs
+++ b/src/test/mir-opt/nll/region-liveness-basic.rs
@@ -31,15 +31,15 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#1r    | {bb2[0], bb2[1], bb3[0], bb3[1]}
-// | '_#2r    | {bb2[1], bb3[0], bb3[1]}
+// | '_#2r    | {bb2[0..=1], bb3[0..=1]}
+// | '_#3r    | {bb2[1], bb3[0..=1]}
 // ...
-//             let _2: &'_#2r usize;
+//             let _2: &'_#3r usize;
 // END rustc.main.nll.0.mir
 // START rustc.main.nll.0.mir
 //    bb2: {
 //            | Live variables on entry to bb2[0]: [_1, _3]
-//        _2 = &'_#1r _1[_3];
+//        _2 = &'_#2r _1[_3];
 //            | Live variables on entry to bb2[1]: [_2]
 //        switchInt(const true) -> [0u8: bb4, otherwise: bb3];
 //    }
diff --git a/src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs b/src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs
index e2ad49a4436..c14ce6bb581 100644
--- a/src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs
+++ b/src/test/mir-opt/nll/region-liveness-drop-may-dangle.rs
@@ -44,5 +44,7 @@ unsafe impl<#[may_dangle] T> Drop for Wrap<T> {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#5r    | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1]}
+// | '_#6r    | {bb2[3..=5], bb3[0..=1]}
+// ...
+// let _2: Wrap<&'_#6r usize>;
 // END rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs b/src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs
index e0272a51d03..058a57fe612 100644
--- a/src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs
+++ b/src/test/mir-opt/nll/region-liveness-drop-no-may-dangle.rs
@@ -46,5 +46,7 @@ impl<T> Drop for Wrap<T> {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#5r    | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1], bb3[2], bb4[0], bb5[0], bb5[1], bb5[2], bb6[0], bb7[0], bb7[1], bb8[0]}
+// | '_#6r    | {bb2[3..=5], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0], bb7[0..=1], bb8[0]}
+// ...
+// let _2: Wrap<&'_#6r usize>;
 // END rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs b/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
index 8aa0eb1a3a9..821cd736671 100644
--- a/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
+++ b/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
@@ -36,14 +36,14 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#1r    | {bb2[0], bb2[1], bb3[0], bb3[1]}
+// | '_#2r    | {bb2[0..=1], bb3[0..=1]}
 // ...
-// | '_#3r    | {bb8[1], bb8[2], bb8[3], bb8[4]}
-// | '_#4r    | {bb2[1], bb3[0], bb3[1], bb8[2], bb8[3], bb8[4]}
+// | '_#4r    | {bb8[1..=4]}
+// | '_#5r    | {bb2[1], bb3[0..=1], bb8[2..=4]}
 // ...
-// let mut _2: &'_#4r usize;
+// let mut _2: &'_#5r usize;
 // ...
-// _2 = &'_#1r _1[_3];
+// _2 = &'_#2r _1[_3];
 // ...
-// _2 = &'_#3r (*_10);
+// _2 = &'_#4r (*_10);
 // END rustc.main.nll.0.mir
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs
index 2bc165bd3c4..a3f68ed5ebf 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic.rs
+++ b/src/test/mir-opt/nll/region-subtyping-basic.rs
@@ -32,16 +32,16 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#1r    | {bb2[0], bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
-// | '_#2r    | {bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
-// | '_#3r    | {bb2[5], bb2[6], bb3[0], bb3[1]}
+// | '_#2r    | {bb2[0..=6], bb3[0..=1]}
+// | '_#3r    | {bb2[1..=6], bb3[0..=1]}
+// | '_#4r    | {bb2[5..=6], bb3[0..=1]}
 // END rustc.main.nll.0.mir
 // START rustc.main.nll.0.mir
-// let _2: &'_#2r usize;
+// let _2: &'_#3r usize;
 // ...
-// let _6: &'_#3r usize;
+// let _6: &'_#4r usize;
 // ...
-// _2 = &'_#1r _1[_3];
+// _2 = &'_#2r _1[_3];
 // ...
 // _7 = _2;
 // ...
diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr
index ed57d89802c..3812ff40407 100644
--- a/src/test/ui/nll/capture-ref-in-struct.stderr
+++ b/src/test/ui/nll/capture-ref-in-struct.stderr
@@ -7,7 +7,7 @@ error[E0597]: `y` does not live long enough
 37 |     }
    |      - borrowed value only lives until here
    |
-   = note: borrowed value must be valid for lifetime '_#4r...
+   = note: borrowed value must be valid for lifetime '_#5r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index c842d51a2ad..2dfafd8f172 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -10,7 +10,7 @@ error: free region `'_#4r` does not outlive free region `'_#3r`
 36 |         let mut closure = expect_sig(|p, y| *p = y);
    |                                             ^^^^^^
 
-note: External requirements
+note: No external requirements
   --> $DIR/escape-argument-callee.rs:36:38
    |
 36 |         let mut closure = expect_sig(|p, y| *p = y);
@@ -20,7 +20,6 @@ note: External requirements
                i16,
                for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) i32))
            ]
-   = note: number of external vids: 1
 
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:30:1
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index 4e9a25e2892..94019798600 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -1,4 +1,4 @@
-note: External requirements
+note: No external requirements
   --> $DIR/escape-argument.rs:36:38
    |
 36 |         let mut closure = expect_sig(|p, y| *p = y);
@@ -8,7 +8,6 @@ note: External requirements
                i16,
                for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32))
            ]
-   = note: number of external vids: 1
 
 note: No external requirements
   --> $DIR/escape-argument.rs:30:1
@@ -33,7 +32,7 @@ error[E0597]: `y` does not live long enough
 39 |     }
    |      - borrowed value only lives until here
    |
-   = note: borrowed value must be valid for lifetime '_#5r...
+   = note: borrowed value must be valid for lifetime '_#6r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
index 60bd7a569a0..277e5201416 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
@@ -59,7 +59,7 @@ error[E0597]: `y` does not live long enough
 36 |       }
    |        - borrowed value only lives until here
    |
-   = note: borrowed value must be valid for lifetime '_#3r...
+   = note: borrowed value must be valid for lifetime '_#4r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
index dc86f4cff08..709e6bc2de1 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
@@ -36,7 +36,7 @@ error[E0597]: `y` does not live long enough
 36 |     }
    |      - borrowed value only lives until here
    |
-   = note: borrowed value must be valid for lifetime '_#3r...
+   = note: borrowed value must be valid for lifetime '_#4r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
index c2f071cc029..50d7877de50 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
@@ -54,8 +54,8 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
             // Only works if 'x: 'y:
             let p = x.get();
             //~^ WARN not reporting region error due to -Znll
+            //~| ERROR free region `'_#5r` does not outlive free region `'_#6r`
             demand_y(x, y, p)
-            //~^ ERROR free region `'_#5r` does not outlive free region `'_#6r`
         },
     );
 }
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index d581622c4c6..f90bc7c175a 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -5,20 +5,20 @@ warning: not reporting region error due to -Znll
    |                     ^^^^^^^
 
 error: free region `'_#5r` does not outlive free region `'_#6r`
-  --> $DIR/propagate-approximated-fail-no-postdom.rs:57:25
+  --> $DIR/propagate-approximated-fail-no-postdom.rs:55:17
    |
-57 |             demand_y(x, y, p)
-   |                         ^
+55 |             let p = x.get();
+   |                 ^
 
-note: External requirements
+note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
    |
 53 | /         |_outlives1, _outlives2, _outlives3, x, y| {
 54 | |             // Only works if 'x: 'y:
 55 | |             let p = x.get();
 56 | |             //~^ WARN not reporting region error due to -Znll
-57 | |             demand_y(x, y, p)
-58 | |             //~^ ERROR free region `'_#5r` does not outlive free region `'_#6r`
+57 | |             //~| ERROR free region `'_#5r` does not outlive free region `'_#6r`
+58 | |             demand_y(x, y, p)
 59 | |         },
    | |_________^
    |
@@ -26,7 +26,6 @@ note: External requirements
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: number of external vids: 4
 
 note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:48:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index 717cf481a01..4bae29ad326 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -24,10 +24,10 @@ note: External requirements
    = note: where '_#1r: '_#2r
 
 error: free region `'_#1r` does not outlive free region `'_#2r`
-  --> $DIR/propagate-approximated-ref.rs:53:38
+  --> $DIR/propagate-approximated-ref.rs:53:29
    |
 53 |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                      ^^^^^^^
+   |                             ^^^^^^^
 
 note: No external requirements
   --> $DIR/propagate-approximated-ref.rs:52:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 9b23c48e249..45dc5d913ee 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -10,7 +10,7 @@ error: free region `'_#2r` does not outlive free region `'_#1r`
 33 |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
    |         ^^^^^^
 
-note: External requirements
+note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
    |
 31 |       foo(cell, |cell_a, cell_x| {
@@ -25,7 +25,6 @@ note: External requirements
                i32,
                for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
            ]
-   = note: number of external vids: 2
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1
@@ -80,7 +79,7 @@ error[E0597]: `a` does not live long enough
 49 | }
    | - borrowed value only lives until here
    |
-   = note: borrowed value must be valid for lifetime '_#1r...
+   = note: borrowed value must be valid for lifetime '_#2r...
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
new file mode 100644
index 00000000000..502b344c89e
--- /dev/null
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
@@ -0,0 +1,45 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/propagate-approximated-to-empty.rs:41:9
+   |
+41 |         demand_y(x, y, x.get())
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: free region `'_#6r` does not outlive free region `'_#4r`
+  --> $DIR/propagate-approximated-to-empty.rs:41:18
+   |
+41 |         demand_y(x, y, x.get())
+   |                  ^
+
+note: No external requirements
+  --> $DIR/propagate-approximated-to-empty.rs:39:47
+   |
+39 |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+   |  _______________________________________________^
+40 | |         // Only works if 'x: 'y:
+41 | |         demand_y(x, y, x.get())
+42 | |         //~^ WARN not reporting region error due to -Znll
+43 | |         //~| ERROR free region `'_#6r` does not outlive free region `'_#4r`
+44 | |     });
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:18 ~ propagate_approximated_to_empty[317d]::supply[0]::{{closure}}[0]) with closure substs [
+               i16,
+               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
+           ]
+
+note: No external requirements
+  --> $DIR/propagate-approximated-to-empty.rs:38:1
+   |
+38 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+39 | |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+40 | |         // Only works if 'x: 'y:
+41 | |         demand_y(x, y, x.get())
+...  |
+44 | |     });
+45 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:6 ~ propagate_approximated_to_empty[317d]::supply[0]) with substs []
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index 43464bfb2b9..43d61fdf1b5 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -24,10 +24,10 @@ note: External requirements
    = note: where '_#1r: '_#2r
 
 error: free region `'_#1r` does not outlive free region `'_#2r`
-  --> $DIR/propagate-approximated-val.rs:46:37
+  --> $DIR/propagate-approximated-val.rs:46:29
    |
 46 |     establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
-   |                                     ^^^^^^
+   |                             ^^^^^^
 
 note: No external requirements
   --> $DIR/propagate-approximated-val.rs:45:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 6094f9aad81..f3c40c838fb 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -5,12 +5,12 @@ warning: not reporting region error due to -Znll
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: free region `'_#6r` does not outlive free region `'_#4r`
-  --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:21
+  --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:18
    |
 47 |         demand_y(x, y, x.get())
-   |                     ^
+   |                  ^
 
-note: External requirements
+note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
    |
 45 |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
@@ -26,7 +26,6 @@ note: External requirements
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: number of external vids: 2
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:44:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 6658ee63abd..a66c2a78970 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -5,12 +5,12 @@ warning: not reporting region error due to -Znll
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: free region `'_#5r` does not outlive free region `'_#7r`
-  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:21
+  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:18
    |
 51 |         demand_y(x, y, x.get())
-   |                     ^
+   |                  ^
 
-note: External requirements
+note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
    |
 49 |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
@@ -26,7 +26,6 @@ note: External requirements
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
-   = note: number of external vids: 3
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:48:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
new file mode 100644
index 00000000000..604c81da49d
--- /dev/null
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
@@ -0,0 +1,60 @@
+// 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 regions which appear only in the closure's generics (in
+// this case, `'a`) are properly mapped to the creator's generics. In
+// this case, the closure constrains its type parameter `T` to outlive
+// the same `'a` for which it implements `Trait`, which can only be the `'a`
+// from the function definition.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+trait Trait<'a> {}
+
+fn establish_relationships<T, F>(value: T, closure: F)
+where
+    F: FnOnce(T),
+{
+    closure(value)
+}
+
+fn require<'a, T>(t: T)
+where
+    T: Trait<'a> + 'a,
+{
+}
+
+#[rustc_regions]
+fn supply<'a, T>(value: T)
+where
+    T: Trait<'a>,
+{
+    establish_relationships(value, |value| {
+        //~^ ERROR `T` does not outlive
+
+        // This function call requires that
+        //
+        // (a) T: Trait<'a>
+        //
+        // and
+        //
+        // (b) T: 'a
+        //
+        // The latter does not hold.
+
+        require(value);
+        //~^ WARNING not reporting region error due to -Znll
+    });
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
new file mode 100644
index 00000000000..efac55f2bee
--- /dev/null
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -0,0 +1,60 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/propagate-from-trait-match.rs:55:9
+   |
+55 |         require(value);
+   |         ^^^^^^^
+
+note: External requirements
+  --> $DIR/propagate-from-trait-match.rs:42:36
+   |
+42 |       establish_relationships(value, |value| {
+   |  ____________________________________^
+43 | |         //~^ ERROR `T` does not outlive
+44 | |
+45 | |         // This function call requires that
+...  |
+56 | |         //~^ WARNING not reporting region error due to -Znll
+57 | |     });
+   | |_____^
+   |
+   = note: defining type: DefId(0/1:16 ~ propagate_from_trait_match[317d]::supply[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((T,))
+           ]
+   = note: number of external vids: 2
+   = note: where T: '_#1r
+
+error: `T` does not outlive `'_#3r`
+  --> $DIR/propagate-from-trait-match.rs:42:36
+   |
+42 |       establish_relationships(value, |value| {
+   |  ____________________________________^
+43 | |         //~^ ERROR `T` does not outlive
+44 | |
+45 | |         // This function call requires that
+...  |
+56 | |         //~^ WARNING not reporting region error due to -Znll
+57 | |     });
+   | |_____^
+
+note: No external requirements
+  --> $DIR/propagate-from-trait-match.rs:38:1
+   |
+38 | / fn supply<'a, T>(value: T)
+39 | | where
+40 | |     T: Trait<'a>,
+41 | | {
+...  |
+57 | |     });
+58 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:6 ~ propagate_from_trait_match[317d]::supply[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 8999f69e8de..cb2b2e2f118 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -10,7 +10,7 @@ error: free region `'_#3r` does not outlive free region `'_#2r`
 21 |     expect_sig(|a, b| b); // ought to return `a`
    |                       ^
 
-note: External requirements
+note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:21:16
    |
 21 |     expect_sig(|a, b| b); // ought to return `a`
@@ -20,7 +20,6 @@ note: External requirements
                i16,
                for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32
            ]
-   = note: number of external vids: 1
 
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:20:1
diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs
new file mode 100644
index 00000000000..31388cf50c5
--- /dev/null
+++ b/src/test/ui/nll/projection-return.rs
@@ -0,0 +1,29 @@
+// 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
+// must-compile-successfully
+
+#![feature(rustc_attrs)]
+
+trait Foo {
+    type Bar;
+}
+
+impl Foo for () {
+    type Bar = u32;
+}
+
+fn foo() -> <() as Foo>::Bar {
+    22
+}
+
+fn main() { }
+
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
new file mode 100644
index 00000000000..9451163ace9
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
@@ -0,0 +1,68 @@
+// 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
+
+// Tests closures that propagate an outlives relationship to their
+// creator where the subject is a projection with no regions (`<T as
+// Iterator>::Item`, to be exact).
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+trait Anything { }
+
+impl<T> Anything for T { }
+
+fn with_signature<'a, T, F>(x: Box<T>, op: F) -> Box<dyn Anything + 'a>
+    where F: FnOnce(Box<T>) -> Box<dyn Anything + 'a>
+{
+    op(x)
+}
+
+#[rustc_regions]
+fn no_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+where
+    T: Iterator,
+{
+    with_signature(x, |mut y| Box::new(y.next()))
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+}
+
+#[rustc_regions]
+fn correct_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+where
+    T: 'a + Iterator,
+{
+    with_signature(x, |mut y| Box::new(y.next()))
+}
+
+#[rustc_regions]
+fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+where
+    T: 'b + Iterator,
+{
+    with_signature(x, |mut y| Box::new(y.next()))
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+}
+
+#[rustc_regions]
+fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+where
+    T: 'b + Iterator,
+    'b: 'a,
+{
+    with_signature(x, |mut y| Box::new(y.next()))
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
new file mode 100644
index 00000000000..9afd5d41182
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -0,0 +1,157 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-no-regions-closure.rs:36:31
+   |
+36 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                               ^^^^^^^^^^^^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-no-regions-closure.rs:54:31
+   |
+54 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                               ^^^^^^^^^^^^^^^^^^
+
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:36:23
+   |
+36 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:15 ~ projection_no_regions_closure[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+           ]
+   = note: number of external vids: 3
+   = note: where <T as std::iter::Iterator>::Item: '_#2r
+
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:46:23
+   |
+46 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+           ]
+   = note: number of external vids: 3
+   = note: where <T as std::iter::Iterator>::Item: '_#2r
+
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:54:23
+   |
+54 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+           ]
+   = note: number of external vids: 4
+   = note: where <T as std::iter::Iterator>::Item: '_#3r
+
+note: External requirements
+  --> $DIR/projection-no-regions-closure.rs:65:23
+   |
+65 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+           ]
+   = note: number of external vids: 4
+   = note: where <T as std::iter::Iterator>::Item: '_#3r
+
+error: `<T as std::iter::Iterator>::Item` does not outlive `'_#4r`
+  --> $DIR/projection-no-regions-closure.rs:36:23
+   |
+36 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: No external requirements
+  --> $DIR/projection-no-regions-closure.rs:32:1
+   |
+32 | / fn no_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+33 | | where
+34 | |     T: Iterator,
+35 | | {
+...  |
+38 | |     //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+39 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:6 ~ projection_no_regions_closure[317d]::no_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-no-regions-closure.rs:42:1
+   |
+42 | / fn correct_region<'a, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+43 | | where
+44 | |     T: 'a + Iterator,
+45 | | {
+46 | |     with_signature(x, |mut y| Box::new(y.next()))
+47 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:7 ~ projection_no_regions_closure[317d]::correct_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: `<T as std::iter::Iterator>::Item` does not outlive `'_#6r`
+  --> $DIR/projection-no-regions-closure.rs:54:23
+   |
+54 |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: No external requirements
+  --> $DIR/projection-no-regions-closure.rs:50:1
+   |
+50 | / fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+51 | | where
+52 | |     T: 'b + Iterator,
+53 | | {
+...  |
+56 | |     //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+57 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ projection_no_regions_closure[317d]::wrong_region[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-no-regions-closure.rs:60:1
+   |
+60 | / fn outlives_region<'a, 'b, T>(x: Box<T>) -> Box<dyn Anything + 'a>
+61 | | where
+62 | |     T: 'b + Iterator,
+63 | |     'b: 'a,
+64 | | {
+65 | |     with_signature(x, |mut y| Box::new(y.next()))
+66 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ projection_no_regions_closure[317d]::outlives_region[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
new file mode 100644
index 00000000000..c815fdc1a0c
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
@@ -0,0 +1,53 @@
+// 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)]
+
+trait Anything { }
+
+impl<T> Anything for T { }
+
+fn no_region<'a, T>(mut x: T) -> Box<dyn Anything + 'a>
+where
+    T: Iterator,
+{
+    Box::new(x.next())
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+}
+
+fn correct_region<'a, T>(mut x: T) -> Box<dyn Anything + 'a>
+where
+    T: 'a + Iterator,
+{
+    Box::new(x.next())
+}
+
+fn wrong_region<'a, 'b, T>(mut x: T) -> Box<dyn Anything + 'a>
+where
+    T: 'b + Iterator,
+{
+    Box::new(x.next())
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
+}
+
+fn outlives_region<'a, 'b, T>(mut x: T) -> Box<dyn Anything + 'a>
+where
+    T: 'b + Iterator,
+    'b: 'a,
+{
+    Box::new(x.next())
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
new file mode 100644
index 00000000000..4d13972641c
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
@@ -0,0 +1,26 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-no-regions-fn.rs:24:5
+   |
+24 |     Box::new(x.next())
+   |     ^^^^^^^^^^^^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-no-regions-fn.rs:40:5
+   |
+40 |     Box::new(x.next())
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: `<T as std::iter::Iterator>::Item` does not outlive `'_#4r`
+  --> $DIR/projection-no-regions-fn.rs:24:5
+   |
+24 |     Box::new(x.next())
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: `<T as std::iter::Iterator>::Item` does not outlive `'_#5r`
+  --> $DIR/projection-no-regions-fn.rs:40:5
+   |
+40 |     Box::new(x.next())
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
new file mode 100644
index 00000000000..e2a2d20d77d
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
@@ -0,0 +1,106 @@
+// 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 cases where we constrain `<T as Anything<'b>>::AssocType` to
+// outlive `'a` and there are no bounds in the trait definition of
+// `Anything`. This means that the constraint can only be satisfied in two
+// ways:
+//
+// - by ensuring that `T: 'a` and `'b: 'a`, or
+// - by something in the where clauses.
+//
+// As of this writing, the where clause option does not work because
+// of limitations in our region inferencing system (this is true both
+// with and without NLL). See `projection_outlives`.
+//
+// Ensuring that both `T: 'a` and `'b: 'a` holds does work (`elements_outlive`).
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+trait Anything<'a> {
+    type AssocType;
+}
+
+fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F)
+where
+    F: FnOnce(Cell<&'a ()>, T),
+{
+    op(cell, t)
+}
+
+fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+}
+
+#[rustc_regions]
+fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `T` does not outlive
+    //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+}
+
+#[rustc_regions]
+fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    'a: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `T` does not outlive
+    //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+}
+
+#[rustc_regions]
+fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+    // This error is unfortunate. This code ought to type-check: we
+    // are projecting `<T as Anything<'b>>::AssocType`, and we know
+    // that this outlives `'a` because of the where-clause. However,
+    // the way the region checker works, we don't register this
+    // outlives obligation, and hence we get an error: this is because
+    // what we see is a projection like `<T as
+    // Anything<'?0>>::AssocType`, and we don't yet know if `?0` will
+    // equal `'b` or not, so we ignore the where-clause. Obviously we
+    // can do better here with a more involved verification step.
+
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `T` does not outlive
+    //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+}
+
+#[rustc_regions]
+fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    T: 'a,
+    'b: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
new file mode 100644
index 00000000000..cbd80d70bf9
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -0,0 +1,194 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-closure.rs:56:39
+   |
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-closure.rs:68:39
+   |
+68 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-closure.rs:90:39
+   |
+90 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+note: External requirements
+  --> $DIR/projection-one-region-closure.rs:56:29
+   |
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:19 ~ projection_one_region_closure[317d]::no_relationships_late[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: where '_#1r: '_#2r
+
+note: External requirements
+  --> $DIR/projection-one-region-closure.rs:68:29
+   |
+68 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_closure[317d]::no_relationships_early[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
+   = note: where '_#2r: '_#3r
+
+note: External requirements
+  --> $DIR/projection-one-region-closure.rs:90:29
+   |
+90 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_closure[317d]::projection_outlives[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
+   = note: where '_#2r: '_#3r
+
+note: External requirements
+   --> $DIR/projection-one-region-closure.rs:103:29
+    |
+103 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:31 ~ projection_one_region_closure[317d]::elements_outlive[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
+    = note: where '_#2r: '_#3r
+
+error: `T` does not outlive `'_#5r`
+  --> $DIR/projection-one-region-closure.rs:56:29
+   |
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+  --> $DIR/projection-one-region-closure.rs:56:20
+   |
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-closure.rs:52:1
+   |
+52 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+53 | | where
+54 | |     T: Anything<'b>,
+55 | | {
+...  |
+59 | |     //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+60 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: `T` does not outlive `'_#6r`
+  --> $DIR/projection-one-region-closure.rs:68:29
+   |
+68 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+  --> $DIR/projection-one-region-closure.rs:68:20
+   |
+68 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-closure.rs:63:1
+   |
+63 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+64 | | where
+65 | |     T: Anything<'b>,
+66 | |     'a: 'a,
+...  |
+71 | |     //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+72 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ projection_one_region_closure[317d]::no_relationships_early[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+error: `T` does not outlive `'_#6r`
+  --> $DIR/projection-one-region-closure.rs:90:29
+   |
+90 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+  --> $DIR/projection-one-region-closure.rs:90:20
+   |
+90 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-closure.rs:75:1
+   |
+75 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+76 | | where
+77 | |     T: Anything<'b>,
+78 | |     T::AssocType: 'a,
+...  |
+93 | |     //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+94 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:10 ~ projection_one_region_closure[317d]::projection_outlives[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+   --> $DIR/projection-one-region-closure.rs:97:1
+    |
+97  | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+98  | | where
+99  | |     T: Anything<'b>,
+100 | |     T: 'a,
+...   |
+103 | |     with_signature(cell, t, |cell, t| require(cell, t));
+104 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:11 ~ projection_one_region_closure[317d]::elements_outlive[0]) with substs [
+                '_#1r,
+                '_#2r,
+                T
+            ]
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
new file mode 100644
index 00000000000..e179927dfb0
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
@@ -0,0 +1,106 @@
+// 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 cases where we constrain `<T as Anything<'b>>::AssocType` to
+// outlive `'a` and there is a unique bound in the trait definition of
+// `Anything` -- i.e., we know that `AssocType` outlives `'b`. In this
+// case, the best way to satisfy the trait bound is to show that `'b:
+// 'a`, which can be done in various ways.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+trait Anything<'a> {
+    type AssocType: 'a;
+}
+
+fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F)
+where
+    F: FnOnce(Cell<&'a ()>, T),
+{
+    op(cell, t)
+}
+
+fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+}
+
+#[rustc_regions]
+fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+}
+
+#[rustc_regions]
+fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    'a: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+}
+
+#[rustc_regions]
+fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+    // This error is unfortunate. This code ought to type-check: we
+    // are projecting `<T as Anything<'b>>::AssocType`, and we know
+    // that this outlives `'a` because of the where-clause. However,
+    // the way the region checker works, we don't register this
+    // outlives obligation, and hence we get an error: this is because
+    // what we see is a projection like `<T as
+    // Anything<'?0>>::AssocType`, and we don't yet know if `?0` will
+    // equal `'b` or not, so we ignore the where-clause. Obviously we
+    // can do better here with a more involved verification step.
+
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+}
+
+#[rustc_regions]
+fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    'b: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'a>,
+{
+    // Note that in this case the closure still propagates an external
+    // requirement between two variables in its signature, but the
+    // creator maps both those two region variables to `'a` on its
+    // side.
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
new file mode 100644
index 00000000000..1088ae846fe
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -0,0 +1,204 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-trait-bound-closure.rs:48:39
+   |
+48 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-trait-bound-closure.rs:59:39
+   |
+59 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-one-region-trait-bound-closure.rs:80:39
+   |
+80 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:48:29
+   |
+48 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:19 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[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 '_#1r: '_#2r
+
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:59:29
+   |
+59 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[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 '_#2r: '_#3r
+
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:80:29
+   |
+80 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[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 '_#2r: '_#3r
+
+note: External requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:91:29
+   |
+91 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[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 '_#2r: '_#3r
+
+note: External requirements
+   --> $DIR/projection-one-region-trait-bound-closure.rs:103:29
+    |
+103 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_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 '_#1r: '_#2r
+
+error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+  --> $DIR/projection-one-region-trait-bound-closure.rs:48:20
+   |
+48 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:44:1
+   |
+44 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+45 | | where
+46 | |     T: Anything<'b>,
+47 | | {
+...  |
+50 | |     //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+51 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+  --> $DIR/projection-one-region-trait-bound-closure.rs:59:20
+   |
+59 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:54:1
+   |
+54 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+55 | | where
+56 | |     T: Anything<'b>,
+57 | |     'a: 'a,
+...  |
+61 | |     //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+62 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+  --> $DIR/projection-one-region-trait-bound-closure.rs:80:20
+   |
+80 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                    ^^^^
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:65:1
+   |
+65 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+66 | | where
+67 | |     T: Anything<'b>,
+68 | |     T::AssocType: 'a,
+...  |
+82 | |     //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
+83 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:10 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-closure.rs:86:1
+   |
+86 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+87 | | where
+88 | |     T: Anything<'b>,
+89 | |     'b: 'a,
+90 | | {
+91 | |     with_signature(cell, t, |cell, t| require(cell, t));
+92 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:11 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+   --> $DIR/projection-one-region-trait-bound-closure.rs:95:1
+    |
+95  | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+96  | | where
+97  | |     T: Anything<'a>,
+98  | | {
+...   |
+103 | |     with_signature(cell, t, |cell, t| require(cell, t));
+104 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:12 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]) with substs [
+                '_#1r,
+                T
+            ]
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
new file mode 100644
index 00000000000..67e28af1146
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
@@ -0,0 +1,99 @@
+// 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 cases where we constrain `<T as Anything<'b>>::AssocType` to
+// outlive `'static`. In this case, we don't get any errors, and in fact
+// we don't even propagate constraints from the closures to the callers.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// must-compile-successfully
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+trait Anything<'a> {
+    type AssocType: 'static;
+}
+
+fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F)
+where
+    F: FnOnce(Cell<&'a ()>, T),
+{
+    op(cell, t)
+}
+
+fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+}
+
+#[rustc_regions]
+fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    'a: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    T::AssocType: 'a,
+{
+    // This error is unfortunate. This code ought to type-check: we
+    // are projecting `<T as Anything<'b>>::AssocType`, and we know
+    // that this outlives `'a` because of the where-clause. However,
+    // the way the region checker works, we don't register this
+    // outlives obligation, and hence we get an error: this is because
+    // what we see is a projection like `<T as
+    // Anything<'?0>>::AssocType`, and we don't yet know if `?0` will
+    // equal `'b` or not, so we ignore the where-clause. Obviously we
+    // can do better here with a more involved verification step.
+
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b>,
+    'b: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'a>,
+{
+    // Note that in this case the closure still propagates an external
+    // requirement between two variables in its signature, but the
+    // creator maps both those two region variables to `'a` on its
+    // side.
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
new file mode 100644
index 00000000000..986676d28d9
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -0,0 +1,155 @@
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:47:29
+   |
+47 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:19 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29
+   |
+56 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29
+   |
+75 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29
+   |
+84 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29
+   |
+96 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1
+   |
+43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+44 | | where
+45 | |     T: Anything<'b>,
+46 | | {
+47 | |     with_signature(cell, t, |cell, t| require(cell, t));
+48 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:51:1
+   |
+51 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+52 | | where
+53 | |     T: Anything<'b>,
+54 | |     'a: 'a,
+55 | | {
+56 | |     with_signature(cell, t, |cell, t| require(cell, t));
+57 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:60:1
+   |
+60 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+61 | | where
+62 | |     T: Anything<'b>,
+63 | |     T::AssocType: 'a,
+...  |
+75 | |     with_signature(cell, t, |cell, t| require(cell, t));
+76 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:10 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:79:1
+   |
+79 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+80 | | where
+81 | |     T: Anything<'b>,
+82 | |     'b: 'a,
+83 | | {
+84 | |     with_signature(cell, t, |cell, t| require(cell, t));
+85 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:11 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-one-region-trait-bound-static-closure.rs:88:1
+   |
+88 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+89 | | where
+90 | |     T: Anything<'a>,
+91 | | {
+...  |
+96 | |     with_signature(cell, t, |cell, t| require(cell, t));
+97 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:12 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
new file mode 100644
index 00000000000..42bfdfcf9f9
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
@@ -0,0 +1,135 @@
+// 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 cases where we constrain `<T as Anything<'a, 'b>>::AssocType`
+// to outlive `'a` and there are two bounds in the trait definition of
+// `Anything` -- i.e., we know that `AssocType` outlives `'a` and
+// `'b`. In this case, it's not clear what is the best way to satisfy
+// the trait bound, and hence we propagate it to the caller as a type
+// test.
+
+// compile-flags:-Znll -Zborrowck=mir -Zverbose
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+trait Anything<'a, 'b> {
+    type AssocType: 'a + 'b;
+}
+
+fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F)
+where
+    F: FnOnce(Cell<&'a ()>, T),
+{
+    op(cell, t)
+}
+
+fn require<'a, 'b, 'c, T>(_cell: Cell<&'a ()>, _t: T)
+where
+    T: Anything<'b, 'c>,
+    T::AssocType: 'a,
+{
+}
+
+#[rustc_regions]
+fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'c>,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as Anything<'_#5r, '_#6r>>::AssocType` does not outlive `'_#7r`
+}
+
+#[rustc_regions]
+fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'c>,
+    'a: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+}
+
+#[rustc_regions]
+fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'c>,
+    T::AssocType: 'a,
+{
+    // This error is unfortunate. This code ought to type-check: we
+    // are projecting `<T as Anything<'b>>::AssocType`, and we know
+    // that this outlives `'a` because of the where-clause. However,
+    // the way the region checker works, we don't register this
+    // outlives obligation, and hence we get an error: this is because
+    // what we see is a projection like `<T as
+    // Anything<'?0>>::AssocType`, and we don't yet know if `?0` will
+    // equal `'b` or not, so we ignore the where-clause. Obviously we
+    // can do better here with a more involved verification step.
+
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+}
+
+#[rustc_regions]
+fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'c>,
+    'b: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'c>,
+    'c: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'b>,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+}
+
+#[rustc_regions]
+fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'b, 'b>,
+    'b: 'a,
+{
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+#[rustc_regions]
+fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+where
+    T: Anything<'a, 'a>,
+{
+    // Note that in this case the closure still propagates an external
+    // requirement between two variables in its signature, but the
+    // creator maps both those two region variables to `'a` on its
+    // side.
+    with_signature(cell, t, |cell, t| require(cell, t));
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
new file mode 100644
index 00000000000..5b708a0d7e6
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -0,0 +1,326 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-two-region-trait-bound-closure.rs:49:39
+   |
+49 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-two-region-trait-bound-closure.rs:60:39
+   |
+60 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/projection-two-region-trait-bound-closure.rs:81:39
+   |
+81 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                                       ^^^^^^^
+
+warning: not reporting region error due to -Znll
+   --> $DIR/projection-two-region-trait-bound-closure.rs:109:39
+    |
+109 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                                       ^^^^^^^
+
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:49:29
+   |
+49 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:22 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[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 as Anything<ReClosureBound('_#1r), ReClosureBound('_#2r)>>::AssocType: '_#3r
+
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:60:29
+   |
+60 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:81:29
+   |
+81 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
+note: External requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:92:29
+   |
+92 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T,
+               i32,
+               extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+           ]
+   = note: number of external vids: 5
+   = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:101:29
+    |
+101 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [
+                '_#1r,
+                '_#2r,
+                '_#3r,
+                T,
+                i32,
+                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
+            ]
+    = note: number of external vids: 5
+    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
+
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:109:29
+    |
+109 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[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 as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
+
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:120:29
+    |
+120 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[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 as Anything<ReClosureBound('_#2r), ReClosureBound('_#2r)>>::AssocType: '_#3r
+
+note: External requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:132:29
+    |
+132 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = note: defining type: DefId(0/1:53 ~ projection_two_region_trait_bound_closure[317d]::one_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 as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
+
+error: `<T as Anything<'_#5r, '_#6r>>::AssocType` does not outlive `'_#7r`
+  --> $DIR/projection-two-region-trait-bound-closure.rs:49:29
+   |
+49 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: No external requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:45:1
+   |
+45 | / fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+46 | | where
+47 | |     T: Anything<'b, 'c>,
+48 | | {
+...  |
+51 | |     //~| ERROR `<T as Anything<'_#5r, '_#6r>>::AssocType` does not outlive `'_#7r`
+52 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
+               '_#1r,
+               '_#2r,
+               T
+           ]
+
+error: `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+  --> $DIR/projection-two-region-trait-bound-closure.rs:60:29
+   |
+60 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: No external requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:55:1
+   |
+55 | / fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+56 | | where
+57 | |     T: Anything<'b, 'c>,
+58 | |     'a: 'a,
+...  |
+62 | |     //~| ERROR `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+63 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:9 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T
+           ]
+
+error: `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+  --> $DIR/projection-two-region-trait-bound-closure.rs:81:29
+   |
+81 |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: No external requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:66:1
+   |
+66 | / fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+67 | | where
+68 | |     T: Anything<'b, 'c>,
+69 | |     T::AssocType: 'a,
+...  |
+83 | |     //~| ERROR `<T as Anything<'_#6r, '_#7r>>::AssocType` does not outlive `'_#8r`
+84 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:10 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T
+           ]
+
+note: No external requirements
+  --> $DIR/projection-two-region-trait-bound-closure.rs:87:1
+   |
+87 | / fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+88 | | where
+89 | |     T: Anything<'b, 'c>,
+90 | |     'b: 'a,
+91 | | {
+92 | |     with_signature(cell, t, |cell, t| require(cell, t));
+93 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:11 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]) with substs [
+               '_#1r,
+               '_#2r,
+               '_#3r,
+               T
+           ]
+
+note: No external requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:96:1
+    |
+96  | / fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T)
+97  | | where
+98  | |     T: Anything<'b, 'c>,
+99  | |     'c: 'a,
+100 | | {
+101 | |     with_signature(cell, t, |cell, t| require(cell, t));
+102 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:12 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]) with substs [
+                '_#1r,
+                '_#2r,
+                '_#3r,
+                T
+            ]
+
+error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+   --> $DIR/projection-two-region-trait-bound-closure.rs:109:20
+    |
+109 |     with_signature(cell, t, |cell, t| require(cell, t));
+    |                    ^^^^
+
+note: No external requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:105:1
+    |
+105 | / fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+106 | | where
+107 | |     T: Anything<'b, 'b>,
+108 | | {
+...   |
+111 | |     //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r`
+112 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]) with substs [
+                '_#1r,
+                T
+            ]
+
+note: No external requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:115:1
+    |
+115 | / fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
+116 | | where
+117 | |     T: Anything<'b, 'b>,
+118 | |     'b: 'a,
+119 | | {
+120 | |     with_signature(cell, t, |cell, t| require(cell, t));
+121 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:14 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]) with substs [
+                '_#1r,
+                '_#2r,
+                T
+            ]
+
+note: No external requirements
+   --> $DIR/projection-two-region-trait-bound-closure.rs:124:1
+    |
+124 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T)
+125 | | where
+126 | |     T: Anything<'a, 'a>,
+127 | | {
+...   |
+132 | |     with_signature(cell, t, |cell, t| require(cell, t));
+133 | | }
+    | |_^
+    |
+    = note: defining type: DefId(0/0:15 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]) with substs [
+                '_#1r,
+                T
+            ]
+
+error: aborting due to 4 previous errors
+
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..14e2eb26976
--- /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 `T` does not outlive
+}
+
+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 `T` does not outlive
+}
+
+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..37ebc38da4d
--- /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: `T` does not outlive `'_#4r`
+  --> $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 `T` does not outlive
+40 | | }
+   | |_^
+   |
+   = note: defining type: DefId(0/0:5 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]) with substs [
+               '_#1r,
+               T
+           ]
+
+error: `T` does not outlive `'_#4r`
+  --> $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..beed1a740ea
--- /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 `T` does not outlive
+        //
+        // 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 `T` does not outlive
+        // 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..78445eb47c3
--- /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 `T` does not outlive
+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 `T` does not outlive
+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: `T` does not outlive `'_#3r`
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26
+   |
+38 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+39 | |         //~^ ERROR `T` does not outlive
+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 `T` does not outlive
+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: `T` does not outlive `'_#5r`
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
+   |
+76 |       with_signature(a, b, |x, y| {
+   |  __________________________^
+77 | |         //~^ ERROR `T` does not outlive
+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
+
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs b/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs
new file mode 100644
index 00000000000..a1e636cbc44
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs
@@ -0,0 +1,41 @@
+// 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
+
+// Test that we assume that universal types like `T` outlive the
+// function body.
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+
+use std::cell::Cell;
+
+// No errors here, because `'a` is local to the body.
+fn region_within_body<T>(t: T) {
+    let some_int = 22;
+    let cell = Cell::new(&some_int);
+    outlives(cell, t)
+}
+
+// Error here, because T: 'a is not satisfied.
+fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) {
+    outlives(cell, t)
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `T` does not outlive
+}
+
+fn outlives<'a, T>(x: Cell<&'a usize>, y: T)
+where
+    T: 'a,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
new file mode 100644
index 00000000000..bbe55c52b6e
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
@@ -0,0 +1,14 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-fn-body.rs:30:5
+   |
+30 |     outlives(cell, t)
+   |     ^^^^^^^^
+
+error: `T` does not outlive `'_#4r`
+  --> $DIR/ty-param-fn-body.rs:30:5
+   |
+30 |     outlives(cell, t)
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.rs b/src/test/ui/nll/ty-outlives/ty-param-fn.rs
new file mode 100644
index 00000000000..76783af4ceb
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn.rs
@@ -0,0 +1,51 @@
+// 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
+
+#![allow(warnings)]
+#![feature(dyn_trait)]
+
+use std::fmt::Debug;
+
+fn no_region<'a, T>(x: Box<T>) -> Box<Debug + 'a>
+where
+    T: Debug,
+{
+    x
+    //~^ WARNING not reporting region error due to -Znll
+    //~| ERROR `T` does not outlive
+}
+
+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 `T` does not outlive
+}
+
+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-fn.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
new file mode 100644
index 00000000000..02c4ebbd5ac
--- /dev/null
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
@@ -0,0 +1,26 @@
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-fn.rs:22:5
+   |
+22 |     x
+   |     ^
+
+warning: not reporting region error due to -Znll
+  --> $DIR/ty-param-fn.rs:38:5
+   |
+38 |     x
+   |     ^
+
+error: `T` does not outlive `'_#3r`
+  --> $DIR/ty-param-fn.rs:22:5
+   |
+22 |     x
+   |     ^
+
+error: `T` does not outlive `'_#4r`
+  --> $DIR/ty-param-fn.rs:38:5
+   |
+38 |     x
+   |     ^
+
+error: aborting due to 2 previous errors
+