Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer regions with an external_name in approx_universal_upper_bound #78164

Merged
merged 1 commit into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub);
// The upper bound of two non-static regions is static: this
// means we know nothing about the relationship between these
// two regions. Pick a 'better' one to use when constructing
// a diagnostic
if ur != static_r && lub != static_r && new_lub == static_r {
lub = std::cmp::min(ur, lub);
// Prefer the region with an `external_name` - this
// indicates that the region is early-bound, so working with
// it can produce a nicer error.
if self.region_definition(ur).external_name.is_some() {
lub = ur;
} else if self.region_definition(lub).external_name.is_some() {
// Leave lub unchanged
} else {
// If we get here, we don't have any reason to prefer
// one region over the other. Just pick the
// one with the lower index for now.
lub = std::cmp::min(ur, lub);
}
} else {
lub = new_lub;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
--> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
|
LL | pub async fn async_fn(x: &mut i32) -> &i32 {
| - let's call the lifetime of this reference `'1`
| - let's call the lifetime of this reference `'1`
LL | let y = &*x;
| --- borrow of `*x` occurs here
LL | *x += 1;
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/async-await/issue-75785-confusing-named-region.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// edition:2018
//
// Regression test for issue #75785
// Tests that we don't point to a confusing named
// region when emitting a diagnostic

pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
let y = &*x;
*x += 1; //~ ERROR cannot assign to
(&32, y)
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/async-await/issue-75785-confusing-named-region.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0506]: cannot assign to `*x` because it is borrowed
--> $DIR/issue-75785-confusing-named-region.rs:9:5
|
LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
| - let's call the lifetime of this reference `'1`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the highlight points at the argument instead of the return type, this fixes #74072.

This means this PR will change the output of the test I added in #76468, so it will need rebasing on top of that.

LL | let y = &*x;
| --- borrow of `*x` occurs here
LL | *x += 1;
| ^^^^^^^ assignment to borrowed `*x` occurs here
LL | (&32, y)
| -------- returning this value requires that `*x` is borrowed for `'1`

error: aborting due to previous error

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