]> git.lizzy.rs Git - rust.git/commitdiff
make `blame_span` deterministic
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 6 Dec 2017 10:50:49 +0000 (05:50 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 15 Dec 2017 15:27:54 +0000 (10:27 -0500)
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/test/compile-fail/mir_check_cast_closure.rs
src/test/compile-fail/mir_check_cast_reify.rs
src/test/compile-fail/mir_check_cast_unsafe_fn.rs
src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr

index f03e8bd7ac152593805c93f18dcac49dee93883f..9a3076c0c32b7b61e28a61e3895de46bd600aa24 100644 (file)
@@ -872,35 +872,50 @@ fn blame_span(&self, fr1: RegionVid, fr2: RegionVid) -> Span {
         // 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 @@ fn subst_closure_mapping<T>(
         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
+                )
             }
         })
     }
index be0d4b1374185d98f6656a69e966c6cf183a285f..6562efeb6d893a628b9ad646a2f001ccad2c21b2 100644 (file)
@@ -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() {}
index 091e0b71b2dc3ecbc6bf0d7781a3fe22ac17af90..1736aea2d6de7604aad69d92284f174b46df9b90 100644 (file)
@@ -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() {}
index 701a7c6b056a6245961062f4e9e4e292bc6ede52..39eafa10040264f3cdd40fab10b2534085b0c7e8 100644 (file)
@@ -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() {}
index c2f071cc029e6898731aacf62844533ea28d3ab9..50d7877de50d7be23e3cb9b9692fafd0f30ccb17 100644 (file)
@@ -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`
         },
     );
 }
index cdda8ab5392bdedd13cd07dd07fa028248e5f0db..f90bc7c175a96ba2810d114eb42759770a056938 100644 (file)
@@ -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 | |         },
    | |_________^
    |
index 717cf481a01d193d1d4343161e6ed5389d80d070..4bae29ad32617128cbfa4b435b72266b83e8aef1 100644 (file)
@@ -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
index e8dc8a13f876bc44d5f7ed22d4d781ea85d01d5a..502b344c89e448b2efcbb48fd689fd2eef8f8bc1 100644 (file)
@@ -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
index 43464bfb2b9a7213dac8d1d994a0b38a57f2c28b..43d61fdf1b5f820bab8cf588d855a3b741715f7b 100644 (file)
@@ -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
index d5bd4b60118fcaffa9689319c155444c767c8505..a5be2b43f04bc02d6cdf125076df3258150611f9 100644 (file)
@@ -40,6 +40,8 @@ fn supply<'a, T>(value: T)
     T: Trait<'a>,
 {
     establish_relationships(value, |value| {
+        //~^ ERROR failed type test
+
         // This function call requires that
         //
         // (a) T: Trait<'a>
@@ -52,7 +54,6 @@ fn supply<'a, T>(value: T)
 
         require(value);
         //~^ WARNING not reporting region error due to -Znll
-        //~| ERROR failed type test
     });
 }
 
index eb415ec8d1ae4a02f1f4532acf6d7d2ef9de1f99..e81c45ef7eda112702dbe6488471cf0d50b7b0f3 100644 (file)
@@ -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 [