Rollup merge of #73806 - Aaron1011:feature/approx-universal-upper, r=estebank

Use an 'approximate' universal upper bound when reporting region errors

Fixes #67765

When reporting errors during MIR region inference, we sometimes use
`universal_upper_bound` to obtain a named universal region that we
can display to the user. However, this is not always possible - in a
case like `fn foo<'a, 'b>() { .. }`, the only upper bound for a region
containing `'a` and `'b` is `'static`. When displaying diagnostics, it's
usually better to display *some* named region (even if there are
multiple involved) rather than fall back to a generic error involving
`'static`.

This commit adds a new `approx_universal_upper_bound` method, which
uses the lowest-numbered universal region if the only alternative is to
return `'static`.
This commit is contained in:
Manish Goregaokar 2020-07-01 07:42:56 -07:00 committed by GitHub
commit f213957c2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 12 deletions

View file

@ -0,0 +1,16 @@
// edition:2018
//
// Regression test for issue #67765
// Tests that we point at the proper location when giving
// a lifetime error.
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(())
}

View file

@ -0,0 +1,12 @@
error[E0515]: cannot return value referencing local variable `s`
--> $DIR/issue-67765-async-diagnostic.rs:13: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`.

View file

@ -1,3 +1,3 @@
fn main() {
[0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR `a` does not live long enough
[0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR closure may outlive
}

View file

@ -1,15 +1,21 @@
error[E0597]: `a` does not live long enough
--> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:49
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
--> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:44
|
LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a));
| - ^- ...but `a` will be dropped here, when the enclosing closure returns
| | |
| | `a` would have to be valid for `'_`...
| has type `&i32`
| ^^^ - `a` is borrowed here
| |
| may outlive borrowed value `a`
|
= note: functions cannot return a borrow to data owned within the function's scope, functions can only return borrows to data passed as arguments
= note: to learn more, visit <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references>
note: closure is returned here
--> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:29
|
LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a));
| ^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
LL | [0].iter().flat_map(|a| [0].iter().map(move |_| &a));
| ^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0373`.

View file

@ -0,0 +1,7 @@
// See https://github.com/rust-lang/rust/pull/67911#issuecomment-576023915
fn f<'a, 'b>(x: i32) -> (&'a i32, &'b i32) {
let y = &x;
(y, y) //~ ERROR cannot return
}
fn main() {}

View file

@ -0,0 +1,11 @@
error[E0515]: cannot return value referencing function parameter `x`
--> $DIR/return-disjoint-regions.rs:4:5
|
LL | let y = &x;
| -- `x` is borrowed here
LL | (y, y)
| ^^^^^^ 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`.