* Arguably this change is sometimes injecting noise into the output
(namely in the cases where the suggested rewrite is inline with the
suggestion and we end up highlighting the original source code).
I would not be opposed to something more aggressive/dynamic, like
revising the suggestion code to automatically print the original
source when necessary (e.g. when the error does not have a span
that includes the span of the suggestion).
* Also, as another note on this change: The doc comment for `Diagnostic::span_suggestion`
says:
/// The message
///
/// * should not end in any punctuation (a `:` is added automatically)
/// * should not be a question
/// * should not contain any parts like "the following", "as shown"
but the `:` is *not* added when the emitted line appears
out-of-line relative to the suggestion. I find that to be an
unfortunate UI experience.
----
As a drive-by fix, also changed code to combine multiple suggestions
for a pattern into a single multipart suggestion (which vastly
improves user experience IMO).
----
Includes the updates to expected NLL diagnostics.
[NLL] Use better spans in some errors
* Use the span of the discriminant and patterns for "fake" statements created to properly check matches. I plan to special case these soon, but this felt like a good first step
* Use the span of the statement, rather than the initialization, when reporting move errors for `let x = ...`, which avoids giving an unhelpful suggestion to use `&{ }`.
r? @nikomatsakis cc @pnkfelix
[NLL] make temp for each candidate in `match` arm
In NLL, `ref mut` patterns leverage the two-phase borrow infrastructure to allow the shared borrows within a guard before the "activation" of the mutable borrow when we begin execution of the match arm's body. (There is further discussion of this on PR #50783.)
To accommodate the restrictions we impose on two-phase borrows (namely that there is a one-to-one mapping between each activation and the original initialization), this PR is making separate temps for each candidate pattern. So in an arm like this:
```rust
PatA(_, ref mut ident) |
PatB(ref mut ident) |
PatC(_, _, ref mut ident) |
PatD(ref mut ident) if guard_stuff(ident) => ...
```
instead of 3 temps (two for the guard and one for the arm body), we now have 4 + 2 temps associated with `ident`: one for each candidate plus the actual temp that the guard uses directly, and then the sixth is the temp used in the arm body.
Fix#51348
Add `-Z borrowck=migrate`
This adds `-Z borrowck=migrate`, which represents the way we want to migrate to NLL under Rust versions to come. It also hooks this new mode into `--edition 2018`, which means we're officially turning NLL on in the 2018 edition.
The basic idea of `-Z borrowck=migrate` that there are cases where NLL is fixing old soundness bugs in the borrow-checker, but in order to avoid just breaking code by immediately rejecting the programs that hit those soundness bugs, we instead use the following strategy:
If your code is accepted by NLL, then we accept it.
If your code is rejected by both NLL and the old AST-borrowck, then we reject it.
If your code is rejected by NLL but accepted by the old AST-borrowck, then we emit the new NLL errors as **warnings**.
These warnings will be turned into hard errors in the future, and they say so in these diagnostics.
Fix#46908
Rollup of 16 pull requests
Successful merges:
- #52558 (Add tests for ICEs which no longer repro)
- #52610 (Clarify what a task is)
- #52617 (Don't match on region kinds when reporting NLL errors)
- #52635 (Fix #[linkage] propagation though generic functions)
- #52647 (Suggest to take and ignore args while closure args count mismatching)
- #52649 (Point spans to inner elements of format strings)
- #52654 (Format linker args in a way that works for gcc and ld)
- #52667 (update the stdsimd submodule)
- #52674 (Impl Executor for Box<E: Executor>)
- #52690 (ARM: expose `rclass` and `dsp` target features)
- #52692 (Improve readability in a few sorts)
- #52695 (Hide some lints which are not quite right the way they are reported to the user)
- #52718 (State default capacity for BufReader/BufWriter)
- #52721 (std::ops::Try impl for std::task::Poll)
- #52723 (rustc: Register crates under their real names)
- #52734 (sparc ABI issue - structure returning from function is returned in 64bit registers (with tests))
Failed merges:
- #52678 ([NLL] Use better spans in some errors)
r? @ghost
Note that this test is carefully crafted to *try* to not segfault
during its run. Howver, it really is representing unsound code that
should be rejected after we manage to remove the AST-borrowck entirely
from the compiler.
refactor and cleanup region errors for NLL
This is a WIP commit. It simplifies some of the code from https://github.com/rust-lang/rust/pull/51536 and extends a few more steps towards the errors that @davidtwco and I were shooting for. These are intended as a replacement for the general "unable to infer lifetime" messages -- one that is actually actionable. We're certainly not there yet, but the overall shape hopefully gets a bit clearer.
I'm thinking about trying to open up an internals thread to sketch out the overall plan and perhaps discuss how to get the wording right, which special cases to handle, etc.
r? @estebank
cc @davidtwco
Suggest not mutably borrowing a mutable reference
This PR would (hopefully) solve #45392. I deviated a bit from @estebank's instructions since the error span only included the borrowed expression (e.g. the `b` in `&mut b`). I also didn't check the mutability of the local binding, since this whole case is concerned with an immutable local.
I can see two outstanding questions:
1. `note_immutability_blame` is called in two places, but I only have one test case. I think it covers the call in `report_bckerror`, but I'm not sure how to trigger the call from `report_aliasability_violation`.
2. There is one failing test, where the local binding is `self: &mut Self`. I'm not entirely sure what the correct output should be, but I think the new message should also apply. Unfortunately, since this parameter is parsed differently, its `let_span` covers both the pattern and the type, leading to a wrong suggestion text. I'm not sure how to correctly identify this case.
This commit is concerned with the case where the user tries to mutably
borrow a mutable reference, thereby triggering an error. Instead of the
existing suggestion to make the binding mutable, the compiler will now
suggest to avoid borrowing altogether.
`PointerKind` is included in `LoanPath` and hence forms part of the
equality check; this led to having two unequal paths that both
represent `*x`, depending on whether the `*` was inserted
automatically or explicitly. Bad mojo. The `note` field, in contrast,
is intended more-or-less primarily for this purpose of adding extra
data.
In particular, I am adding an implicit injected borrow on the pattern
matches, and when we go around the loop, the compiler is reporting
that this injected borrow is conflicting with the move of the original
value when the match succeeds.
Instead of tracking the "cause" of each bit that gets added, try to
recover that by walking outlives relationships. This is currently
imprecise, since it ignores the "point" where the outlives relationship
is incurred -- but that's ok, since we're about to stop considering that
overall in a later commit. This does seem to affect one error message
negatively, I didn't dig *too* hard to find out why.
NOTE: I was careful to make each change in a manner that preserves the
existing diagnostic output (usually by ensuring that no lines were
added or removed). This means that the resulting source files are not
as nice to read as they were at the start. But we will have to review
these cases by hand anyway as follow-up work, so cleanup could
reasonably happen then (or not at all).
Extend two-phase borrows to apply to method receiver autorefs
Fixes#48598 by permitting two-phase borrows on the autorefs created when functions and methods.