about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs60
-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/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr30
11 files changed, 71 insertions, 52 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index f03e8bd7ac1..9a3076c0c32 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -872,35 +872,50 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // be obvious to the user -- not to mention the naive notion
         // of dependencies, which doesn't account for the locations of
         // contraints at all. But it will do for now.
-        for constraint in &self.constraints {
-            if constraint.sub == fr2 && influenced_fr1[constraint.sup] {
-                return constraint.span;
-            }
-        }
-
-        bug!(
-            "could not find any constraint to blame for {:?}: {:?}",
-            fr1,
-            fr2
-        );
+        let relevant_constraint = self.constraints
+                .iter()
+                .filter_map(|constraint| {
+                    if constraint.sub != fr2 {
+                        None
+                    } else {
+                        influenced_fr1[constraint.sup]
+                            .map(|distance| (distance, constraint.span))
+                    }
+                })
+                .min() // constraining fr1 with fewer hops *ought* to be more obvious
+                .map(|(_dist, span)| span);
+
+        relevant_constraint.unwrap_or_else(|| {
+            bug!(
+                "could not find any constraint to blame for {:?}: {:?}",
+                fr1,
+                fr2
+            );
+        })
     }
 
     /// Finds all regions whose values `'a` may depend on in some way.
-    /// Basically if there exists a constraint `'a: 'b @ P`, then `'b`
-    /// and `dependencies('b)` will be in the final set.
+    /// For each region, returns either `None` (does not influence
+    /// `'a`) or `Some(d)` which indicates that it influences `'a`
+    /// with distinct `d` (minimum number of edges that must be
+    /// traversed).
     ///
     /// Used during error reporting, extremely naive and inefficient.
-    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, bool> {
-        let mut result_set = IndexVec::from_elem(false, &self.definitions);
+    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, Option<usize>> {
+        let mut result_set = IndexVec::from_elem(None, &self.definitions);
         let mut changed = true;
-        result_set[r0] = true;
+        result_set[r0] = Some(0); // distance 0 from `r0`
 
         while changed {
             changed = false;
             for constraint in &self.constraints {
-                if result_set[constraint.sup] {
-                    if !result_set[constraint.sub] {
-                        result_set[constraint.sub] = true;
+                if let Some(n) = result_set[constraint.sup] {
+                    let m = n + 1;
+                    if result_set[constraint.sub]
+                        .map(|distance| m < distance)
+                        .unwrap_or(true)
+                    {
+                        result_set[constraint.sub] = Some(m);
                         changed = true;
                     }
                 }
@@ -1049,13 +1064,16 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
         value: &T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>
+        T: TypeFoldable<'tcx>,
     {
         infcx.tcx.fold_regions(value, &mut false, |r, _depth| {
             if let ty::ReClosureBound(vid) = r {
                 closure_mapping[*vid]
             } else {
-                bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r)
+                bug!(
+                    "subst_closure_mapping: encountered non-closure bound free region {:?}",
+                    r
+                )
             }
         })
     }
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/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 cdda8ab5392..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,10 +5,10 @@ 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: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
@@ -17,8 +17,8 @@ note: No external requirements
 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 | |         },
    | |_________^
    |
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-to-empty.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
index e8dc8a13f87..502b344c89e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
@@ -5,10 +5,10 @@ warning: not reporting region error due to -Znll
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: free region `'_#6r` does not outlive free region `'_#4r`
-  --> $DIR/propagate-approximated-to-empty.rs:41:21
+  --> $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
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-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
index d5bd4b60118..a5be2b43f04 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
@@ -40,6 +40,8 @@ where
     T: Trait<'a>,
 {
     establish_relationships(value, |value| {
+        //~^ ERROR failed type test
+
         // This function call requires that
         //
         // (a) T: Trait<'a>
@@ -52,7 +54,6 @@ where
 
         require(value);
         //~^ WARNING not reporting region error due to -Znll
-        //~| ERROR failed type test
     });
 }
 
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
index eb415ec8d1a..e81c45ef7ed 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -1,7 +1,7 @@
 warning: not reporting region error due to -Znll
-  --> $DIR/propagate-from-trait-match.rs:53:9
+  --> $DIR/propagate-from-trait-match.rs:55:9
    |
-53 |         require(value);
+55 |         require(value);
    |         ^^^^^^^
 
 note: External requirements
@@ -9,12 +9,12 @@ note: External requirements
    |
 42 |       establish_relationships(value, |value| {
    |  ____________________________________^
-43 | |         // This function call requires that
-44 | |         //
-45 | |         // (a) T: Trait<'a>
+43 | |         //~^ ERROR failed type test
+44 | |
+45 | |         // This function call requires that
 ...  |
-55 | |         //~| ERROR failed type test
-56 | |     });
+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 [
@@ -26,17 +26,17 @@ note: External requirements
    = note: number of external vids: 2
    = note: where T: '_#1r
 
-error: failed type test: TypeTest { generic_kind: T/#1, lower_bound: '_#3r, point: bb0[3], span: $DIR/propagate-from-trait-match.rs:42:36: 56:6, test: IsOutlivedByAnyRegionIn(['_#2r]) }
+error: failed type test: TypeTest { generic_kind: T/#1, lower_bound: '_#3r, point: bb0[3], span: $DIR/propagate-from-trait-match.rs:42:36: 57:6, test: IsOutlivedByAnyRegionIn(['_#2r]) }
   --> $DIR/propagate-from-trait-match.rs:42:36
    |
 42 |       establish_relationships(value, |value| {
    |  ____________________________________^
-43 | |         // This function call requires that
-44 | |         //
-45 | |         // (a) T: Trait<'a>
+43 | |         //~^ ERROR failed type test
+44 | |
+45 | |         // This function call requires that
 ...  |
-55 | |         //~| ERROR failed type test
-56 | |     });
+56 | |         //~^ WARNING not reporting region error due to -Znll
+57 | |     });
    | |_____^
 
 note: No external requirements
@@ -47,8 +47,8 @@ note: No external requirements
 40 | |     T: Trait<'a>,
 41 | | {
 ...  |
-56 | |     });
-57 | | }
+57 | |     });
+58 | | }
    | |_^
    |
    = note: defining type: DefId(0/0:6 ~ propagate_from_trait_match[317d]::supply[0]) with substs [