Skip to content

Commit bcc0a9c

Browse files
committed
modify leak-check to track only outgoing edges from placeholders
Also, update the affected tests. This seems strictly better but it is actually more permissive than I initially intended. In particular it accepts this ``` forall<'a, 'b> { exists<'intersection> { 'a: 'intersection, 'b: 'intersection, } } ``` and I'm not sure I want to accept that. It implies that we have a `'empty` in the new universe intoduced by the `forall`.
1 parent 1a4e2b6 commit bcc0a9c

30 files changed

+219
-201
lines changed

src/librustc_infer/infer/region_constraints/leak_check.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,23 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
4242
_ => bug!("leak_check: expected placeholder found {:?}", placeholder_region,),
4343
};
4444

45-
// Find all regions that are related to this placeholder
46-
// in some way. This means any region that either outlives
47-
// or is outlived by a placeholder.
48-
let mut taint_set = TaintSet::new(TaintDirections::both(), placeholder_region);
45+
// Find all regions that this placeholder `!p` must outlive -- i.e.,
46+
// any region `r` where `!p: r` must hold. It is an error if any
47+
// such region `r` is another placeholder or in a universe that
48+
// can't see the placeholder. (This is actually incorrect, because
49+
// we don't take into account the possibility of bounds in
50+
// environment that tell us that the placeholder may be related to
51+
// other regions).
52+
//
53+
// Note that we *don't* look for cases like `r: !p`. This is
54+
// because:
55+
//
56+
// * If `r` is some other placeholder `!p1`, then we'll find the
57+
// error when we search the regions that `!p1` must outlive.
58+
// * If `r` is a variable in some outer universe, then it can
59+
// potentially be assigned to `'static`, so this relation could
60+
// hold.
61+
let mut taint_set = TaintSet::new(TaintDirections::outgoing(), placeholder_region);
4962
taint_set.fixed_point(
5063
tcx,
5164
self.undo_log.region_constraints(),

src/test/ui/closure-expected-type/expect-fn-supply-fn.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ fn expect_free_supply_bound() {
2828
// Here, we are given a function whose region is bound at closure level,
2929
// but we expect one bound in the argument. Error results.
3030
with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
31-
//~^ ERROR type mismatch
31+
//~^ ERROR mismatched types
3232
}
3333

3434
fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
3535
// Here, we are given a `fn(&u32)` but we expect a `fn(&'x
3636
// u32)`. In principle, this could be ok, but we demand equality.
3737
with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
38-
//~^ ERROR type mismatch
38+
//~^ ERROR mismatched types
3939
}
4040

4141
fn expect_bound_supply_free_from_closure() {
@@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() {
4444
// the argument level.
4545
type Foo<'a> = fn(&'a u32);
4646
with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
47-
//~^ ERROR type mismatch
47+
//~^ ERROR mismatched types
4848
});
4949
}
5050

src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,46 +36,33 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the b
3636
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
3737
| ^^^^^^^^^^^^^^^^^^^^^^
3838

39-
error[E0631]: type mismatch in closure arguments
40-
--> $DIR/expect-fn-supply-fn.rs:30:5
39+
error[E0308]: mismatched types
40+
--> $DIR/expect-fn-supply-fn.rs:30:52
4141
|
42-
LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
43-
| ------------------------------------------ required by a bound in this
44-
LL | where F: for<'a> FnOnce(fn(&'a u32), &i32)
45-
| ------------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
46-
...
4742
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
48-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
49-
| |
50-
| expected signature of `fn(fn(&'a u32), &i32) -> _`
43+
| ^^^^^^^^ one type is more general than the other
44+
|
45+
= note: expected fn pointer `fn(&u32)`
46+
found fn pointer `for<'r> fn(&'r u32)`
5147

52-
error[E0631]: type mismatch in closure arguments
53-
--> $DIR/expect-fn-supply-fn.rs:37:5
48+
error[E0308]: mismatched types
49+
--> $DIR/expect-fn-supply-fn.rs:37:53
5450
|
55-
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
56-
| ------------------------------------------- required by a bound in this
57-
LL | where F: FnOnce(fn(&u32), &i32)
58-
| ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
59-
...
6051
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
62-
| |
63-
| expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
52+
| ^^^^^^^^^^^ one type is more general than the other
53+
|
54+
= note: expected fn pointer `for<'r> fn(&'r u32)`
55+
found fn pointer `fn(&'x u32)`
6456

65-
error[E0631]: type mismatch in closure arguments
66-
--> $DIR/expect-fn-supply-fn.rs:46:5
57+
error[E0308]: mismatched types
58+
--> $DIR/expect-fn-supply-fn.rs:46:53
6759
|
68-
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
69-
| ------------------------------------------- required by a bound in this
70-
LL | where F: FnOnce(fn(&u32), &i32)
71-
| ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
72-
...
7360
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
74-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
75-
| |
76-
| expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
61+
| ^^^^^^^ one type is more general than the other
62+
|
63+
= note: expected fn pointer `for<'r> fn(&'r u32)`
64+
found fn pointer `fn(&u32)`
7765

7866
error: aborting due to 5 previous errors
7967

80-
Some errors have detailed explanations: E0308, E0631.
81-
For more information about an error, try `rustc --explain E0308`.
68+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/hr-subtype.rs:39:26
1+
error: fatal error triggered by #[rustc_error]
2+
--> $DIR/hr-subtype.rs:96:1
33
|
4-
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
6-
...
7-
LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
8-
LL | | for<'a> fn(&'a u32, &'a u32)) }
9-
| |__________________________________________________________________- in this macro invocation
10-
|
11-
= note: expected enum `std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32)>`
12-
found enum `std::option::Option<for<'a> fn(&'a u32, &'a u32)>`
13-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
4+
LL | / fn main() {
5+
LL | |
6+
LL | |
7+
LL | |
8+
... |
9+
LL | |
10+
LL | | }
11+
| |_^
1412

1513
error: aborting due to previous error
1614

17-
For more information about this error, try `rustc --explain E0308`.

src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: fatal error triggered by #[rustc_error]
2-
--> $DIR/hr-subtype.rs:100:1
2+
--> $DIR/hr-subtype.rs:96:1
33
|
44
LL | / fn main() {
55
LL | |
66
LL | |
77
LL | |
8-
LL | |
8+
... |
99
LL | |
1010
LL | | }
1111
| |_^

src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: fatal error triggered by #[rustc_error]
2-
--> $DIR/hr-subtype.rs:100:1
2+
--> $DIR/hr-subtype.rs:96:1
33
|
44
LL | / fn main() {
55
LL | |
66
LL | |
77
LL | |
8-
LL | |
8+
... |
99
LL | |
1010
LL | | }
1111
| |_^

src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
22
--> $DIR/hr-subtype.rs:39:26
33
|
44
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
5+
| ^^^^^^^^^^^ one type is more general than the other
66
...
77
LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
88
LL | | fn(&'x u32)) }
Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/hr-subtype.rs:39:26
1+
error: fatal error triggered by #[rustc_error]
2+
--> $DIR/hr-subtype.rs:96:1
33
|
4-
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
6-
...
7-
LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
8-
LL | | for<'a> fn(Co<'a>, Co<'a>)) }
9-
| |______________________________________________________________________- in this macro invocation
10-
|
11-
= note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>)>`
12-
found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>)>`
13-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
4+
LL | / fn main() {
5+
LL | |
6+
LL | |
7+
LL | |
8+
... |
9+
LL | |
10+
LL | | }
11+
| |_^
1412

1513
error: aborting due to previous error
1614

17-
For more information about this error, try `rustc --explain E0308`.
Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/hr-subtype.rs:39:26
1+
error: fatal error triggered by #[rustc_error]
2+
--> $DIR/hr-subtype.rs:96:1
33
|
4-
LL | gimme::<$t1>(None::<$t2>);
5-
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
6-
...
7-
LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>,
8-
LL | | for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) }
9-
| |______________________________________________________________________________________- in this macro invocation
10-
|
11-
= note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>) -> Contra<'a>>`
12-
found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>>`
13-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
4+
LL | / fn main() {
5+
LL | |
6+
LL | |
7+
LL | |
8+
... |
9+
LL | |
10+
LL | | }
11+
| |_^
1412

1513
error: aborting due to previous error
1614

17-
For more information about this error, try `rustc --explain E0308`.

src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: fatal error triggered by #[rustc_error]
2-
--> $DIR/hr-subtype.rs:100:1
2+
--> $DIR/hr-subtype.rs:96:1
33
|
44
LL | / fn main() {
55
LL | |
66
LL | |
77
LL | |
8-
LL | |
8+
... |
99
LL | |
1010
LL | | }
1111
| |_^

0 commit comments

Comments
 (0)