The SCCs of the region graph are not a reliable heuristic to use for blaming an interesting
constraint for diagnostics. For region errors, if the outlived region is `'static`, or the involved
types are invariant in their lifetiems, there will be cycles in the constraint graph containing both
the target region and the most interesting constraints to blame. To get better diagnostics in these
cases, this commit removes that heuristic.
`ExtraConstraintInfo` was used only for a single subdiagnostic, so this moves the logic for that
to its own function and eliminates the indirection. In order to do so cleanly, this also changes
the arguments to `BorrowExplanation::add_explanation_to_diagnostic`, which happens to simplify its
call sites.
Before this commit, replace-version-placeholder hardcoded the path
defining CURRENT_RUSTC_VERSION (to avoid replacing it). After a refactor
moved the file defining it without changing the hardcoded path, the tool
started replacing the constant itself with the version number.
To avoid this from happening in the future, this changes the definition
of the constant to avoid the tool from ever matching it.
Suppress host effect predicates if underlying trait doesn't hold
Don't report two errors for when the (`HostEffectPredicate`) `T: const Trait` isn't implemented because (`TraitPredicate`) `T: Trait` doesn't even hold.
Use `PostBorrowckAnalysis` in `check_coroutine_obligations`
This currently errors with:
```
error: concrete type differs from previous defining opaque type use
--> tests/ui/coroutine/issue-52304.rs:10:21
|
10 | pub fn example() -> impl Coroutine {
| ^^^^^^^^^^^^^^ expected `{example::{closure#0} upvar_tys=() resume_ty=() yield_ty=&'{erased} i32 return_ty=() witness={example::{closure#0}}}`, got `{example::{closure#0} upvar_tys=() resume_ty=() yield_ty=&'static i32 return_ty=() witness={example::{closure#0}}}`
|
= note: previous use here
```
This is because we end up redefining the opaque in `check_coroutine_obligations` but with the `yield_ty = &'erased i32` from hir typeck, which causes the *equality* check for opaques to fail.
The coroutine obligtions in question (when `-Znext-solver` is enabled) are:
```
Binder { value: TraitPredicate(<Opaque(DefId(0:5 ~ issue_52304[4c6d]::example::{opaque#0}), []) as std::marker::Sized>, polarity:Positive), bound_vars: [] }
Binder { value: AliasRelate(Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(0:5 ~ issue_52304[4c6d]::example::{opaque#0}), .. })), Equate, Term::Ty(Coroutine(DefId(0:6 ~ issue_52304[4c6d]::example::{closure#0}), [(), (), &'{erased} i32, (), CoroutineWitness(DefId(0:6 ~ issue_52304[4c6d]::example::{closure#0}), []), ()]))), bound_vars: [] }
Binder { value: AliasRelate(Term::Ty(Coroutine(DefId(0:6 ~ issue_52304[4c6d]::example::{closure#0}), [(), (), &'{erased} i32, (), CoroutineWitness(DefId(0:6 ~ issue_52304[4c6d]::example::{closure#0}), []), ()])), Subtype, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(0:5 ~ issue_52304[4c6d]::example::{opaque#0}), .. }))), bound_vars: [] }
```
Ignoring the fact that we end up stalling some really dumb obligations here (lol), I think it makes more sense for us to be using post borrowck analysis for this check anyways.
r? lcnr
inline_threshold mark deprecated
no-stack-check
print deprecation message for -Car too
inline_threshold deprecated and do nothing: make in untracked
make OptionDesc struct from tuple
A few borrowck tweaks to improve 2024 edition migration lints
See first two commits' changes to test outputs. Test coverage in this area is kinda weak, but I think it affects more cases than this (like the craters that will begin to trigger the `tail_expr_drop_order` tests in #134523).
Third commit is a drive-by change that removes a deref hack from `UseSpans` which doesn't really improve diagnostics much.
Mention `unnameable_types` in `unreachable_pub` documentation.
This link makes sense because someone who wishes to avoid unusable `pub` is likely, but not guaranteed, to be interested in avoiding unnameable types.
Also fixed some grammar problems I noticed in the area.
Fixes#116604.
r? Urgau
add m68k-unknown-none-elf target
r? `@workingjubilee`
The existing `m68k-unknown-linux-gnu` target builds `std` by default, requires atomics, and has a base cpu with an fpu. A smaller/more embedded target is desirable both to have a baseline target for the ISA, as well to make debugging easier for working on the llvm backend. Currently this target is using the `M68010` as the minimum CPU due, but as missing features are merged into the `M68k` llvm backend I am hoping to lower this further.
I have been able to build very small crates using a toolchain built against this target (together with a later version of `object`) using the configuration described in the target platform-support documentation, although getting anything of substantial complexity to build quickly hits errors in the llvm backend
This link makes sense because someone who wishes to avoid unusable `pub`
is likely, but not guaranteed, to be interested in avoiding unnameable
types.
Also fixed some grammar problems I noticed in the area.
Fixes#116604.
cg_llvm: Use constants for DWARF opcodes, instead of FFI calls
Split off from #134009 to incorporate feedback from https://github.com/rust-lang/rust/pull/134009#discussion_r1903133906.
Most of the constant values now come from gimli, which is already a compiler dependency.
I noticed that `DW_OP_LLVM_fragment` is an LLVM detail that is not defined by DWARF and could hypothetically change, so I added a static assertion on the C++ side to detect that if it ever happens.
r? workingjubilee
Add a notion of "some ABIs require certain target features"
I think I finally found the right shape for the data and checks that I recently added in https://github.com/rust-lang/rust/pull/133099, https://github.com/rust-lang/rust/pull/133417, https://github.com/rust-lang/rust/pull/134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both `-Ctarget-feature` and `#[target_feature]` are updated to ensure we follow the rules of the ABI. This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features.
We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this *before* applying `-Ctarget-feature` to maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested.
For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;)
As a side-effect this also (unstably) allows *enabling* `x87` when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see https://github.com/rust-lang/rust/issues/133611, but no such change is happening in this PR.
r? `@workingjubilee`
Target: Add mips mti baremetal support
Do the same thing as gcc, which use the vendor `mti` to mark the toolchain as MIPS32r2 default.
We support both big endian and little endian flavor:
mips-mti-none-elf
mipsel-mti-none-elf
[Debuginfo] Force enum `DISCR_*` to `static const u64` to allow for inspection via LLDB
see [here](https://rust-lang.zulipchat.com/#narrow/channel/317568-t-compiler.2Fwg-debugging/topic/Revamping.20Debuginfo/near/486614878) for more info.
This change mainly helps `*-msvc` debugged with LLDB. Currently, LLDB cannot inspect `static` struct fields, so the intended visualization for enums is only borderline functional, and niche enums with ranges of discriminant cannot be determined at all .
LLDB *can* inspect `static const` values (though for whatever reason, non-enum/non-u64 consts don't work).
This change adds the `LLVMRustDIBuilderCreateQualifiedType` to the rust FFI layer to wrap the discr type with a `const` modifier, as well as forcing all generated integer enum `DISCR_*` values to be u64's. Those values will only ever be used by debugger visualizers anyway, so it shouldn't be a huge deal, but I left a fixme comment for it just in case.. The `tag` also still properly reflects the discriminant type, so no information is lost.
turn rustc_box into an intrinsic
I am not entirely sure why this was made a special magic attribute, but an intrinsic seems like a more natural way to add magic expressions to the language.
Pass the arch rather than full target name to windows_registry::find_tool
The full target name can be anything with custom target specs. Passing just the arch wasn't possible before cc 1.2, but is now thanks to https://github.com/rust-lang/cc-rs/pull/1285.
try-job: i686-msvc
rustc_intrinsic: support functions without body
We synthesize a HIR body `loop {}` but such bodyless intrinsics.
Most of the diff is due to turning `ItemKind::Fn` into a brace (named-field) enum variant, because it carries a `bool`-typed field now. This is to remember whether the function has a body. MIR building panics to avoid ever translating the fake `loop {}` body, and the intrinsic logic uses the lack of a body to implicitly mark that intrinsic as must-be-overridden.
I first tried actually having no body rather than generating the fake body, but there's a *lot* of code that assumes that all function items have HIR and MIR, so this didn't work very well. Then I noticed that even `rustc_intrinsic_must_be_overridden` intrinsics have MIR generated (they are filled with an `Unreachable` terminator) so I guess I am not the first to discover this. ;)
r? `@oli-obk`
Rollup of 7 pull requests
Successful merges:
- #133964 (core: implement `bool::select_unpredictable`)
- #135001 (Allow using self-contained LLD in bootstrap)
- #135055 (Report impl method has stricter requirements even when RPITIT inference gets in the way)
- #135064 (const-in-pattern: test that the PartialEq impl does not need to be const)
- #135066 (bootstrap: support `./x check run-make-support`)
- #135069 (remove unused function params)
- #135084 (Update carrying_mul_add test to tolerate `nuw`)
r? `@ghost`
`@rustbot` modify labels: rollup
const-in-pattern: test that the PartialEq impl does not need to be const
Fixes https://github.com/rust-lang/rust/issues/119398 by adding a test.
`@compiler-errors` is there some place in the code where we could add a comment saying "as a backcompat hack, here we only require `PartialEq` and not `const PartialEq`"?
r? `@compiler-errors`
Project to `TyKind::Error` when there are unconstrained non-lifetime (ty/const) impl params
It splits the `enforce_impl_params_are_constrained` function into lifetime/non-lifetime, and queryfies the latter. We can then use the result of the latter query (`Result<(), ErrorGuaranteed>`) to intercept projection and constrain the projected type to `TyKind::Error`, which ensures that we leak no ty or const vars to places that don't expect them, like `normalize_erasing_regions`.
The reason we split `enforce_impl_params_are_constrained` into two parts is because we only error for *lifetimes* if the lifetime ends up showing up in any of the associated types of the impl (e.g. we allow `impl<'a> Foo { type Assoc = (); }`). However, in order to compute the `type_of` query for the anonymous associated type of an RPITIT, we need to do trait solving (in `query collect_return_position_impl_trait_in_trait_tys`). That would induce cycles. Luckily, it turns out for lifetimes we don't even care about if they're unconstrained, since they're erased in all contexts that we are trying to fix ICEs. So it's sufficient to keep this check separated out of the query.
I think this is a bit less invasive of an approach compared to #127973. The major difference between this PR and that PR is that we queryify the check instead of merging it into the `explicit_predicates_of` query, and we use the result to taint just projection goals, rather than trait goals too. This doesn't require a lot of new tracking in `ItemCtxt` and `GenericPredicates`, and it also seems to not require any other changes to typeck like that PR did.
Fixes#123141Fixes#125874Fixes#126942Fixes#127804Fixes#130967
r? oli-obk
Improve infer (`_`) suggestions in `const`s and `static`s
Fixes https://github.com/rust-lang/rust/issues/135010.
This PR does a few things to (imo) greatly improve the error message when users write something like `static FOO: [i32; _] = [1, 2, 3]`.
Firstly, it adapts the recovery code for when we encounter `_` in a const/static to work a bit more like `fn foo() -> _`, and removes the somewhat redundant query `diagnostic_only_typeck`.
Secondly, it changes the lowering for `[T; _]` to always lower under the `feature(generic_arg_infer)` logic to `ConstArgKind::Infer`. We still issue the feature error, so it's not doing anything *observable* on the good path, but it does mean that we no longer erroneously interpret `[T; _]`'s array length as a `_` **wildcard expression** (à la destructuring assignment, like `(_, y) = expr`).
Lastly it makes the suggestions verbose and fixes (well, suppresses) a bug with stashing and suggestions.
r? oli-obk
Some type-outlives computation tweaks
Some tweaks that I wrote when investigating https://github.com/rust-lang/rust/issues/135006.
The only commit that's probably interesting here is f3646748cd (the first commit). For some reason it was concerned with filtering out param-env outlives clauses when they matched item-bound outlives clauses. However, if you look at the rest of the control flow for that function, not filtering out those bounds doesn't actually affect the behavior materially.
Pass objcopy args for stripping on OSX
When `-Cstrip` was changed in #131405 to use the bundled rust-objcopy instead of /usr/bin/strip on OSX, strip-like arguments were preserved.
But strip and objcopy are, while being the same binary, different, they have different defaults depending on which binary they are. Notably, strip strips everything by default, and objcopy doesn't strip anything by default.
Additionally, `-S` actually means `--strip-all`, so debuginfo stripped everything and symbols didn't strip anything.
We now correctly pass `--strip-debug` and `--strip-all`.
fixes#135028
try-job: aarch64-apple
try-job: dist-aarch64-apple
Do the same thing as gcc, which use the vendor `mti` to mark
the toolchain as MIPS32r2 default.
We support both big endian and little endian flavor:
mips-mti-none-elf
mipsel-mti-none-elf
taint fcx on selection errors during unsizing
With `feature(dyn_compatible_for_dispatch)` we only check for dyn-compatibility by checking the `T: Unsize<dyn Trait>` predicate during the unsizing coercions checks. If the predicate doesn't hold, we emit an error, but pretend the coercion succeeded to prevent further errors. To prevent const eval from attempting to actually perform this coercion, we need to taint the fcx after reporting the trait errors in the coercion check.
fixes https://github.com/rust-lang/rust/issues/135021
fixes https://github.com/rust-lang/rust/issues/130521
When `-Cstrip` was changed to use the bundled rust-objcopy instead of
/usr/bin/strip on OSX, strip-like arguments were preserved.
But strip and objcopy are, while being the same binary, different, they
have different defaults depending on which binary they are.
Notably, strip strips everything by default, and objcopy doesn't strip
anything by default.
Additionally, `-S` actually means `--strip-all`, so debuginfo stripped
everything and symbols didn't strip anything.
We now correctly pass `--strip-debug` and `--strip-all`.
Range metadata was disabled for amdgpu due to a backend bug. I did not
encounter any problems when removing the workaround to enable range
metadata (tried compiling `core` and `alloc`), so I assume this has
been fixed in LLVM in the last years.
Remove the workaround to re-enable range metadata.
Autodiff Upstreaming - rustc_codegen_llvm changes
Now that the autodiff/Enzyme backend is merged, this is an upstream PR for the `rustc_codegen_llvm` changes.
It also includes small changes to three files under `compiler/rustc_ast`, which overlap with my frontend PR (https://github.com/rust-lang/rust/pull/129458).
Here I only include minimal definitions of structs and enums to be able to build this backend code.
The same goes for minimal changes to `compiler/rustc_codegen_ssa`, the majority of changes there will be in another PR, once either this or the frontend gets merged.
We currently have 68 files left to merge, 19 in the frontend PR, 21 (+3 from the frontend) in this PR, and then ~30 in the middle-end.
This PR is large because it includes two of my three large files (~800 loc each). I could also first only upstream enzyme_ffi.rs, but I think people might want to see some use of these bindings in the same PR?
To already highlight the things which reviewers might want to discuss:
1) `enzyme_ffi.rs`: I do have a fallback module to make sure that we don't link rustc against Enzyme when we build rustc without autodiff support.
2) `add_panic_msg_to_global` was a pain to write and I currently can't even use it. Enzyme writes gradients into shadow memory. Pass in one float scalar? We'll allocate and return an extra float telling you how this float affected the output. Pass in a slice of floats? We'll let you allocate the vector and pass in a mutable reference to a float slice, we'll then write the gradient into that slice. It should be at least as large as your original slice, so we check that and panic if not. Currently we panic silently, but I already generate a nicer panic message with this function. I just don't know how to print it to the user. yet. I discussed this with a few rustc devs and the best we could come up with (for now), was to look for mangled panic calls in the IR and pick one, which works surprisingly reliably. If someone knows a good way to clean this up and print the panic message I'm all in, otherwise I can remove the code that writes the nicer panic message and keep the silent panic, since it's enough for soundness. Especially since this PR is already a bit larger.
3) `SanitizeHWAddress`: When differentiating C++, Enzyme can use TBAA to "understand" enums/unions, but for Rust we don't have this information. LLVM might to speculative loads which (without TBAA) confuse Enzyme, so we disable those with this attribute. This attribute is only set during the first opt run before Enzyme differentiates code. We then remove it again once we are done with autodiff and run the opt pipeline a second time. Since enums are everywhere in Rust, support for them is crucial, but if this looks too cursed I can remove these ~100 lines and keep them in my fork for now, we can then discuss them separately to make this PR simpler?
4) Duplicated llvm-opt runs: Differentiating already optimized code (and being able to do additional optimizations on the fly, e.g. for GPU code) is _the_ reason why Enzyme is so fast, so the compile time is acceptable for autodiff users: https://enzyme.mit.edu/talks/Publications/ (There are also algorithmic issues in Enzyme core which are more serious than running opt twice).
5) I assume that if we merge these minimal cg_ssa changes here already, I also need to fix the other backends (GCC and cliff) to have dummy implementations, correct?
6) *I'm happy to split this PR up further if reviewers have recommendations on how to.*
For the full implementation, see: https://github.com/rust-lang/rust/pull/129175
Tracking:
- https://github.com/rust-lang/rust/issues/124509
Provide structured suggestion for `impl Default` of type where all fields have defaults
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:28:1
|
LL | / impl Default for B {
LL | | fn default() -> Self {
LL | | B {
LL | | x: s(),
| | --- this field has a default value
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
help: to avoid divergence in behavior between `Struct { .. }` and `<Struct as Default>::default()`, derive the `Default`
|
LL ~ #[derive(Default)] struct B {
|
```
Note that above the structured suggestion also includes completely removing the manual `impl`, but the rendering doesn't.
Some small nits to the borrowck suggestions for mutating a map through index
1. Suggesting users to either use `.insert` or `.get_mut` (which do totally different things) can be a bit of a footgun, so let's make that a bit more nuanced.
2. I find the suggestion of `.get_mut(|val| { *val = whatever; })` to be a bit awkward. I changed this to be an if-let instead.
3. Fix a bug which was suppressing the structured suggestion for some mutations via the index operator on `HashMap`/`BTreeMap`.
r? estebank or reassign
E0277: suggest dereferencing function arguments in more cases
This unifies and generalizes some of the logic in `TypeErrCtxt::suggest_dereferences` so that it will suggest dereferencing arguments to function/method calls in order to satisfy trait bounds in more cases.
Previously it would only fire on reference types, and it had two separate cases (one specifically to get through custom `Deref` impls when passing by-reference, and one specifically to catch #87437). I've based the new checks loosely on what's done for `E0308` in `FnCtxt::suggest_deref_or_ref`: it will suggest dereferences to satisfy trait bounds whenever the referent is `Copy`, is boxed (& so can be moved out of the boxes), or is being passed by reference.
This doesn't make the suggestion fire in contexts other than function arguments or binary operators (which are in a separate case that this doesn't touch), and doesn't make it suggest a combination of `&`-removal and dereferences. Those would require a bit more restructuring, so I figured just doing this would be a decent first step.
Closes#90997
borrowck diagnostics: make `add_move_error_suggestions` use the HIR rather than `SourceMap`
This PR aims to fix#132806 by rewriting `add_move_error_suggestions`[^1]. Previously, it manually scanned the source text to find a leading `&`, which isn't always going to produce a correct result (see: that issue). Admittedly, the HIR visitor in this PR introduces a lot of boilerplate, but hopefully the logic at its core isn't too complicated (I go over it in the comments). I also tried a simpler version that didn't use a HIR visitor and suggested adding `ref` always, but the `&ref x` suggestions really didn't look good. As a bonus for the added complexity though, it's now able to produce nice `&`-removing suggestions in more cases.
I tried to do this such that it avoids edition-dependent checks and its suggestions can be applied together with those from the match ergonomics 2024 migration lint. I haven't added tests for that since the details of match ergonomics 2024 are still being sorted out, but I can try if desired once that's finalized.
[^1]: In brief, it fires on patterns where users try to bind by-value in such a way that moves out of a reference to a non-Copy type (including slice references with non-copy elements). The suggestions are to change the binding's mode to be by-reference, either by removing[^2] an enclosing `&`/`&mut` or adding `ref` to the binding.
[^2]: Incidentally, I find the terminology of "consider removing the borrow" a bit confusing for a suggestion to remove a `&` pattern in order to make bindings borrow rather than move. I'm not sure what a good, concise way to explain that would be though, and that should go in a separate PR anyway.
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:28:1
|
LL | / impl Default for B {
LL | | fn default() -> Self {
LL | | B {
LL | | x: s(),
| | --- this field has a default value
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
help: to avoid divergence in behavior between `Struct { .. }` and `<Struct as Default>::default()`, derive the `Default`
|
LL ~ #[derive(Default)] struct B {
|
```
Note that above the structured suggestion also includes completely removing the manual `impl`, but the rendering doesn't.
Account for C string literals and `format_args` in `HiddenUnicodeCodepoints` lint
This is stacked on #134955, and either that can land first or both of them can land together here. I split this out because this is a bit more involved of an impl.
Fixes#94945
compiler: Add a statement-of-intent to `rustc_abi`
This just documents the most basic idea of what the crate is even for in my view, rather than leaving that strewn about GitHub issues, PR reviews, and Zulip streams. In particular, I hope to make it clearer what code should go in `rustc_abi` and what should not, which is of immediate relevance to contributors.
I considered going even further and explaining ideas like "ABI compatibility", prologues, and so on. However, because of the cross-cutting nature of ABI, I think such explanations should probably live in the place for cross-cutting documents: the rustc dev guide. This is only meant to be a quick "by the way".
explicitly set float ABI for all ARM targets
We currently always set the `FloatABIType` field in the LLVM target machine to `Default`, which means LLVM infers the ARM float ABI (hard vs soft) from the LLVM target triple. This causes problems such as having to set the LLVM triple to `*-gnueabi` for our `musleabi` targets to ensure they get correctly inferred as soft-float targets. It also means rustc doesn't really know which float ABI ends up being used, which is a blocker for https://github.com/rust-lang/rust/pull/134794. So I think we should stop doing that and instead explicitly control that value. That's what this PR implements.
See [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/187780-t-compiler.2Fwg-llvm/topic/Softfloat.20ABI.2C.20hardfloat.20instructions) for more context.
Best reviewed commit-by-commit. I hope I got all those `llvm_floatabi` values right...
stabilize const_swap
libs-api FCP passed in https://github.com/rust-lang/rust/issues/83163.
However, I only just realized that this actually involves an intrinsic. The intrinsic could be implemented entirely with existing stable const functionality, but we choose to make it a primitive to be able to detect more UB. So nominating for `@rust-lang/lang` to make sure they are aware; I leave it up to them whether they want to FCP this.
While at it I also renamed the intrinsic to make the "nonoverlapping" constraint more clear.
Fixes#83163
A couple datalog/borrowck cleanups
As discussed on zulip, here's a chill one in between slightly more interesting PRs:
- I hadn't noticed there still were a couple of datalog-related modules outside of their dedicated `polonius` module (go to horn-clause jail, bonk!).
- there somehow was both a `diags` module and a `diagnostics` module.
- a couple other tiny things being renamed -- let me know what you think.
As requested I've tried to have somewhat granular commits to ease review, but the last two or three could be squashed together, since they're all related to the `diags` module (but moving its contents is less tedious to check in its own commit).
r? `@jackh726`
rustc_codegen_ssa: Buffer file writes in link_rlib
This makes this step take ~25ms on my machine (M3 Max 64GB) for Zed repo instead of ~150ms (on editor crate). Additionally it takes down the time needed for a clean cargo build of ripgrep from ~6.1s to 5.9s.
This change is mostly relevant for dev builds of crates with multiple large CGUs.
I imagine it could be quite relevant for dev scenarios on Windows, but sadly I have no way to measure that myself.
Compute liveness constraints in location-sensitive polonius
This continues the location-sensitive prototype. In this episode, we build the liveness constraints.
Reminder of the approach we're taking: we need variance data to create liveness edges in the forward/backward/both directions (respectively in the cases of covariance, contravariance, invariance) in the localized constraint graph.
This PR:
- introduces the holder for that, and for the liveness data in the correct shape: the transpose of what we're using today, "live regions per points".
- records use/drop live region variance during tracing
- records regular live region variance at the end of liveness
- records the correctly shaped live region per point matrix
- uses all of the above to compute the liveness constraints
(There's still technically one tiny part of the liveness owl left to do, but I'll leave it for a future PR: we also need to disable the NLL optimization that avoids computing liveness for locals whose types contain a region outliving a free region -- the existing constraints make it effectively live at all points; this doesn't work under polonius)
r? `@jackh726` cc `@matthewjasper`
Rollup of 4 pull requests
Successful merges:
- #134870 (Fix sentence fragment in `pin` module docs)
- #134884 (Fix typos)
- #134892 (Added codegen test for elidings bounds check when indexes are manually checked)
- #134894 (Document how to run the split Docker pipelines)
r? `@ghost`
`@rustbot` modify labels: rollup
Improve default target options for x86_64-unknown-linux-none
Without a standard library, we cannot unwind, so it should be panic=abort by default.
Additionally, it does not have std because while it is Linux, it cannot use libc, which std uses today for Linux.
Using PIE by default may be surprising to users, as shown in #134763, so I've documented it explicitly. I'm not sure if we want to count that as fixing the issue or not.
cc `@morr0ne,` as you added the target (and are the maintainer), and `@Noratrieb,` who reviewed that PR (:D).
- add a FIXME when looking for the region variance of unexpected regions
- drive-by: fix a doc comment link
- drive-by: simplify the variance match using exported variants instead
This context struct will hold data to help creating localized
constraints:
- the live regions, with the shape matching a CFG walk, indexed per
point
- the variance of these live regions, represented as the direction we'll
add the appropriate
We also add this structure to the mir typeck to record liveness data,
and make it responsible for localized constraint creation.
Avoid ICE in borrowck
Provide a fallback in `best_blame_constraint` when `find_constraint_paths_between_regions` doesn't have a result. This code is due a rework to avoid the letf-over `unwrap()`, but avoids the ICE caused by the repro.
Fix#133252.
This makes this step take ~25ms on my machine (M3 Max 64GB) for Zed repo instead of ~150ms. Additionally it takes down the time needed for a clean cargo build of ripgrep from ~6.1s to 5.9s.
This change is mostly relevant for crates with multiple large CGUs.
Implement `default_overrides_default_fields` lint
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
r? `@compiler-errors`
This is a simpler version of #134441, detecting the simpler case when a field with a default should have not been specified in the manual `Default::default()`, instead using `..` for it. It doesn't provide any suggestions, nor the checks for "equivalences" nor whether the value used in the imp being used would be suitable as a default field value.
Skip parenthesis around tuple struct field calls
The pretty-printer previously did not distinguish between named vs unnamed fields when printing a function call containing a struct field. It would print the call as `(self.fun)()` for a named field which is correct, and `(self.0)()` for an unnamed field which is redundant.
This PR changes function calls of tuple struct fields to print without parens.
**Before:**
```rust
struct Tuple(fn());
fn main() {
let tuple = Tuple(|| {});
(tuple.0)();
}
```
**After:**
```rust
struct Tuple(fn());
fn main() {
let tuple = Tuple(|| {});
tuple.0();
}
```
Skip parenthesis if `.` makes statement boundary unambiguous
There is a rule in the parser that statements and match-arms never end in front of a `.` or `?` token (except when the `.` is really `..` or `..=` or `...`). So some of the leading subexpressions that need parentheses inserted when followed by some other operator like `-` or `+`, do not need parentheses when followed by `.` or `?`.
Example:
```rust
fn main() {
loop {}.to_string() + "";
match () {
_ => loop {}.to_string() + "",
};
}
```
`-Zunpretty=expanded` before:
```console
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
(loop {}).to_string() + "";
match () { _ => (loop {}).to_string() + "", };
}
```
After:
```console
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
loop {}.to_string() + "";
match () { _ => loop {}.to_string() + "", };
}
```
Make `ty::Error` implement all auto traits
I have no idea what's up with the crashes test I fixed--I really don't want to look into it since it has to do something with borrowck and multiple layers of opaques. I think the underlying idea of allowing error types to implement all auto traits is justified though.
Fixes#134796Fixes#131050
r? lcnr
Add a compiler intrinsic to back `bigint_helper_methods`
cc https://github.com/rust-lang/rust/issues/85532
This adds a new `carrying_mul_add` intrinsic, to implement `wide_mul` and `carrying_mul`.
It has fallback MIR for all types -- including `u128`, which isn't currently supported on nightly -- so that it'll continue to work on all backends, including CTFE.
Then it's overridden in `cg_llvm` to use wider intermediate types, including `i256` for `u128::carrying_mul`.
Spruce up the docs of several queries related to the type/trait system and const eval
- Editorial
- Proper rustdoc summary/synopsis line by making use of extra paragraphs: Leads to better rendered output on module pages, in search result lists and overall, too
- Use rustdoc warning blocks for admonitions of the form "do not call / avoid calling this query directly"
- Use intra-doc links of the form ``[`Self::$query`]`` to cross-link queries. Indeed, such links are generally a bit brittle due to the existence of `TyCtxtFeed` which only contains a subset of queries. Therefore the docs of `feedable` queries cannot cross-link to non-`feedable` ones. I'd say it's fine to use intra-doc links despite the potential/unlikely occasional future breakage (if a query with the aforementioned characteristics becomes `feedable`). `Self::` is nicer than `TyCtxt::` (which would be more stable) since it accounts for other contexts like `TyCtxt{Feed,At,Ensure{,WithValue}}`
- Informative
- Generally add, flesh out and correct some doc comments
- Add *Panic* sections (to a few selected queries only). The lists of panics aren't necessarily exhaustive and focus on the more "obvious" or "important" panics.
- Where applicable add a paragraph calling attention to the relevant [`#[rustc_*]` TEST attribute](https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#rustc_-test-attributes)
The one non-doc change (it's internal and not observable):
Be even more defensive in `query constness`'s impl (spiritual follow-up to #134122) (see self review comment).
Fixes#133494.
r\? **any**(compiler-errors, oli-obk)
ptr::copy: fix docs for the overlapping case
Fixes https://github.com/rust-lang/unsafe-code-guidelines/issues/549
As discussed in that issue, it doesn't make any sense for `copy` to read a byte via `src` after it was already written via `dst`. The entire point of this method is that is copies correctly even if they overlap, and that requires always reading any given location before writing it.
Cc `@rust-lang/opsem`
[macro_metavar_expr_concat] Fix#128346Fix#128346Fix#131393
The syntax is invalid in both issues so I guess that theoretically the compiler should have aborted early.
This PR tries to fix a local problem but let me know if there are better options.
cc `@petrochenkov` if you are interested
fix default-backtrace-ice test
when running `tests/ui/panics/default-backtrace-ice.rs locally it gave this error:
```
failures:
---- [ui] tests/ui/panics/default-backtrace-ice.rs stdout ----
Saved the actual stderr to "/home/jyn/src/rust3/build/x86_64-unknown-linux-gnu/test/ui/panics/default-backtrace-ice/default-backtrace-ice.stderr"
diff of stderr:
7
8 aborting due to `-Z treat-err-as-bug=1`
9 stack backtrace:
- (end_short_backtrace)
- (begin_short_backtrace)
- (end_short_backtrace)
- (begin_short_backtrace)
+ [... omitted 22 frames ...]
+
```
(note that you must *not* use --bless; we previously did not have an error annotation to verify it was a full backtrace instead of a short backtrace.)
this is a regression from setting RUST_BACKTRACE=1 by default in https://github.com/rust-lang/rust/pull/134743. we need to turn off the new behavior when running UI tests so that they reflect our dist compiler. normally that's done by checking `sess.unstable_opts.ui_testing`, but this happens extremely early in the compiler before we've expanded arg files. do an extremely simple hack that doesn't work in all cases - we don't need it to work in all cases, only when running UI tests.
cc https://github.com/rust-lang/rust/pull/129658#issuecomment-2561988081
r? `@jieyouxu`
when running `tests/ui/panics/default-backtrace-ice.rs locally it gave this error:
```
failures:
---- [ui] tests/ui/panics/default-backtrace-ice.rs stdout ----
Saved the actual stderr to "/home/jyn/src/rust3/build/x86_64-unknown-linux-gnu/test/ui/panics/default-backtrace-ice/default-backtrace-ice.stderr"
diff of stderr:
7
8 aborting due to `-Z treat-err-as-bug=1`
9 stack backtrace:
- (end_short_backtrace)
- (begin_short_backtrace)
- (end_short_backtrace)
- (begin_short_backtrace)
+ [... omitted 22 frames ...]
+
```
this is a regression from setting RUST_BACKTRACE=1 by default. we need to turn off the new behavior when running UI tests so that they reflect our dist compiler. normally that's done by checking `sess.unstable_opts.ui_testing`, but this happens extremely early in the compiler before we've expanded arg files. do an extremely simple hack that doesn't work in all cases - we don't need it to work in all cases, only when running UI tests.
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Without a standard library, we cannot unwind, so it should be
panic=abort by default.
Additionally, it does not have std because while it is
Linux, it cannot use libc, which std uses today for Linux.
Update `#[coverage(..)]` attribute error messages to match the current implementation
The allowed positions for `#[coverage(..)]` attributes were expanded by #126721, but the corresponding error messages were never updated to reflect the new behaviour.
Part of #134749.
Default to short backtraces for dev builds of rustc itself
A dev build almost certainly means that whoever's built the compiler has the opportunity to rerun it to collect a more complete trace. So we don't need to default to a complete trace; we should hide irrelevant details by default.
A dev build almost certainly means that whoever's built the compiler
has the opportunity to rerun it to collect a more complete trace. So
we don't need to default to a complete trace; we should hide irrelevant
details by default.
Correctly note item kind in `NonConstFunctionCall` error message
Don't just call everything a "`fn`". This is more consistent with the error message we give for conditionally-const items, which do note the item's def kind.
r? fmease, this is a prerequisite for making those `~const PartialEq` error messages better. Re-roll if you're busy or don't want to review this.
Begin to implement type system layer of unsafe binders
Mostly TODOs, but there's a lot of match arms that are basically just noops so I wanted to split these out before I put up the MIR lowering/projection part of this logic.
r? oli-obk
Tracking:
- https://github.com/rust-lang/rust/issues/130516
Use `#[derive(Default)]` instead of manual `impl` when possible
While working on #134175 I noticed a few manual `Default` `impl`s that could be `derive`d instead. These likely predate the existence of the `#[default]` attribute for `enum`s.
Revert stabilization of the `#[coverage(..)]` attribute
Due to a process mixup, the PR to stabilize the `#[coverage(..)]` attribute (#130766) was merged while there are still outstanding concerns. The default action in that situation is to revert, and the feature is not sufficiently urgent or uncontroversial to justify special treatment, so this PR reverts that stabilization.
---
- A key point that came up in offline discussions is that unlike most user-facing features, this one never had a proper RFC, so parts of the normal stabilization process that implicitly rely on an RFC break down in this case.
- As the implementor and de-facto owner of the feature in its current form, I would like to think that I made good choices in designing and implementing it, but I don't feel comfortable proceeding to stabilization without further scrutiny.
- There hasn't been a clear opportunity for T-compiler to weigh in or express concerns prior to stabilization.
- The stabilization PR cites a T-lang FCP that occurred in the tracking issue, but due to the messy design and implementation history (and lack of a clear RFC), it's unclear what that FCP approval actually represents in this case.
- At the very least, we should not proceed without a clear statement from T-lang or the relevant members about the team's stance on this feature, especially in light of the other concerns listed here.
- The existing user-facing documentation doesn't clearly reflect which parts of the feature are stable commitments, and which parts are subject to change. And there doesn't appear to be a clear consensus anywhere about where that line is actually drawn, or whether the chosen boundary is acceptable to the relevant teams and individuals.
- For example, the [stabilization report comment](https://github.com/rust-lang/rust/issues/84605#issuecomment-2166514660) mentions that some aspects are subject to change, but that text isn't consistent with my earlier comments, and there doesn't appear to have been any explicit discussion or approval process.
- [The current reference text](https://github.com/rust-lang/reference/blob/4dfaa4f/src/attributes/coverage-instrumentation.md) doesn't mention this distinction at all, and instead simply describes the current implementation behaviour.
- When the implementation was changed to its current form, the associated user-facing error messages were not updated, so they still refer to the attribute only being allowed on functions and closures.
- On its own, this might have been reasonable to fix-forward in the absence of other concerns, but the fact that it never came up earlier highlights the breakdown in process that has occurred here.
---
Apologies to everyone who was excited for this stabilization to land, but unfortunately it simply isn't ready yet.
cleanup `TypeVerifier`
We should merge it with the `TypeChecker` as we no longer bail in cases where it encounters an error since #111863.
It's quite inconsistent whether a check lives in the verifier or the `TypeChecker`, so this feels like a quite impactful cleanup. I expect that for this we may want to change the `TypeChecker` to also be a MIR visitor 🤔 this is non-trivial so I didn't fully do it in this PR.
Best reviewed commit by commit.
r? `@compiler-errors` feel free to reassign however
Rollup of 6 pull requests
Successful merges:
- #130289 (docs: Permissions.readonly() also ignores root user special permissions)
- #134583 (docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code)
- #134611 (Align `{i686,x86_64}-win7-windows-msvc` to their parent targets)
- #134629 (compiletest: Allow using a specific debugger when running debuginfo tests)
- #134642 (Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.)
- #134660 (Fix spacing of markdown code block fences in compiler rustdoc)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix spacing of markdown code block fences in compiler rustdoc
Two place have misaligned open and close ```` ``` ````.
I noticed these because one of them disrupted syntax highlighting in my editor for the rest of the file as I was working on a different change.
<p align="center"><img src="https://github.com/user-attachments/assets/5de21d08-c30c-4e9c-8587-e83b988b9db5" width="500"></p>
Align `{i686,x86_64}-win7-windows-msvc` to their parent targets
There were some changes to `{i686,x86_64}-pc-windows-msvc`, include them in the backward compatibility targets as well.
CC `@roblabla`
Use `PtrMetadata` instead of `Len` in slice drop shims
I tried to do a bigger change in #134297 which didn't work, so here's the part I really wanted: Removing another use of `Len`, in favour of `PtrMetadata`.
Split into two commits where the first just adds a test, so you can look at the second commit to see how the drop shim for an array changes with this PR.
Reusing the same reviewer from the last one:
r? BoxyUwU
coroutine_clone: add comments
I was very surprised to learn that coroutines can be cloned. This has non-trivial semantic consequences that I do not think have been considered. Lucky enough, it's still unstable. Let's add some comments and pointers so we hopefully become aware when a MIR opt actually is in conflict with this.
Cc `@rust-lang/wg-mir-opt`
Explain why a type is not eligible for `impl PointerLike`.
The rules were baffling when I ran in to them trying to add some impls (to `std`, not my own code, as it happens), so I made the compiler explain them to me.
The logic of the successful cases is unchanged, but I did rearrange it to reverse the order of the primitive and `Adt` cases; this makes producing the errors easier. I'm still not very familiar with `rustc` internals, so let me know if there's a better way to do any of this.
This also adds test coverage for which impls are accepted or rejected, which I didn't see any of already.
The PR template tells me I should consider mentioning a tracking issue, but there isn't one for `pointer_like_trait`, so I'll mention `dyn_star`: #102425
Use E0665 for missing `#[default]` on enum and update doc
The docs for E0665 when doing `#[derive(Default]` on an `enum` previously didn't mention `#[default]` at all, or made a distinction between unit variants, that can be annotated, and tuple or struct variants, which cannot.
E0665 was not being emitted, we now use it for the same error it belonged to before.
```
error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
--> $DIR/macros-nonfatal-errors.rs:42:10
|
LL | #[derive(Default)]
| ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | | Foo,
LL | | Bar,
LL | | }
| |_- this enum needs a unit variant marked with `#[default]`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Foo,
| ++++++++++
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Bar,
| ++++++++++
```
update `rustc_index_macros` feature handling
It seems that cargo can't [conditionally propagate features](214587c89d/compiler/rustc_index/Cargo.toml (L20)) if they were enabled by default on the target crate, but disabled with `default-features = false` in the current/parent crate.
Fixes#118129
Foundations of location-sensitive polonius
I'd like to land the prototype I'm describing in the [polonius project goal](https://github.com/rust-lang/rust-project-goals/issues/118). It still is incomplete and naive and terrible but it's working "well enough" to consider landing.
I'd also like to make review easier by not opening a huge PR, but have a couple small-ish ones (the +/- line change summary of this PR looks big, but >80% is moving datalog to a single place).
This PR starts laying the foundation for that work:
- it refactors and collects 99% of the old datalog fact gen, which was spread around everywhere, into a single dedicated module. It's still present at 3 small places (one of which we should revert anyways) that are kinda deep within localized components and are not as easily extractable into the rest of fact gen, so it's fine for now.
- starts introducing the localized constraints, the building blocks of the naive way of implementing the location-sensitive analysis in-tree, which is roughly sketched out in https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/ and https://smallcultfollowing.com/babysteps/blog/2023/09/29/polonius-part-2/ but with a different vibe than per-point environments described in these posts, just `r1@p: r2@q` constraints.
- sets up the skeleton of generating these localized constraints: converting NLL typeck constraints, and creating liveness constraints
- introduces the polonius dual to NLL MIR to help development and debugging. It doesn't do much currently but is a way to see these localized constraints: it's an NLL MIR dump + a dumb listing of the constraints, that can be dumped with `-Zdump-mir=polonius -Zpolonius=next`. Its current state is not intended to be a long-term thing, just for testing purposes -- I will replace its contents in the future with a different approach (an HTML+js file where we can more easily explore/filter/trace these constraints and loan reachability, have mermaid graphs of the usual graphviz dumps, etc).
I've started documenting the approach in this PR, I'll add more in the future. It's quite simple, and should be very clear when more constraints are introduced anyways.
r? `@matthewjasper`
Best reviewed per commit so that the datalog move is less bothersome to read, but if you'd prefer we separate that into a different PR, I can do that (and michael has offered to review these more mechanical changes if it'd help).