mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
improve heuristics for what makes an interesting constraint
This commit is contained in:
parent
76991ea237
commit
0d918a8575
@ -104,7 +104,48 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
categorized_path
|
||||
);
|
||||
|
||||
// Find what appears to be the most interesting path to report to the user.
|
||||
// To find the best span to cite, we first try to look for the
|
||||
// final constraint that is interesting and where the `sup` is
|
||||
// not unified with the ultimate target region. The reason
|
||||
// for this is that we have a chain of constraints that lead
|
||||
// from the source to the target region, something like:
|
||||
//
|
||||
// '0: '1 ('0 is the source)
|
||||
// '1: '2
|
||||
// '2: '3
|
||||
// '3: '4
|
||||
// '4: '5
|
||||
// '5: '6 ('6 is the target)
|
||||
//
|
||||
// Some of those regions are unified with `'6` (in the same
|
||||
// SCC). We want to screen those out. After that point, the
|
||||
// "closest" constraint we have to the end is going to be the
|
||||
// most likely to be the point where the value escapes -- but
|
||||
// we still want to screen for an "interesting" point to
|
||||
// highlight (e.g., a call site or something).
|
||||
let target_scc = self.constraint_sccs.scc(target_region);
|
||||
let best_choice = (0..path.len()).rev().find(|&i| {
|
||||
let constraint = &self.constraints[path[i]];
|
||||
|
||||
let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
|
||||
if constraint_sup_scc == target_scc {
|
||||
return false;
|
||||
}
|
||||
|
||||
match categorized_path[i].0 {
|
||||
ConstraintCategory::Boring => false,
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
if let Some(i) = best_choice {
|
||||
let (category, span) = categorized_path[i];
|
||||
return (category, span, target_region);
|
||||
}
|
||||
|
||||
// If that search fails, that is.. unusual. Maybe everything
|
||||
// is in the same SCC or something. In that case, find what
|
||||
// appears to be the most interesting point to report to the
|
||||
// user via an even more ad-hoc guess.
|
||||
categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
|
||||
debug!("best_blame_constraint: sorted_path={:#?}", categorized_path);
|
||||
|
||||
|
@ -10,19 +10,21 @@ warning: not reporting region error due to nll
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/static-return-lifetime-infered.rs:17:9
|
||||
|
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
| ----- `self` is a reference that is only valid in the closure body
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^^^ cast requires that `'1` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/static-return-lifetime-infered.rs:21:9
|
||||
|
|
||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||
| -------- `self` is a reference that is only valid in the closure body
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^^^ cast requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -35,22 +35,22 @@ LL | let mut out = Struct { head: x, _tail: [()] };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `y`
|
||||
--> $DIR/issue-40288-2.rs:16:31
|
||||
--> $DIR/issue-40288-2.rs:17:9
|
||||
|
|
||||
LL | fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
|
||||
| - consider changing the type of `y` to `&'a T`
|
||||
...
|
||||
LL | let slice: &mut [_] = &mut out;
|
||||
| ^^^^^^^^ lifetime `'a` required
|
||||
LL | slice[0] = y;
|
||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `y`
|
||||
--> $DIR/issue-40288-2.rs:31:41
|
||||
--> $DIR/issue-40288-2.rs:32:9
|
||||
|
|
||||
LL | fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
|
||||
| - consider changing the type of `y` to `&'a T`
|
||||
...
|
||||
LL | let dst: &mut Struct<_, [()]> = &mut out;
|
||||
| ^^^^^^^^ lifetime `'a` required
|
||||
LL | dst.head = y;
|
||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -11,20 +11,20 @@ LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
||||
| ^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:11:33
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:12:5
|
||||
|
|
||||
LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||
| --- ^ --- these two types are declared with different lifetimes...
|
||||
| |
|
||||
| ...but data flows into `z` here
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
||||
| ^^^^^^^^^^^^^ ...but data flows into `z` here
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:11:36
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:12:5
|
||||
|
|
||||
LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||
| --- ^ --- these two types are declared with different lifetimes...
|
||||
| |
|
||||
| ...but data flows into `z` here
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
||||
| ^^^^^^^^^^^^^ ...but data flows into `z` here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -52,9 +52,9 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
|
||||
cell_c,
|
||||
|_outlives1, _outlives2, _outlives3, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
let p = x.get(); //~ ERROR
|
||||
let p = x.get();
|
||||
//~^ WARN not reporting region error due to nll
|
||||
demand_y(x, y, p)
|
||||
demand_y(x, y, p) //~ ERROR
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
warning: not reporting region error due to nll
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
|
||||
|
|
||||
LL | let p = x.get(); //~ ERROR
|
||||
LL | let p = x.get();
|
||||
| ^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
|
||||
|
|
||||
LL | |_outlives1, _outlives2, _outlives3, x, y| {
|
||||
| ---------- ---------- lifetime `'2` appears in this argument
|
||||
| |
|
||||
| lifetime `'1` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | let p = x.get(); //~ ERROR
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
...
|
||||
LL | demand_y(x, y, p) //~ ERROR
|
||||
| ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
|
||||
|
|
||||
LL | / |_outlives1, _outlives2, _outlives3, x, y| {
|
||||
LL | | // Only works if 'x: 'y:
|
||||
LL | | let p = x.get(); //~ ERROR
|
||||
LL | | let p = x.get();
|
||||
LL | | //~^ WARN not reporting region error due to nll
|
||||
LL | | demand_y(x, y, p)
|
||||
LL | | demand_y(x, y, p) //~ ERROR
|
||||
LL | | },
|
||||
| |_________^
|
||||
|
|
||||
|
@ -5,7 +5,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
||||
| ^^^
|
||||
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
|
||||
|
|
||||
LL | foo(cell, |cell_a, cell_x| {
|
||||
| ------ ------ `cell_x` is a reference that is only valid in the closure body
|
||||
@ -13,7 +13,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
||||
| `cell_a` is declared here, outside of the closure body
|
||||
LL | //~^ WARNING not reporting region error due to nll
|
||||
LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
|
||||
| ^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
|
||||
|
@ -5,7 +5,7 @@ LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:24
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
|
||||
|
|
||||
LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
| --------- - lifetime `'1` appears in this argument
|
||||
@ -13,7 +13,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
| lifetime `'2` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
|
||||
|
@ -5,7 +5,7 @@ LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:24
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
|
||||
|
|
||||
LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
| ---------- ---------- lifetime `'2` appears in this argument
|
||||
@ -13,7 +13,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
||||
| lifetime `'1` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
|
||||
|
@ -23,13 +23,16 @@ LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/dyn-trait-underscore.rs:18:5
|
||||
--> $DIR/dyn-trait-underscore.rs:16:52
|
||||
|
|
||||
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
||||
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
||||
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||
| ________________-___________________________________^
|
||||
| | |
|
||||
| | let's call the lifetime of this reference `'1`
|
||||
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
||||
LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||
LL | | }
|
||||
| |_^ return requires that `'1` must outlive `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user