-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Account for 'duplicate' closure regions in borrowck diagnostics
Fixes #67765 When we process closures/generators, we create a new NLL inference variable each time we encounter an early-bound region (e.g. "'a") in the substs of the closure. These region variables are then treated as universal regions when the perform region inference for the closure. However, we may encounter the same region multiple times, such as when the closure references multiple upvars that are bound by the same early-bound lifetime. For example: `fn foo<'a>(x: &'a u8, y: &'a u8) -> u8 { (|| *x + *y)() }` This results in the creation of multiple 'duplicate' region variables, which all correspond to the same early-bound region. During type-checking of the closure, we don't really care - any constraints involving these regions will get propagated back up to the enclosing function, which is then responsible for checking said constraints using the 'real' regions. Unfortunately, this presents a problem for diagnostic code, which may run in the context of the closure. In order to display a good error message, we need to map arbitrary region inference variables (which may not correspond to anything meaningful to the user) into a 'nicer' region variable that can be displayed to the user (e.g. a universally bound region, written by the user). To accomplish this, we repeatedly compute an 'upper bound' of the region variable, stopping once we hit a universally bound region, or are unable to make progress. During the processing of a closure, we may determine that a region variable needs to outlive mutliple universal regions. In a closure context, some of these universal regions may actually be 'the same' region - that is, they correspond to the same early-bound region. If this is the case, we will end up trying to compute an upper bound using these regions variables, which will fail (we don't know about any relationship between them). However, we don't actually need to find an upper bound involving these duplicate regions - since they're all actually "the same" region, we can just pick an arbirary region variable from a given "duplicate set" (all region variables that correspond to a given early-bound region). By doing so, we can generate a more precise diagnostic, since we will be able to print a message involving a particular early-bound region (and the variables using it), instead of falling back to a more generic error message.
- Loading branch information
Showing
7 changed files
with
150 additions
and
22 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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// edition:2018 | ||
|
||
fn main() {} | ||
|
||
async fn func<'a>() -> Result<(), &'a str> { | ||
let s = String::new(); | ||
|
||
let b = &s[..]; | ||
|
||
Err(b)?; //~ ERROR cannot return value referencing local variable `s` | ||
|
||
Ok(()) | ||
} |
12 changes: 12 additions & 0 deletions
12
src/test/ui/async-await/issue-67765-async-diagnostic.stderr
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,12 @@ | ||
error[E0515]: cannot return value referencing local variable `s` | ||
--> $DIR/issue-67765-async-diagnostic.rs:10:11 | ||
| | ||
LL | let b = &s[..]; | ||
| - `s` is borrowed here | ||
LL | | ||
LL | Err(b)?; | ||
| ^ returns a value referencing data owned by the current function | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0515`. |