[NLL] Be more permissive when checking access due to Match
Partially addresses #53114. notably, we should now have parity with AST borrowck. Matching on uninitialized values is still forbidden.
* ~~Give fake borrows for match their own `BorrowKind`~~
* ~~Allow borrows with this kind to happen on values that are already mutably borrowed.~~
* ~~Track borrows with this type even behind shared reference dereferences and consider all accesses to be deep when checking for conflicts with this borrow type. See [src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs](cb5c989598 (diff-a2126cd3263a1f5342e2ecd5e699fbc6)) for an example soundness issue this fixes (a case of #27282 that wasn't handled correctly).~~
* Create a new `BorrowKind`: `Shallow` (name can be bike-shed)
* `Shallow` borrows differ from shared borrows in that
* When we check for access we treat them as a `Shallow(Some(_))` read
* When we check for conflicts with them, if the borrow place is a strict prefix of the access place then we don't consider that a conflict.
* For example, a `Shallow` borrow of `x` does not conflict with any access or borrow of `x.0` or `*x`
* Remove the current fake borrow in matches.
* When building matches, we take a `Shallow` borrow of any `Place` that we switch on or bind in a match, and any prefix of those places. (There are some optimizations where we do fewer borrows, but this shouldn't change semantics)
* `match x { &Some(1) => (), _ => (), }` would `Shallow` borrow `x`, `*x` and `(*x as Some).0` (the `*x` borrow is unnecessary, but I'm not sure how easy it would be to remove.)
* Replace the fake discriminant read with a `ReadForMatch`.
* Change ReadForMatch to only check for initializedness (to prevent `let x: !; match x {}`), but not conflicting borrows. It is still considered a use for liveness and `unsafe` checking.
* Give special cased error messages for this kind of borrow.
Table from the above issue after this PR
| Thing | AST | MIR | Want | Example |
| --- | --- | --- | --- |---|
| `let _ = <unsafe-field>` | 💚 | 💚 | ❌ | [playground](https://play.rust-lang.org/?gist=bb7843e42fa5318c1043d04bd72abfe4&version=nightly&mode=debug&edition=2015) |
| `match <unsafe_field> { _ => () }` | ❌ | ❌ | ❌ | [playground](https://play.rust-lang.org/?gist=3e3af05fbf1fae28fab2aaf9412fb2ea&version=nightly&mode=debug&edition=2015) |
| `let _ = <moved>` | 💚 | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=91a6efde8288558e584aaeee0a50558b&version=nightly&mode=debug&edition=2015) |
| `match <moved> { _ => () }` | ❌ | ❌ | 💚 | [playground](https://play.rust-lang.org/?gist=804f8185040b2fe131f2c4a64b3048ca&version=nightly&mode=debug&edition=2015) |
| `let _ = <borrowed>` | 💚 | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=0e487c2893b89cb772ec2f2b7c5da876&version=nightly&mode=debug&edition=2015) |
| `match <borrowed> { _ => () }` | 💚 | 💚 | 💚 | [playground](https://play.rust-lang.org/?gist=0e487c2893b89cb772ec2f2b7c5da876&version=nightly&mode=debug&edition=2015) |
r? @nikomatsakis
This commit is an initial start at implementing the standard library for
wasm32-unknown-unknown with the experimental `atomics` feature enabled. None of
these changes will be visible to users of the wasm32-unknown-unknown target
because they all require recompiling the standard library. The hope with this is
that we can get this support into the standard library and start iterating on it
in-tree to enable experimentation.
Currently there's a few components in this PR:
* Atomic fences are disabled on wasm as there's no corresponding atomic op and
it's not clear yet what the convention should be, but this will change in the
future!
* Implementations of `Mutex`, `Condvar`, and `RwLock` were all added based on
the atomic intrinsics that wasm has.
* The `ReentrantMutex` and thread-local-storage implementations panic currently
as there's no great way to get a handle on the current thread's "id" yet.
Right now the wasm32 target with atomics is unfortunately pretty unusable,
requiring a lot of manual things here and there to actually get it operational.
This will likely continue to evolve as the story for atomics and wasm unfolds,
but we also need more LLVM support for some operations like custom `global`
directives for this to work best.
This change makes "await" ident an error in 2018 edition without async_await
feature and adds "await" to the 2018 edition keyword lint group that
suggest migration on the 2015 edition.
Rewrite docs for pointer methods
This takes over https://github.com/rust-lang/rust/pull/51016 by @ecstatic-morse. They did most of the work, I just did some editing.
However, I realized one problem: This updates the docs for the "free functions" in `core::ptr`, but it does not update the copies of these docs for the inherent methods of the `*const T` and `*mut T` types. These getting out-of-sync is certainly bad, but I also don't feel like copying all this stuff around. Instead, we should remove this redundancy. Any good ideas?
[NLL] Rework checking for borrows conflicting with drops
Previously, we would split the drop access into multiple checks for each
field of a struct/tuple/closure and through `Box` dereferences. This
changes this to check if the borrow is accessed by the drop in
`places_conflict`.
We also now handle enums containing `Drop` types.
Closes#53569
r? @nikomatsakis
cc @pnkfelix
update rls to 32d457717ce37babef199fe4984b1e20d4e108d4
I patched rls to use the `rustc_tools_utils` supplied by the clippy submodule to get around the tidy warning.
Should fix rls and toolstate.
avoid loading constructor attributes in AdtDef decoding
During metadata loading, the AdtDefs for every ADT in the universe need
to be loaded (for example, for coherence of builtin traits). For that,
the attributes of the AdtDef need to be loaded too.
The attributes of a struct are duplicated between 2 def ids - the
constructor def-id, and the "type" def id. Loading attributes for both
def-ids, which was done in #53721, slowed the compilation of small
crates by 2-3%. This PR makes sure we only load the attributes for the
"type" def-id, avoiding the slowdown.
r? @eddyb & cc @nnethercote
Previously, we would split the drop access into multiple checks for each
field of a struct/tuple/closure and through `Box` dereferences. This
changes this to check if the borrow is accessed by the drop in
places_conflict.
This also allows us to handle enums in a simpler way, since we don't
have to construct any new places.
When dropping a self-borrowing struct we shouldn't add a "values in a
scope are dropped in the opposite order they are defined" message,
since there is only one value being dropped.
move CTFE engine snapshot state out of miri engine into CTFE machine instance
It still lives in the `interpret` module as it needs access to all sorts of private stuff. Also rename a thing to make @eddyb happy :D
The goal was not to change any behavior.
Error now correctly checks whether the borrow that does not live
long enough is being returned before annotating the error with the
arguments and return type from the signature - as this would not be
relevant if the borrow was not being returned.
Enhances annotation logic to properly consider named lifetimes where
lifetime elision rules that were previously implemented would not apply.
Further, adds new help and note messages to diagnostics and highlights
only lifetime when dealing with named lifetimes.
This error can only occur within a function when a borrow of data owned
within the function is returned; and when there are arguments that could
have been returned instead. Therefore, it is always applicable to add a
specific note that links to the relevant rust documentation about
dangling references.
For cases where there are references in the parameters and in the the
outputs that do not match, and where no closures are involved, this
commit introduces an improved error that mentions (or synthesizes)
a name for the regions involved to better illustrate why the borrow
does not live long enough.