-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
make member constraints pick static if no upper bounds
The current member constraint algorithm has a failure mode when it encounters a variable `'0` and the only constraint is that `':static: '0`. In that case, there are no upper bounds, or at least no non-trivial upper bounds. As a result, we are not able to rule out any of the choices, so if you have a constraint like `'0 member ['a, 'b, 'static]`, where `'a` and `'b` are unrelated, then the algorithm gets stuck as there is no 'least choice' from that set. The tweak in this commit changes the algorithm so that *if* there are no upper bounds (and hence `'0` can get as large as desired without creating a region check error), it will just pick `'static`. This should only occur in cases where the data is flowing out from a `'static` value. This change is probably *not* right for impl Trait in let bindings, but those are challenging with member constraints anyway, and not currently supported. Furthermore, this change is not needed in a polonius-like formulation, which effectively permits "ad-hoc intersections" of lifetimes as the value for a region, and hence could give a value like `'a ^ 'b` as the resulting lifetime. Therefore I think there isn't forwards compat danger here. (famous last words?)
- Loading branch information
1 parent
207d955
commit b893cff
Showing
4 changed files
with
99 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/test/ui/async-await/multiple-lifetimes/two-refs-and-a-dyn.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Regression test for #63033. The scenario here is: | ||
// | ||
// - The returned future captures the `Box<dyn T>`, which is shorthand for `Box<dyn T + 'static>`. | ||
// - The actual value that gets captured is `Box<dyn T + '?0>` where `'static: '?0` | ||
// - We generate a member constraint `'?0 member ['a, 'b, 'static]` | ||
// - None of those regions are a "least choice", so we got stuck | ||
// | ||
// After the fix, we now select `'static` in cases where there are no upper bounds (apart from | ||
// 'static). | ||
// | ||
// edition:2018 | ||
// check-pass | ||
|
||
#![allow(dead_code)] | ||
trait T {} | ||
struct S; | ||
impl S { | ||
async fn f<'a, 'b>(_a: &'a S, _b: &'b S, _c: Box<dyn T>) {} | ||
} | ||
fn main() {} |
16 changes: 16 additions & 0 deletions
16
src/test/ui/async-await/multiple-lifetimes/two-refs-and-a-static.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Regression test for #63033. The scenario here is: | ||
// | ||
// - The returned future captures the &'static String` | ||
// - The actual value that gets captured is `&'?0 String` where `'static: '?0` | ||
// - We generate a member constraint `'?0 member ['a, 'b, 'static]` | ||
// - None of those regions are a "least choice", so we got stuck | ||
// | ||
// After the fix, we now select `'static` in cases where there are no upper bounds (apart from | ||
// 'static). | ||
// | ||
// edition:2018 | ||
// check-pass | ||
|
||
async fn test<'a, 'b>(test: &'a String, test2: &'b String, test3: &'static String) {} | ||
|
||
fn main() {} |