Support an explicit annotation for marker traits
From the tracking issue for rust-lang/rfcs#1268:
> It seems obvious that we should make a `#[marker]` annotation. ~ https://github.com/rust-lang/rust/issues/29864#issuecomment-368959441
This PR allows you to put `#[marker]` on a trait, at which point:
- [x] The trait must not have any items ~~All of the trait's items must have defaults~~
- [x] Any impl of the trait must be empty (not override any items)
- [x] But impls of the trait are allowed to overlap
r? @nikomatsakis
[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
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.
Previously, region naming would always highlight the source of the
region name it found. Now, region naming returns the name as part
of a larger structure that encodes the source of the region naming
such that a region name can be optionally added to the diagnostic.
Previously, explain_borrow would emit an error with the explanation of
the a borrow. Now, it returns a enum with what the explanation for the
borrow is and any relevant spans or information such that the calling
code can choose to emit the same note/suggestion as before by calling
the emit method on the new enum.
incr.comp.: Allow for more fine-grained testing of CGU reuse and use it to test incremental ThinLTO.
This adds some tests specifically targeted at incremental ThinLTO, plus the infrastructure for tracking the kind of cache hit/miss we had for a given CGU. @alexcrichton, let me know if you can think of any more tests to add. ThinLTO works rather reliably for small functions, so we should be able to test it in a robust way.
I think after this lands it might time for a "Help us test incremental ThinLTO" post on irlo.
r? @alexcrichton
Report when borrow could cause `&mut` aliasing during Drop
We were already issuing an error for the cases where this cropped up, so this is not fixing any soundness holes. The previous diagnostic just wasn't accurately describing the problem in the user's code.
Fix#52059
[NLL] Record more infomation on free region constraints in typeck
Changes:
* Makes the span of the MIR return place point to the return type
* Don't try to use a path to a type alias as a path to the adt it aliases (fixes an ICE)
* Don't claim that `self` is declared outside of the function. [see this test](f2995d5b1a (diff-0c9e6b1b204f42129b481df9ce459d44))
* Remove boring/interesting distinction and instead add a `ConstraintCategory` to the constraint.
* Add categories for implicit `Sized` and `Copy` requirements, for closure bounds, for user type annotations and `impl Trait`.
* Don't use the span of the first statement for Locations::All bounds (even if it happens to work on the tests we have)
Future work:
* Fine tuning the heuristic used to choose the place the report the error.
* Reporting multiple places (behind a flag)
* Better closure bounds reporting. This probably requires some discussion.
r? @nikomatsakis
Implement `MaybeUninit`
This PR:
- Adds `MaybeUninit` (see #53491) to `{core,std}::mem`.
- Makes `mem::{uninitialized,zeroed}` panic when they are used to instantiate an uninhabited type.
- Does *not* deprecate `mem::{uninitialized,zeroed}` just yet. As per https://github.com/rust-lang/rust/issues/53491#issuecomment-414147666, we should not deprecate them until `MaybeUninit` is stabilized.
- It replaces uses of `mem::{uninitialized,zeroed}` in core and alloc with `MaybeUninit`.
There are still several instances of `mem::{uninitialized,zeroed}` in `std` that *this* PR doesn't address.
r? @RalfJung
cc @eddyb you may want to look at the new panicking logic