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

Use larger span for adjustment THIR expressions #89110

Merged
merged 1 commit into from
Sep 30, 2021

Conversation

Aaron1011
Copy link
Member

Currently, we use a relatively 'small' span for THIR
expressions generated by an 'adjustment' (e.g. an autoderef,
autoborrow, unsizing). As a result, if a borrow generated
by an adustment ends up causing a borrowcheck error, for example:

let mut my_var = String::new();
let my_ref = &my_var
my_var.push('a');
my_ref;

then the span for the mutable borrow may end up referring
to only the base expression (e.g. my_var), rather than
the method call which triggered the mutable borrow
(e.g. my_var.push('a'))

Due to a quirk of the MIR borrowck implementation,
this doesn't always get exposed in migration mode,
but it does in many cases.

This commit makes THIR building consistently use 'larger'
spans for adjustment expressions. These spans are recoded
when we first create the adjustment during typecheck. For
example, an autoref adjustment triggered by a method call
will record the span of the entire method call.

The intent of this change it make it clearer to users
when it's the specific way in which a variable is
used (for example, in a method call) that produdes
a borrowcheck error. For example, an error message
claiming that a 'mutable borrow occurs here' might
be confusing if it just points at a usage of a variable
(e.g. my_var), when no &mut is in sight. Pointing
at the entire expression should help to emphasize
that the method call itself is responsible for
the mutable borrow.

In several cases, this makes the #![feature(nll)] diagnostic
output match up exactly with the default (migration mode) output.
As a result, several .nll.stderr files end up getting removed
entirely.

@rust-highfive
Copy link
Collaborator

r? @wesleywiser

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 19, 2021
@Aaron1011
Copy link
Member Author

r? @estebank

@Aaron1011
Copy link
Member Author

Aaron1011 commented Sep 19, 2021

Note that we don't currently explain that an autoderef/autoborrow was the cause of the borrow that resulted in an error. Doing so would require tracking additional information about THIR expressions / MIR statements, since we can't otherwise distinguish between a user-written &mut_var, and an adjustment-generated autoref.

However, I don't think this change makes the situation any more confusing. Previously, a user might be lead to incorrectly ask "Why does writing my_var trigger a mutable reference". With this change, they will hopefully instead be lead to ask "Why does writing my_var.some_method() trigger a mutable reference", which is the right question to be asking.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@estebank
Copy link
Contributor

r=me after fixing the tests

@rust-log-analyzer

This comment has been minimized.

@Aaron1011
Copy link
Member Author

It looks like storing the additional span in Adjustment is causing a large number of new incr comp invalidations of typecheck results. I'll see if anything can be done about it.

@estebank
Copy link
Contributor

If you somehow keep two spans around, I would love it if we could point at both the receiver and the call with different labels to maybe explain what's happening better, but that might be too involved for this PR.

@bors
Copy link
Contributor

bors commented Sep 24, 2021

☔ The latest upstream changes (presumably #88804) made this pull request unmergeable. Please resolve the merge conflicts.

@Aaron1011
Copy link
Member Author

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 25, 2021
@bors
Copy link
Contributor

bors commented Sep 25, 2021

⌛ Trying commit f33117fb9d8b1559497dd8d617e088d08e6e3345 with merge ac898de96c454463a122001d8e531e7be605a152...

@bors
Copy link
Contributor

bors commented Sep 25, 2021

☀️ Try build successful - checks-actions
Build commit: ac898de96c454463a122001d8e531e7be605a152 (ac898de96c454463a122001d8e531e7be605a152)

@rust-timer
Copy link
Collaborator

Queued ac898de96c454463a122001d8e531e7be605a152 with parent 043972f, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (ac898de96c454463a122001d8e531e7be605a152): comparison url.

Summary: This benchmark run did not return any relevant changes.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 25, 2021
Currently, we use a relatively 'small' span for THIR
expressions generated by an 'adjustment' (e.g. an autoderef,
autoborrow, unsizing). As a result, if a borrow generated
by an adustment ends up causing a borrowcheck error, for example:

```rust
let mut my_var = String::new();
let my_ref = &my_var
my_var.push('a');
my_ref;
```

then the span for the mutable borrow may end up referring
to only the base expression (e.g. `my_var`), rather than
the method call which triggered the mutable borrow
(e.g. `my_var.push('a')`)

Due to a quirk of the MIR borrowck implementation,
this doesn't always get exposed in migration mode,
but it does in many cases.

This commit makes THIR building consistently use 'larger'
spans for adjustment expressions

The intent of this change it make it clearer to users
when it's the specific way in which a variable is
used (for example, in a method call) that produdes
a borrowcheck error. For example, an error message
claiming that a 'mutable borrow occurs here' might
be confusing if it just points at a usage of a variable
(e.g. `my_var`), when no `&mut` is in sight. Pointing
at the entire expression should help to emphasize
that the method call itself is responsible for
the mutable borrow.

In several cases, this makes the `#![feature(nll)]` diagnostic
output match up exactly with the default (migration mode) output.
As a result, several `.nll.stderr` files end up getting removed
entirely.
@Aaron1011
Copy link
Member Author

@estebank: I rewrote the implementation entirely - only rustc_mir_build needs to be modified now. Also, I've decreased the scale of this change slightly - it now only applies to method calls, rather than all adjustments.

@estebank
Copy link
Contributor

@bors r+

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 28, 2021
@bors
Copy link
Contributor

bors commented Sep 29, 2021

⌛ Testing commit 4d66986 with merge 85de977ecd19afc104105755aba47eb2521d2347...

@bors
Copy link
Contributor

bors commented Sep 29, 2021

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Sep 29, 2021
@Aaron1011
Copy link
Member Author

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 29, 2021
@bors
Copy link
Contributor

bors commented Sep 29, 2021

⌛ Testing commit 4d66986 with merge 700edf49ebfdb401f007379f83aebd2d6c8cb752...

@bors
Copy link
Contributor

bors commented Sep 29, 2021

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Sep 29, 2021
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-msvc-1 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    Finished dev [unoptimized + debuginfo] target(s) in 0.28s
Set({"src/tools/tidy"}) not skipped for "bootstrap::test::Tidy" -- not in ["src/test/ui", "src/tools/linkchecker"]
Skipping Suite("src/test/ui") because it is excluded
Suite("src/test/run-pass-valgrind") not skipped for "bootstrap::test::RunPassValgrind" -- not in ["src/test/ui", "src/tools/linkchecker"]
thread 'main' panicked at '"lldb" "-P" failed Output { status: ExitStatus(ExitStatus(3221225781)), stdout: "", stderr: "" }', src\bootstrap\test.rs:1394:40
Build completed unsuccessfully in 0:00:01
Build completed unsuccessfully in 0:00:01
make: *** [Makefile:72: ci-subset-1] Error 1
---
Cleaning up orphan processes
Terminate orphan process: pid (6136) (node)
Terminate orphan process: pid (2848) (python)
Terminate orphan process: pid (2896) (sccache)
Terminate orphan process: pid (892) (vctip)

@ehuss
Copy link
Contributor

ehuss commented Sep 29, 2021

@bors retry
Issue with Windows LLDB

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 29, 2021
@Mark-Simulacrum
Copy link
Member

@bors treeclosed-

@bors
Copy link
Contributor

bors commented Sep 30, 2021

⌛ Testing commit 4d66986 with merge 4aa7879...

@bors
Copy link
Contributor

bors commented Sep 30, 2021

☀️ Test successful - checks-actions
Approved by: estebank
Pushing 4aa7879 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Sep 30, 2021
@bors bors merged commit 4aa7879 into rust-lang:master Sep 30, 2021
@rustbot rustbot added this to the 1.57.0 milestone Sep 30, 2021
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (4aa7879): comparison url.

Summary: This benchmark run did not return any relevant changes.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 12, 2023
…stment-error, r=oli-obk

(re-)tighten sourceinfo span of adjustments in MIR

Diagnostics rely on the spans of MIR statements being (approximately) correct in order to give suggestions relative to that span (i.e. `shrink_to_hi` and `shrink_to_lo`).

I discovered that we're *intentionally* lowering THIR exprs with their parent expr's span if they come from adjustments that are due to a parent expression. While I understand why that may be desirable to demonstrate the relationship of an adjustment and the expression that requires it, it leads to

1. very verbose borrowck output
2. incorrect spans for suggestions

Some diagnostics get around that by giving suggestions relative to other spans we've collected during MIR lowering, such as the span of the method's identifier (e.g. `name` in `.name()`), but this doesn't work too well when things come from desugaring.

I assume it also has lead to numerous tweaks and complications to diagnostics code down the road, which this PR doesn't necessarily aim to fix but may open the gates to fixing later... The last three commits are simplifications due to the fact that we can assume that the move span actually points to what is being moved (and a test).

This regressed in rust-lang#89110, which was debated somewhat in rust-lang#90286. cc `@Aaron1011` who originally made this change.

r? diagnostics

Fixes rust-lang#113547
Fixes rust-lang#111016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants