Rollup of 4 pull requests
Successful merges:
- rust-lang/rust#156073 ([rustdoc] Fix `doc_cfg` feature on reexports)
- rust-lang/rust#152216 (Fix 'assign to data in an index of' collection suggestions)
- rust-lang/rust#155433 (Rip out rustc_layout_scalar_valid_range_* attribute support)
- rust-lang/rust#156098 (Hand-implement `impl Debug for NumBuffer` to avoid constraining `T` or printing MaybeUninit)
Hand-implement `impl Debug for NumBuffer` to avoid constraining `T` or printing MaybeUninit
The derived implementation requires `T: Debug`, and doesn't need to.
Fix 'assign to data in an index of' collection suggestions
fixes https://github.com/rust-lang/rust/issues/150001
fixes https://github.com/rust-lang/rust-analyzer/issues/16076
fixes https://github.com/rust-lang/rust/issues/134917
The issues are threefold and linked:
1. Assigning data to a ~~collection~~BTreeMap/HashMap suggests 3 solutions all marked as `MachineApplicable`
2. The suggestions are slightly wrong with regards to their borrowing needs.
3. The suggestions are not guaranteed to produce code that is valid, and suggestion number two is equivalent to an update, not an insertion.
This PR:
- splits the large triple suggestion into three
- sets them to `MaybeIncorrect`
- automatically determines the required borrowing to use.
I think this solution may not be very elegant, expecially the key typechecking / borrowing part, but it works. I am however very open to any improvement/change :)
edit: edited to replace 'collection' with BTreeMap/HashMap'
[rustdoc] Fix `doc_cfg` feature on reexports
Part of rust-lang/rust#150268.
I don't mark the issue as fixed as I need to check the third case described in the issue. First commit comes from https://github.com/rust-lang/rust/pull/156020, will need to rebase this PR once the original is merged.
r? @Urgau
change field `tools` on `AttributeParser` to hold `&'tcx RegisteredTools`
Makes tools actually stored, and not just tool names
this was originally part of rust-lang/rust#155691 but was split out to make that PR smaller.
r? @petrochenkov
cc @JonathanBrouwer
Remove unused spans from AttributeKind
Recently I noticed some spans in diagnostic attributes were never used. I went through and checked the other variants too.
refactor rustc_on_unimplemented's filtering
Previously when you had a
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub condition: Option<OnUnimplementedCondition>,
pub subcommands: ThinVec<Directive>,
pub message: Option<(Span, FormatString)>,
...
}
```
that condition would control the emission of the message, label, notes etc. I've changed that to
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub filters: ThinVec<(Filter, Directive)>,
pub message: Option<(Span, FormatString)>,
...
```
so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last).
The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so `OnUnimplementedCondition` and the like would have to be renamed anyway.
Validate source snippet when format input is raw string
Fixesrust-lang/rust#114865
The issue occurred because the user's proc macro respanned the format arg to an unrelated multi-byte string and we ICE'd by landing in the middle of a multi-byte char.
This PR adds validation that prevents the parser from trying to walk such obviously wrong snippets. Such validation already existed for non-raw strings. This PR adds it for raw strings as well.
Make retags an implicit part of typed copies
Ever since Stacked Borrows was first implemented in Miri, that was done with `Retag` statements: given a place (usually a local variable), those statements find all references stored inside the place and refresh their tags to ensure the aliasing requirements are upheld. However, this is a somewhat unsatisfying approach for multiple reasons:
- It leaves open the [question](https://github.com/rust-lang/unsafe-code-guidelines/issues/371) of where to even put `Retag` statements. Over time, the AddRetag pass settled on one possible answer to this, but it wasn't very canonical.
- For assignments of the form `*ptr = expr`, if the assignment involves copying a reference, we probably want to do a retag -- but if we do a `Retag(*ptr)` as the next instruction, it can be non-trivial to argue that this even retags the right value, so we refrained from doing retags in that case. This has [come up](https://github.com/llvm/llvm-project/pull/160913#issuecomment-3341908717) as a potential issue for Rust making better use of LLVM "captures" annotations. (That said, there might be [other ways](https://github.com/rust-lang/unsafe-code-guidelines/issues/593#issuecomment-4328112031) to obtain this desired optimization.)
- Normal compilation avoids generating retags, but we still generate LLVM IR with `noalias`. What does that even mean? How do MIR optimization passes interact with retags? These are questions we have to figure out to make better use of aliasing information, but currently we can't even really ask such questions.
I think we should resolve all that by making retags part of what happens during a typed copy (a concept and interpreter infrastructure that did not exist yet when retags were initially introduced). Under this proposal, when executing a MIR assignment statement, what conceptually happens is as follows:
- We evaluate the LHS to a place.
- We evaluate the RHS to a value. This does a typed load from memory if needed, raising UB if memory does not contain a valid representation of the assignment's type.
- We walk that value, identify all references inside of it, and retag them. If this happens as part of passing a function argument, this is a protecting retag.
- We store (a representation of) the value into the place.
However, this semantics doesn't fully work: there's a mandatory MIR pass that turns expressions like `&mut ***ptr` into intermediate deref's. Those must *not* do any retags. So far this happened because the AddRetag pass did not add retags for assignments to deref temporaries, but that information is not recorded in cross-crate MIR. Therefore I instead added a field to `Rvalue::Use` to indicate whether this value should be retagged or not. A non-retagging copy seems like a sufficiently canonical primitive that we should be able to express it. Dealing with the fallout from that is a large chunk of the overall diff. (I also considered adding this field to `StatementKind::Assign` instead, but decided against that as we only actually need it for `Rvalue::Use`. I am not sure if this was the right call...)
This neatly answers the question of when retags should occur, and handles cases like `*ptr = expr`. It avoids traversing values twice in Miri. It makes codegen's use of `noalias` sound wrt the actual MIR that it is working on. It also gives us a target semantics to evaluate MIR opts against. However, I did not carefully check all MIR opts -- in particular, GVN needs a thorough look under the new semantics; it currently can turn alias-correct code into alias-incorrect code. (But this PR doesn't make things any worse for normal compilation where the retag indicator is anyway ignored.)
Another side-effect of this PR is that `-Zmiri-disable-validation` now also disables alias checking. It'd be nicer to keep them orthogonal but I find this an acceptable price to pay.
- [rustc benchmark results](https://github.com/rust-lang/rust/pull/154341#issuecomment-4125313290)
- [miri benchmark results](https://github.com/rust-lang/rust/pull/154341#issuecomment-4129840926)
Do not depend on typeck to borrow-check inline consts.
Instead fetch the type from the inline-const's MIR, which comes from exactly the same typeck information.
Add extra symbol check for `.to_owned()`
Follow up of rust-lang/rust#154646
Previously when adding a suggestion for using `Cow::into_owned()` instead of `ToOwned::to_owned()`, the compiler would just convert the methods `Span` into a `String` and do checks on that `String`. This PR adds an extra guard to that suggestion by checking if the method is `sym::to_owned_method`.
r? @davidtwco since you added the review to the previous PR
Previously when adding a suggestion for using `Cow::into_owned()`
instead of `ToOwned::to_owned()`, the compiler would just convert the
methods `Span` into a `String` and do checks on that `String`. This PR
adds an extra guard to that suggestion by checking if the method is
`sym::to_owned_method`.
added a valid example that violated the assumption in the proposed
change: it is possible for a borrowee type to be a ref of it's borrowed
type.
removed the assumption, treated all cases appropriately.
compiler: Print valid `-Zmir-enable-passes` names if invalid name is used
If a user passes an invalid name to `-Zmir-enable-passes`, print the valid names as a note.
To avoid the annoyance of having to keep blessing test output, completely normalize away the list of names in the test.
The diagnostic is duplicated, but that is not introduced by this commit. In other words, we don't make matters worse. The existing "is unknown and will be ignored" diagnostic is already duplicated, as can be seen in the existing test stderr.
The output is on one long line, but that makes normalization in tests easier, and I don't think we have to overdo this. We can let terminals wrap the line.
<details>
<summary>Click to expand current output</summary>
`note: valid MIR pass names are: AbortUnwindingCalls, AddCallGuards, AddMovesForPackedDrops, AddRetag, CheckAlignment, CheckCallRecursion, CheckConstItemMutation, CheckDropRecursion, CheckEnums, CheckForceInline, CheckInlineAlwaysTargetFeature, CheckLiveDrops, CheckNull, CheckPackedRef, CleanupPostBorrowck, CopyProp, CtfeLimit, DataflowConstProp, DeadStoreElimination-final, DeadStoreElimination-initial, Derefer, DestinationPropagation, EarlyOtherwiseBranch, ElaborateBoxDerefs, ElaborateDrops, EnumSizeOpt, EraseDerefTemps, ForceInline, FunctionItemReferences, GVN, ImpossiblePredicates, Inline, InstSimplify-after-simplifycfg, InstSimplify-before-inline, InstrumentCoverage, JumpThreading, KnownPanicsLint, LowerIntrinsics, LowerSliceLenCalls, Marker, MatchBranchSimplification, MentionedItems, MultipleReturnTerminators, PostAnalysisNormalize, PreCodegen, PromoteTemps, ReferencePropagation, RemoveNoopLandingPads, RemovePlaceMention, RemoveStorageMarkers, RemoveUninitDrops, RemoveUnneededDrops, RemoveZsts, ReorderBasicBlocks, ReorderLocals, RequiredConstsVisitor, SanityCheck, ScalarReplacementOfAggregates, SimplifyCfg-after-unreachable-enum-branching, SimplifyCfg-final, SimplifyCfg-initial, SimplifyCfg-make_shim, SimplifyCfg-post-analysis, SimplifyCfg-pre-optimizations, SimplifyCfg-promote-consts, SimplifyCfg-remove-false-edges, SimplifyComparisonIntegral, SimplifyConstCondition-after-const-prop, SimplifyConstCondition-after-inst-simplify, SimplifyConstCondition-final, SimplifyLocals-after-value-numbering, SimplifyLocals-before-const-prop, SimplifyLocals-final, SingleUseConsts, SsaRangePropagation, StateTransform, StripDebugInfo, Subtyper, UnreachableEnumBranching, UnreachablePropagation, Validator`
</details>
Reuse CTFE MIR for constructors.
For constructors, we manually build the MIR shim we want. We can just have `optimized_mir` call `mir_for_ctfe` instead of rebuilding the shim.
Make `diverging_type_vars` a vec of `TyVid`
r? @lcnr
The following changes, in separate commits:
* Make its elements a `TyVid`, since there should never by any other types than `TyVars` in there
* Make it a vec, since it being a set doesn't make much sense. You never really should do a `contains` on it, since you should normalize the tyvids in the set to their root var first.