Improve `redundant_locals` help message
Fixes#11625
AFAIK, `span_lint_and_help` points the beginning of spans when we pass multiple spans to the second argument, so This PR I also modified its help span and its message.
lint result of the given example in the issue will be:
```console
error: redundant redefinition of a binding `apple`
--> src/main.rs:5:5
|
5 | let apple = apple;
| ^^^^^^^^^^^^^^^^^^
|
help: `apple` is initially defined here
--> src/main.rs:4:9
|
4 | let apple = 42;
| ^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals
```
I hope that this change might help reduce user confusion, but I'd appreciate alternative suggestions:)
changelog: [`redundant_locals`]: Now points at the rebinding of the variable
Continuation of #3054: enable spurious reads in TB
The last additions to the test suite of TB left some unresolved `#[should_panic]` that these new modifications solve.
## Problem
Recall that the issues were arising from the interleavings that follow.
### A. `Reserved -> Frozen` has visible effects after function exit
The transition `Reserved -> Frozen` irreversibly blocks write accesses to the tag, so in the interleaving below `y` initially `Reserved` becomes `Frozen` only in the target where a spurious read through `x` is inserted. This makes the later write through `y` UB only in the target and not in the source.
```
1: retag x (&, protect)
2: retag y (&mut, protect)
1: spurious read x
1: ret x
2: ret y
2: write y
```
### B. Protectors only announce their presence on retag
There is a read-on-reborrow for protected locations, but if the retag of `x` occurs before that of `y` and there is no explicit access through `x`, then `y` is unaware of the existence of `x`. This is problematic because a spurious read inserted through `x` between the retag of `y` and the return of the function protecting `x` is a noalias violation in the target without UB in the source.
```
1: retag x (&, protect)
2: retag y (&mut, protect)
1: spurious read x
1: ret x
2: write y
2: ret y
```
## Step 1: Finer behavior for `Reserved`
Since one problem is that `Reserved -> Frozen` has consequences beyond function exit, we decide to remove this transition entirely. To replace it we introduce a new subtype of `Reserved` with the extra boolean `aliased` set.
`Reserved { aliased: true }` forbids child accesses, but only temporarily: it has no effect on activation once the tag is no longer protected.
This makes the semantics of Tree Borrows slightly weaker in favor of being more similar to noalias.
This solves interleaving **A.**, but **B.** is still a problem and the exhaustive tests do not pass yet.
## Step 2: Read on function exit
Protected tags issue a "reminder" that they are protected until this instant inclusive, in the form of an implicit read (symmetrically to the implicit read on retag). This ensures that if the periods on which two tags `x` and `y` are protected overlap then no matter the interleaving of retags and returns, there is either a protector currently active or a read that has been emitted, both of which temporarily block activation.
This makes the exhaustive test designed previously pass, but it has an effect on the ability to return an activated pointer that I had not foreseen before implementing it.
## Step 2': Do not propagate to children
A naive implementation of **Step 2** makes the following code UB:
```rs
fn reborrow(x: &mut u8) -> &mut u8 {
let y = &mut *x;
*y = *y;
y // callee returns `y: Active`...
}
let x = &mut 0u8;
let y = reborrow(x); // ... and caller receives `y: Frozen`
*y = 1; // UB
```
This is unacceptable, and a simple fix is to make this implicit read visible only to foreign tags.
We still lack hindsight on the ramifications of this decision, and the fact that the problematic pattern was only discovered because it occured in one completely unrelated test (with a cryptic error message) is worrying. We should be vigilant as to how this interacts with the rest of the model.
## TODO
As of commit #281c30, the data race model has not been fully updated.
We have removed the reborrow of mutable references counting as a write access, but we still need the implicit read of function exit to count as a read.
Fix `items_after_test_module` for non root modules, add applicable suggestion
Fixes#11050Fixes#11153
changelog: [`items_after_test_module`]: Now suggests a machine-applicable suggestion.
changelog: [`items:after_test_module`]: Also lints for non root modules
Rollup of 6 pull requests
Successful merges:
- #115454 (Clarify example in docs of str::char_slice)
- #115522 (Clarify ManuallyDrop bit validity)
- #115588 (Fix a comment in std::iter::successors)
- #116198 (Add more diagnostic items for clippy)
- #116329 (update some comments around swap())
- #116475 (rustdoc-search: fix bug with multi-item impl trait)
r? `@ghost`
`@rustbot` modify labels: rollup
Use `std::path::PathBuf` rather than `String`; use `std::env::var_os`
rather than `std::env::var`. These changes avoid a number of error paths
which can arise in the presence of non-UTF-8 paths.
Reserved loses permissions too quickly.
Adding more fine-grained behavior of Reserved lets it lose
write permissions only temporarily.
Protected tags receive a read access on initialized locations.
Fix a comment in std::iter::successors
The `unfold` function have since #58062 been renamed to `from_fn`.
(I'm not sure if this whole comment is still useful—it's not like there are many iterators that *can't* be based on `from_fn`. Anyway, in its current form this comment is not correct, and it sent me into a half-hour research of what happened to `unfold` function, so I want to do *something* with it 🙃 deleting these three lines is a perfectly fine alternative, in my opinion.)
Clarify example in docs of str::char_slice
Just a one word improvement.
“Last” can be misread as meaning the last (third) instead of the previous (first).
`waitqueue` clarifications for SGX platform
The documentation of `waitqueue` functions on the `x86_64-fortanix-unknown-sgx` platform is incorrect at some places and on others missing. This PR improves upon this.
cc: `@jethrogb`
LLVM still has trouble re-using discriminants sometimes when rebuilding a two-variant enum, so when we have the correct variant already built, just use it.
That's simpler in LLVM *and* in MIR, so might as well: <https://rust.godbolt.org/z/KhdE8eToW>
refactor dlsym: dispatch symbols via the normal shim mechanism
This avoids having to adjust Miri when switching between invoking the function via a linked symbol vs via dlsym.
Support getentropy on macOS as a foreign item
Prior this was always assumed to be accessed via `dlsym` shim, but in `std` I'm attempting to start [unconditionally linking](https://github.com/rust-lang/rust/pull/116319) to `getentropy` on macOS now that Rust's platform version support allows it.
This just moves the main logic of the previous `dlsym` handler into an eval context extension so it can be used via both call paths. The `dlsym` handler is still needed as `getrandom` uses it.