make blame_span deterministic

This commit is contained in:
Niko Matsakis 2017-12-06 05:50:49 -05:00
parent a118afe7ca
commit 0d6bd42abb
11 changed files with 70 additions and 51 deletions

View File

@ -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;
}
}
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);
bug!(
"could not find any constraint to blame for {:?}: {:?}",
fr1,
fr2
);
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
)
}
})
}

View 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() {}

View 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() {}

View 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() {}

View 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`
},
);
}

View 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 | | },
| |_________^
|

View 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

View 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

View 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

View File

@ -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
});
}

View 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 [