Sync rustc_codegen_cranelift
Since the last sync there have mostly been fixes of various sorts. I also changed cg_clif from using a custom driver to `-Zcodegen-backend` when built as separate project. When built as part of rust it was already using `-Zcodegen-backend`.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
rustc: Stricter checking for #[link] attributes
A subset of https://github.com/rust-lang/rust/pull/94962 that doesn't touch library renaming/reordering/deduplication.
`#[link]` attributes are checked for all kinds of unexpected arguments inside them.
I also tried to make wording for these errors more consistent, that's why some existing errors are changed, including errors for command line `-l` options.
Spans are also made more precise where possible.
Allow the unused_macro_rules lint for now
It was newly added by #96150 with warn by default, which is great as it gave exposure to the community, and their feedback gave me ideas for improvements.
Allowing the lint is good for two reasons:
* It makes the transition easier as e.g. allow directives won't fire the unknown lint warning once it is turned to warn by default in the future. The [commit that allowed the lint in fuchsia](https://fuchsia.googlesource.com/fuchsia/+/9d8f96517c3963de2f0e25598fd36061914524cd%5E%21/) had to allow unknown lints for example.
This is especially important compared to other lints in the unused group,
because the _ prefix trick doesn't exist for macro rules, allowing is the
only option (either of unused_macro_rules, or of the entire unused group,
but that is not as informative to readers). Allowing the lint also makes it
possible to work on possible heuristics for disabling the macro in specific
cases.
* It gives time for implementing heuristics for when to suppress the lint, e.g.
when `compile_error!` is invoked by that arm (so it's only there to yield an error).
See: https://github.com/rust-lang/rust/pull/96150#issuecomment-1126599107
I would also like this to be backported to the 1.62 beta branch (cc #97016).
Add EarlyBinder
Chalk has no concept of `Param` (e0ade19d13/chalk-ir/src/lib.rs (L579)) or `ReEarlyBound` (e0ade19d13/chalk-ir/src/lib.rs (L1308)). Everything is just "bound" - the equivalent of rustc's late-bound. It's not completely clear yet whether to move everything to the same time of binder in rustc or add `Param` and `ReEarlyBound` in Chalk.
Either way, tracking when we have or haven't already substituted out these in rustc can be helpful.
As a first step, I'm just adding a `EarlyBinder` newtype that is required to call `subst`. I also add a couple "transparent" `bound_*` wrappers around a couple query that are often immediately substituted.
r? `@nikomatsakis`
Initial work on Miri permissive-exposed-provenance
Rustc portion of the changes for portions of a permissive ptr-to-int model for Miri. The main changes here are changing `ptr_get_alloc` and `get_alloc_id` to return an Option, and also making ptr-to-int casts have an expose side effect.
This makes the transition easier as e.g. allow directives
won't fire the unknown lint warning once it is turned to
warn by default in the future. This is especially
important compared to other lints in the unused group
because the _ prefix trick doesn't exist for macro rules,
so allowing is the only option (either of unused_macro_rules,
or of the entire unused group, but that is not as informative
to readers). Allowing the lint also makes it possible to work
on possible heuristics for disabling the macro in specific
cases.
Add MVP LLVM based mingw-w64 targets
Fixes https://github.com/rust-lang/rust/issues/72241
Those are `rustc` side changes to create working x86_64 and AArch64 Rustc hosts and targets.
Apart from this PR changes to various crates are required which I'll do once this is accepted.
I'm expecting more changes on `rustc` side later on as I cannot even run full testsuite at this moment because passing JSON spec breaks paths in various tests.
Tier 3 policy:
> A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
I pledge to do my best maintaining it, MSYS2 is one of interested consumers so it should have enough testing (after the releases).
> Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
This triple name was discussed at [`t-compiler/LLVM+mingw-w64 Windows targets`](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/LLVM.2Bmingw-w64.20Windows.20targets)
> Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
I think the explanation in platform support doc is enough to make this aspect clear.
> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
It's using open source tools only.
> The target must not introduce license incompatibilities.
It's even more liberal than already existing `*-pc-windows-gnu`.
> Anything added to the Rust repository must be under the standard Rust license (MIT OR Apache-2.0).
Understood.
> The target must not cause the Rust tools or libraries built for any other host (even when supporting cross-compilation to the target) to depend on any new dependency less permissive than the Rust licensing policy. This applies whether the dependency is a Rust crate that would require adding new license exceptions (as specified by the tidy tool in the rust-lang/rust repository), or whether the dependency is a native library or binary. In other words, the introduction of the target must not cause a user installing or running a version of Rust or the Rust tools to be subject to any new license requirements.
There are no new dependencies/features required.
> Compiling, linking, and emitting functional binaries, libraries, or other code for the target (whether hosted on the target itself or cross-compiling from another target) must not depend on proprietary (non-FOSS) libraries. Host tools built for the target itself may depend on the ordinary runtime libraries supplied by the platform and commonly used by other applications built for the target, but those libraries must not be required for code generation for the target; cross-compilation to the target must not require such libraries at all. For instance, rustc built for the target may depend on a common proprietary C runtime library or console output library, but must not depend on a proprietary code generation library or code optimization library. Rust's license permits such combinations, but the Rust project has no interest in maintaining such combinations within the scope of Rust itself, even at tier 3.
As previously said it's using open source tools only.
> "onerous" here is an intentionally subjective term. At a minimum, "onerous" legal/licensing terms include but are not limited to: non-disclosure requirements, non-compete requirements, contributor license agreements (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, requirements conditional on the employer or employment of any particular Rust developers, revocable terms, any requirements that create liability for the Rust project or its developers or users, or any requirements that adversely affect the livelihood or prospects of the Rust project or its developers or users.
There are no such terms present/
> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
I'm not the reviewer here.
> This requirement does not prevent part or all of this policy from being cited in an explicit contract or work agreement (e.g. to implement or maintain support for a target). This requirement exists to ensure that a developer or team responsible for reviewing and approving a target does not face any legal threats or obligations that would prevent them from freely exercising their judgment in such approval, even if such judgment involves subjective matters or goes beyond the letter of these requirements.
Again I'm not the reviewer here.
> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (core for most targets, alloc for targets that can support dynamic memory allocation, std for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running binaries, or running tests (even if they do not pass), the documentation must explain how to run such binaries or tests for the target, using emulation if possible or dedicated hardware if necessary.
Building is described in platform support doc, running tests doesn't work right now (without hacks) because Rust's build system doesn't seem to support testing targets built from `.json`.
Docs will be updated once this lands in beta allowing master branch to build and run tests without `.json` files.
> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via `@)` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
Understood.
> Backlinks such as those generated by the issue/PR tracker when linking to an issue or PR are not considered a violation of this policy, within reason. However, such messages (even on a separate repository) must not generate notifications to anyone involved with a PR who has not requested such notifications.
Understood.
> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
I believe I didn't break any other target.
> In particular, this may come up when working on closely related targets, such as variations of the same architecture with different features. Avoid introducing unconditional uses of features that another variation of the target may not have; use conditional compilation or runtime detection, as appropriate, to let each target run code supported by that target.
I think there are no such problems in this PR.
Drop tracking: handle invalid assignments better
Previously this test case was crashing with an index out of bounds error deep in the call to `needs_drop`. We avoid this by detecting clearly invalid assignees in the `mutate` callback and ignoring these.
Previously this test case was crashing with an index out of bounds error
deep in the call to `needs_drop`. We avoid this by detecting clearly
invalid assignees in the `mutate` callback and ignoring these.
Fix e_flags for 32-bit MIPS targets in generated object file
In #95604 the compiler started generating a temporary symbols.o which is added to the linker invocation. This object file has an `e_flags` which is invalid for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking these targets with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L76-L79) with
```
rust-lld: error: foo-cgu.0.rcgu.o: ABI 'o32' is incompatible with target ABI 'n64'
```
because it omits the ABI bits (`EF_MIPS_ABI_O32`) so lld assumes it's using the N64 ABI. This breaks linking on nightly for the out-of-tree [mipsel-sony-psx target](https://github.com/ayrtonm/psx-sdk-rs/issues/9), the builtin mipsel-sony-psp target (cc `@overdrivenpotato)` and probably any other 32-bit MIPS target using lld.
This PR sets the ABI in `e_flags` to O32 since that's the only ABI for 32-bit MIPS that LLVM supports. It also sets other `e_flags` bits based on the target to avoid similar issues with the object file arch and PIC. I had to bump the object crate version since some of these constants were [added recently](https://github.com/gimli-rs/object/pull/433). I'm not sure if this PR needs a test, but I can confirm that it fixes the linking issue on both targets I mentioned.
Gracefully handle normalization failures in the prospective inliner cycle detector
Preliminary work for adding the regression test in #96950 to our test suite (it was flaky on glacier).
If this PR solves the flakiness on glacier, we can then merge #96950
don't encode only locally used attrs
Part of https://github.com/rust-lang/compiler-team/issues/505.
We now filter builtin attributes before encoding them in the crate metadata in case they should only be used in the local crate. To prevent accidental misuse `get_attrs` now requires the caller to state which attribute they are interested in. For places where that isn't trivially possible, I've added a method `fn get_attrs_unchecked` which I intend to remove in a followup PR.
After this pull request landed, we can then slowly move all attributes to only be used in the local crate while being certain that we don't accidentally try to access them from extern crates.
cc https://github.com/rust-lang/rust/pull/94963#issuecomment-1082924289
diagnostics: port more diagnostics to derive + support for `()` fields
- Extend diagnostic derive so that spanless subdiagnostics (e.g. some uses of `help`/`note`) can be applied via attributes to fields of type `()` (currently spanless subdiagnostics are applied via attributes on the diagnostic struct itself). A consequence of this is that `Option<()>` fields can be used to represent optional spanless subdiagnostics, which are sometimes useful (e.g. for a `help` that should only show on nightly builds).
- Simplify the "explicit generic args with impl trait" diagnostic struct (from #96760) using support for `Option<()>` spanless subdiagnostics.
- Change `DiagnosticBuilder::set_arg`, used to provide context for Fluent messages, so that it takes anything that implements `IntoDiagnosticArg`, rather than `DiagnosticArgValue` - this improves the ergonomics of manual implementations of `SessionDiagnostic` which are translatable.
- Port "the type parameter `T` must be explicitly specified", "manual implementations of `X` are experimental", "could not resolve substs on overridden impl" diagnostics to diagnostic structs.
- When testing macros from `rustc_macros` in `ui-fulldeps` tests, sometimes paths from the compiler source tree can be shown in error messages - these need to be normalized in `compiletest`.
r? `@oli-obk`
cc `@pvdrz`
Port the "the type parameter `T` must be explicitly specified"
diagnostic to using a diagnostic struct.
Signed-off-by: David Wood <david.wood@huawei.com>
Manual implementors of translatable diagnostics will need to call
`set_arg`, not just the derive, so make this function a bit more
ergonomic by taking `IntoDiagnosticArg` rather than
`DiagnosticArgValue`.
Signed-off-by: David Wood <david.wood@huawei.com>
Using new support for spanless subdiagnostics from `()` fields in the
diagnostic derive, simplify the "explicit generic args with impl trait"
diagnostic's struct.
Signed-off-by: David Wood <david.wood@huawei.com>
Type attributes could previously be used to support spanless
subdiagnostics but these couldn't easily be made optional in the same
way that spanned subdiagnostics could by using a field attribute on a
field with an `Option<Span>` type. Spanless subdiagnostics can now be
specified on fields with `()` type or `Option<()>` type.
Signed-off-by: David Wood <david.wood@huawei.com>
Remove `PartialOrd`/`Ord` impl for `PlaceRef`
This is a new attempt at #93315. It removes one usage
of the `Ord` impl for `DefId`, which should make it easier
to eventually remove that impl.
Add `sub_ptr` on pointers (the `usize` version of `offset_from`)
We have `add`/`sub` which are the `usize` versions of `offset`, this adds the `usize` equivalent of `offset_from`. Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`.
As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives. That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.
This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE. It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
Like we have `add`/`sub` which are the `usize` version of `offset`, this adds the `usize` equivalent of `offset_from`. Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`.
As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives. That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.
This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE. It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
Implement a lint to warn about unused macro rules
This implements a new lint to warn about unused macro rules (arms/matchers), similar to the `unused_macros` lint added by #41907 that warns about entire macros.
```rust
macro_rules! unused_empty {
(hello) => { println!("Hello, world!") };
() => { println!("empty") }; //~ ERROR: 1st rule of macro `unused_empty` is never used
}
fn main() {
unused_empty!(hello);
}
```
Builds upon #96149 and #96156.
Fixes#73576
Gracefully fail to resolve associated items instead of `delay_span_bug`.
`codegen_fulfill_obligation` is used during instance resolution for trait items.
In case of insufficient normalization issues during MIR inlining, it caused ICEs.
It's better to gracefully refuse to resolve the associated item, and let the caller decide what to do with this.
Split from https://github.com/rust-lang/rust/pull/91743Closes#69121Closes#73021Closes#88599Closes#93008Closes#93248Closes#94680Closes#96170
r? `@oli-obk`
tighten sanity checks around Scalar and ScalarPair
While investigating https://github.com/rust-lang/rust/issues/96185 I noticed codegen has tighter sanity checks here than Miri does, so I added some more assertions. Strangely, some of them fail, so I also needed to add a HACK... that is probably worth looking into.
This does not fix that issue, but it changes the ICE messages, making it quite clear that we have a scalar whose size is not the same as that of the surrounding layout.
r? `@oli-obk`
logging: add env var to control verbose scope entry/exit logging
~~This got removed in https://github.com/rust-lang/rust/pull/75143, and I find this makes long traces a lot harder to read, so I propose we add this back.~~
Example trace:
```
│ │ ├─0ms INFO rustc_const_eval::interpret::step return
│ │ ├─0ms INFO rustc_const_eval::interpret::eval_context popping stack frame (returning from function)
│ │┌┘rustc_const_eval::interpret::eval_context::frame std::ptr::mut_ptr::<impl *mut u8>::guaranteed_eq
│ ├┘rustc_const_eval::interpret::eval_context::frame std::ptr::mut_ptr::<impl *mut u8>::is_null
│ ├─1ms INFO rustc_const_eval::interpret::step // executing bb2
│ ├─1ms INFO rustc_const_eval::interpret::step StorageDead(_4)
│ ├─1ms INFO rustc_const_eval::interpret::step StorageDead(_2)
│ ├─1ms INFO rustc_const_eval::interpret::step return
│ ├─1ms INFO rustc_const_eval::interpret::eval_context popping stack frame (returning from function)
│┌┘rustc_const_eval::interpret::eval_context::frame std::ptr::mut_ptr::<impl *mut u8>::is_null
├┘rustc_const_eval::interpret::eval_context::frame std::sys_common::thread_local_dtor::register_dtor_fallback::run_dtors
├─178ms INFO rustc_const_eval::interpret::step // executing bb2
├─178ms INFO rustc_const_eval::interpret::step StorageDead(_5)
```
r? `@oli-obk`
Fix inaccurate function name in `rustc_const_eval` docs
Looks to me like this fixes#85513. I had trouble making a intra-docs link to `eval_place_to_op` work, though...
Use lifetimes on type-alias-impl-trait used in function signatures to infer output type lifetimes
fixes https://github.com/rust-lang/rust/issues/96564
TLDR:
```rust
fn execute(ty: Ty<'_>) -> &str { todo!() }
```
(`Ty` being a type alias impl trait) used to produce the following error before this PR
```
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> src/lib.rs:4:27
|
4 | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^
|
= note: lifetimes appearing in an associated type are not considered constrained
```
Remove hacks in `make_token_stream`.
`make_tokenstream` has three commented hacks, and a comment at the top
referring to #67062. These hacks have no observable effect, at least as judged
by running the test suite. The hacks were added in #82608, with an explanation
[here](https://github.com/rust-lang/rust/pull/82608#issuecomment-812877329). It
appears that one of the following is true: (a) they never did anything useful,
(b) they do something useful but we have no test coverage for them, or (c)
something has changed in the meantime that means they are no longer necessary.
This commit removes the hacks and the comments, in the hope that (b) is not
true.
r? `@Aaron1011`
Use `FxIndexSet` to avoid sorting fake borrows
This fixes#96449, but I haven't yet been able to
make the reproducer work using `#[cfg]` attributes,
so we can't use the 'revision' infra to write a test
The previous implementation relied on sorting by `PlaceRef`.
This requires sorting by a `DefId`, which uses untracked state
(see #93315)
In #95604 the compiler started generating a temporary symbols.o which is added
to the linker invocation. This object file has an `e_flags` which may be invalid
for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking
with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L79) with
```
rust-lld: error: foo-cgu.0.rcgu.o: ABI 'o32' is incompatible with target ABI 'n64'
```
because it omits the ABI bits (EF_MIPS_ABI_O32) so lld assumes it's using the
N64 ABI. This breaks linking on nightly for the out-of-tree [psx
target](https://github.com/ayrtonm/psx-sdk-rs/issues/9), the builtin
mipsel-sony-psp target (cc @overdrivenpotato) and any other 32-bit MIPS
target using lld.
This PR sets the ABI in `e_flags` to O32 since that's the only ABI for 32-bit
MIPS that LLVM supports. It also sets other `e_flags` bits based on the target.
I had to bump the object crate version since some of these constants were [added
recently](https://github.com/gimli-rs/object/pull/433). I'm not sure if this
PR needs a test, but I can confirm that it fixes the linking issue on both
targets I mentioned.
Handle mismatched generic param kinds in trait impls betterly
- Check that generic params on a generic associated type are the same as in the trait definition
- Check that const generics are not used in place of type generics (and the other way round too)
r? `@lcnr`
Check hidden types for well formedness at the definition site instead of only at the opaque type itself
work towards #90409 . We'll need to look into closure and generator bodies of closures and generators nested inside the hidden type in order to fix that. In hindsight this PR is not necessary for that, but it may be a bit easier with it and we'll get better diagnostics from it on its own.
make sure ScalarPair enums have ScalarPair variants; add some layout sanity checks
`@eddyb` suggested that it might be reasonable for `ScalarPair` enums to simply adjust the ABI of their variants accordingly, such that the layout invariant Miri expects actually holds. This PR implements that. I should note though that I don't know much about this layout computation code and what non-Miri consumers expect from it, so tread with caution!
I also added a function to sanity-check that computed layouts are internally consistent. This helped a lot in figuring out the final shape of this PR, though I am also not 100% sure that these sanity checks are the right ones.
Cc `@oli-obk`
Fixes https://github.com/rust-lang/rust/issues/96221
Properly fix#96638Closes#96638
The main part of this change is `Error::Invalid` now returns both the input and arg indices. However, I realized the code here was kind of confusing and not internally consistent (and thus I was having trouble getting the right behavior). So I've also switched `input_indices` and `arg_indices` to more closely match some naming in `checks` (although I think a more thorough cleanup there could be beneficial). I've added comments, but essentially `input_indices` refers to *user provided* inputs and `arg_indices` refers to *expected* args.
Do not lint on explicit outlives requirements from external macros.
The current implementation of the list rightfully skipped where predicates from external macros.
However, if the where predicate came from the current macro but the bounds were from an external macro, the lint still fired.
Closes https://github.com/rust-lang/rust/issues/96640
This fixes#96449, but I haven't yet been able to
make the reproducer work using `#[cfg]` attributes,
so we can't use the 'revision' infra to write a test
The previous implementation relied on sorting by `PlaceRef`.
This requires sorting by a `DefId`, which uses untracked state
(see #93315)
Fortify handing of where bounds on trait & trait alias definitions
Closes https://github.com/rust-lang/rust/issues/96664
Closes https://github.com/rust-lang/rust/issues/96665
Since https://github.com/rust-lang/rust/pull/93803, when listing all bounds and predicates we now need to account for the possible presence of predicates on any of the generic parameters. Both bugs were hidden by the special handling of bounds at the generic parameter declaration position.
Trait alias expansion used to confuse predicates on `Self` and where predicates.
Exiting too late when listing all the bounds caused a cycle error.
Optimize switch sources representation and usage
* Avoid constructing switch sources unless necessary - switch sources are used by backward analysis with a custom switch int edge effects, but are otherwise unnecessarily computed.
* Use sparse representation of switch sources to avoid quadratic space overhead.
Some subst cleanup
Two separate things here. Both changes are useful for some refactoring I'm doing to add an "EarlyBinder" newtype. (Part of chalkification).
1) Remove `subst_spanned` and just use `subst`. It wasn't used much anyways. In practice, I think we can probably get most of the info just from the actual error message. If not, outputting logs should do the trick. (The specific line probably wouldn't help much anyways).
2) Call `.subst()` before `replace_bound_vars_with_fresh_vars` and `erase_late_bound_regions` in three places that do the opposite. I think there might have been some time in the past that the order here matter for something, but this shouldn't be the case anymore. Conceptually, it makes more sense to the of the *early bound* vars on `fn`s as "outside" the late bound vars.
Actually fix ICE from #96583
PR #96746 fixed a very similar bug, so the same logic is used in a different place.
I originally concluded that the two issues (#96583 and #96738) were identical by comparing the backtrace, but I didn't look close enough.
Warn on unused `#[doc(hidden)]` attributes on trait impl items
[Zulip conversation](https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/.E2.9C.94.20Validy.20checks.20for.20.60.23.5Bdoc.28hidden.29.5D.60).
Whether an associated item in a trait impl is shown or hidden in the documentation entirely depends on the corresponding item in the trait declaration. Rustdoc completely ignores `#[doc(hidden)]` attributes on impl items. No error or warning is emitted:
```rust
pub trait Tr { fn f(); }
pub struct Ty;
impl Tr for Ty { #[doc(hidden)] fn f() {} }
// ^^^^^^^^^^^^^^ ignored by rustdoc and currently
// no error or warning issued
```
This may lead users to the wrong belief that the attribute has an effect. In fact, several such cases are found in the standard library (I've removed all of them in this PR).
There does not seem to exist any incentive to allow this in the future either: Impl'ing a trait for a type means the type *fully* conforms to its API. Users can add `#[doc(hidden)]` to the whole impl if they want to hide the implementation or add the attribute to the corresponding associated item in the trait declaration to hide the specific item. Hiding an implementation of an associated item does not make much sense: The associated item can still be found on the trait page.
This PR emits the warn-by-default lint `unused_attribute` for this case with a future-incompat warning.
`@rustbot` label T-compiler T-rustdoc A-lint
optimize `promote_consts` by caching the results of `validate_local`
From the FIXME in the impl of `promote_consts`. Early return the `validate_local` should save some compile time.
`qualif_local` is similar to this, but requires futher changing because there are different types of qualif checks. If this PR is effective, I will do it as well.
Remove `#[rustc_deprecated]`
This removes `#[rustc_deprecated]` and introduces diagnostics to help users to the right direction (that being `#[deprecated]`). All uses of `#[rustc_deprecated]` have been converted. CI is expected to fail initially; this requires #95958, which includes converting `stdarch`.
I plan on following up in a short while (maybe a bootstrap cycle?) removing the diagnostics, as they're only intended to be short-term.
Support tool lints with the `#[expect]` attribute (RFC 2383)
This PR fixes the ICE https://github.com/rust-lang/rust/issues/94953 by making the assert for converted expectation IDs conditional.
Additionally, it moves the lint expectation check into a separate query to support rustdoc and other tools. On the way, I've also added some tests to ensure that the attribute works for Clippy and rustdoc lints.
The number of changes comes from the long test file. This may look like a monster PR, this may smell like a monster PR and this may be a monster PR, but it's a harmless monster. 🦕
---
Closes: https://github.com/rust-lang/rust/issues/94953
cc: https://github.com/rust-lang/rust/issues/85549
r? `@wesleywiser`
cc: `@rust-lang/rustdoc`
Switch sources are used by backward analysis with a custom switch int
edge effects, but are otherwise unnecessarily computed.
Delay the computation until we know that switch sources are indeed
required and avoid the computation otherwise.
Track if a where bound comes from a impl Trait desugar
With https://github.com/rust-lang/rust/pull/93803 `impl Trait` function arguments get desugared to hidden where bounds. However, Clippy needs to know if a bound was originally a `impl Trait` or an actual bound. This adds a field to the `WhereBoundPredicate` struct to keep track of this information during AST->HIR lowering.
r? `@cjgillot`
cc `@estebank` (as the reviewer of #93803)
With #93803 `impl Trait` function arguments get desugared to hidden
where bounds. However, Clippy needs to know if a bound was originally a
impl Trait or an actual bound. This adds a field to the
`WhereBoundPredicate` struct to keep track of this information during
HIR lowering.
Improve validator around field projections and checked bin ops
The two commits are unrelated. In both cases, these rules were already documented in MIR docs.
diagnostics: port more diagnostics to derive + add support for `Vec` fields
- Port "unconstrained opaque type" diagnostic to using the derive.
- Allow `Vec` fields in diagnostic derive - enables support for diagnostics that have multiple primary spans, or have subdiagnostics repeated at multiple locations. `Vec<..>` fields in the diagnostic derive become loops in the generated code.
- Add `create_{err,warning}` - there wasn't a way to create a diagnostic from a struct and not emit it straight away.
- Port "explicit generic args w/ impl trait" diagnostic to using the derive.
r? `````@oli-obk`````
cc `````@pvdrz`````
make Size and Align debug-printing a bit more compact
In particular in `{:#?}`-mode, these take up a lot of space, so I think this is the better alternative (even though it is a bit longer in `{:?}` mode, I think it is still more readable).
We could make it even smaller by deviating further from what the actual code looks like, e.g. via something like `Size(4 bytes)`. Not sure what people would think about that?
Cc `````@oli-obk`````
Begin fixing all the broken doctests in `compiler/`
Begins to fix#95994.
All of them pass now but 24 of them I've marked with `ignore HELP (<explanation>)` (asking for help) as I'm unsure how to get them to work / if we should leave them as they are.
There are also a few that I marked `ignore` that could maybe be made to work but seem less important.
Each `ignore` has a rough "reason" for ignoring after it parentheses, with
- `(pseudo-rust)` meaning "mostly rust-like but contains foreign syntax"
- `(illustrative)` a somewhat catchall for either a fragment of rust that doesn't stand on its own (like a lone type), or abbreviated rust with ellipses and undeclared types that would get too cluttered if made compile-worthy.
- `(not-rust)` stuff that isn't rust but benefits from the syntax highlighting, like MIR.
- `(internal)` uses `rustc_*` code which would be difficult to make work with the testing setup.
Those reason notes are a bit inconsistently applied and messy though. If that's important I can go through them again and try a more principled approach. When I run `rg '```ignore \(' .` on the repo, there look to be lots of different conventions other people have used for this sort of thing. I could try unifying them all if that would be helpful.
I'm not sure if there was a better existing way to do this but I wrote my own script to help me run all the doctests and wade through the output. If that would be useful to anyone else, I put it here: https://github.com/Elliot-Roberts/rust_doctest_fixing_tool
Rollup of 8 pull requests
Successful merges:
- #96660 ([bootstrap] Give a better error when trying to run a path with no registered step)
- #96701 (update `jemallocator` example to use 2018 edition import syntax)
- #96746 (Fix an ICE on #96738)
- #96758 (bootstrap: bsd platform flags for split debuginfo)
- #96778 (Remove closures on `expect_local` to apply `#[track_caller]`)
- #96781 (Fix an incorrect link in The Unstable Book)
- #96783 (Link to correct issue in issue-95034 known-bug)
- #96801 (Add regression test for #96319)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Rollup of 10 pull requests
Successful merges:
- #96557 (Allow inline consts to reference generic params)
- #96590 (rustdoc: when running a function-signature search, tweak the tab bar)
- #96650 (Collect function instance used in `global_asm!` sym operand)
- #96733 (turn `append_place_to_string` from recursion into iteration)
- #96748 (Fixes reexports in search)
- #96752 (Put the incompatible_closure_captures lint messages in alphabetical order)
- #96754 (rustdoc: ensure HTML/JS side implementors don't have dups)
- #96772 (Suggest fully qualified path with appropriate params)
- #96776 (Fix two minor issues in hir.rs)
- #96782 (a small `mirror_expr` cleanup)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Fix two minor issues in hir.rs
I found these two places in hir.rs which could use a bit of improvements while going through the code.
No functional change.
Put the incompatible_closure_captures lint messages in alphabetical order
Looks like they were in hash order before, which was causing me trouble in #94598, so this PR sorts the errors by trait name.
turn `append_place_to_string` from recursion into iteration
This PR fixes the FIXME in the impl of `append_place_to_string` which turns `append_place_to_string` from recursion into iteration, meanwhile simplifying the code relatively.
Collect function instance used in `global_asm!` sym operand
The constants used in SymFn operands have FnDef type,
so the type of the constant identifies the function.
Fixes#96623.
Allow inline consts to reference generic params
Tracking issue: #76001
The RFC says that inline consts cannot reference to generic parameters (for now), same as array length expressions. And expresses that it's desirable for it to reference in-scope generics, when array length expressions gain that feature as well.
However it is possible to implement this for inline consts before doing this for all anon consts, because inline consts are only used as values and they won't be used in the type system. So we can have:
```rust
fn foo<T>() {
let x = [4i32; std::mem::size_of::<T>()]; // NOT ALLOWED (for now)
let x = const { std::mem::size_of::<T>() }; // ALLOWED with this PR!
let x = [4i32; const { std::mem::size_of::<T>() }]; // NOT ALLOWED (for now)
}
```
This would make inline consts super useful for compile-time checks and assertions:
```rust
fn assert_zst<T>() {
const { assert!(std::mem::size_of::<T>() == 0) };
}
```
This would create an error during monomorphization when `assert_zst` is instantiated with non-ZST `T`s. A error during mono might sound scary, but this is exactly what a "desugared" inline const would do:
```rust
fn assert_zst<T>() {
struct F<T>(T);
impl<T> F<T> {
const V: () = assert!(std::mem::size_of::<T>() == 0);
}
let _ = F::<T>::V;
}
```
It should also be noted that the current inline const implementation can already reference the type params via type inference, so this resolver-level restriction is not any useful either:
```rust
fn foo<T>() -> usize {
let (_, size): (PhantomData<T>, usize) = const {
const fn my_size_of<T>() -> (PhantomData<T>, usize) {
(PhantomData, std::mem::size_of::<T>())
}
my_size_of()
};
size
}
```
```@rustbot``` label: F-inline_const
Fixing #95444 by only displaying passes that take more than 5 millise…
As discussed in #95444, I have added the code to test and only display prints that are greater than 5 milliseconds.
r? `@jyn514`
Remove mutable_borrow_reservation_conflict lint and allow the code pattern
This was the only breaking issue with the NLL stabilization PR. Lang team decided to go ahead and allow this.
r? `@nikomatsakis`
Closes#59159Closes#56254
Add a dedicated length-prefixing method to `Hasher`
This accomplishes two main goals:
- Make it clear who is responsible for prefix-freedom, including how they should do it
- Make it feasible for a `Hasher` that *doesn't* care about Hash-DoS resistance to get better performance by not hashing lengths
This does not change rustc-hash, since that's in an external crate, but that could potentially use it in future.
Fixes#94026
r? rust-lang/libs
---
The core of this change is the following two new methods on `Hasher`:
```rust
pub trait Hasher {
/// Writes a length prefix into this hasher, as part of being prefix-free.
///
/// If you're implementing [`Hash`] for a custom collection, call this before
/// writing its contents to this `Hasher`. That way
/// `(collection![1, 2, 3], collection![4, 5])` and
/// `(collection![1, 2], collection![3, 4, 5])` will provide different
/// sequences of values to the `Hasher`
///
/// The `impl<T> Hash for [T]` includes a call to this method, so if you're
/// hashing a slice (or array or vector) via its `Hash::hash` method,
/// you should **not** call this yourself.
///
/// This method is only for providing domain separation. If you want to
/// hash a `usize` that represents part of the *data*, then it's important
/// that you pass it to [`Hasher::write_usize`] instead of to this method.
///
/// # Examples
///
/// ```
/// #![feature(hasher_prefixfree_extras)]
/// # // Stubs to make the `impl` below pass the compiler
/// # struct MyCollection<T>(Option<T>);
/// # impl<T> MyCollection<T> {
/// # fn len(&self) -> usize { todo!() }
/// # }
/// # impl<'a, T> IntoIterator for &'a MyCollection<T> {
/// # type Item = T;
/// # type IntoIter = std::iter::Empty<T>;
/// # fn into_iter(self) -> Self::IntoIter { todo!() }
/// # }
///
/// use std:#️⃣:{Hash, Hasher};
/// impl<T: Hash> Hash for MyCollection<T> {
/// fn hash<H: Hasher>(&self, state: &mut H) {
/// state.write_length_prefix(self.len());
/// for elt in self {
/// elt.hash(state);
/// }
/// }
/// }
/// ```
///
/// # Note to Implementers
///
/// If you've decided that your `Hasher` is willing to be susceptible to
/// Hash-DoS attacks, then you might consider skipping hashing some or all
/// of the `len` provided in the name of increased performance.
#[inline]
#[unstable(feature = "hasher_prefixfree_extras", issue = "88888888")]
fn write_length_prefix(&mut self, len: usize) {
self.write_usize(len);
}
/// Writes a single `str` into this hasher.
///
/// If you're implementing [`Hash`], you generally do not need to call this,
/// as the `impl Hash for str` does, so you can just use that.
///
/// This includes the domain separator for prefix-freedom, so you should
/// **not** call `Self::write_length_prefix` before calling this.
///
/// # Note to Implementers
///
/// The default implementation of this method includes a call to
/// [`Self::write_length_prefix`], so if your implementation of `Hasher`
/// doesn't care about prefix-freedom and you've thus overridden
/// that method to do nothing, there's no need to override this one.
///
/// This method is available to be overridden separately from the others
/// as `str` being UTF-8 means that it never contains `0xFF` bytes, which
/// can be used to provide prefix-freedom cheaper than hashing a length.
///
/// For example, if your `Hasher` works byte-by-byte (perhaps by accumulating
/// them into a buffer), then you can hash the bytes of the `str` followed
/// by a single `0xFF` byte.
///
/// If your `Hasher` works in chunks, you can also do this by being careful
/// about how you pad partial chunks. If the chunks are padded with `0x00`
/// bytes then just hashing an extra `0xFF` byte doesn't necessarily
/// provide prefix-freedom, as `"ab"` and `"ab\u{0}"` would likely hash
/// the same sequence of chunks. But if you pad with `0xFF` bytes instead,
/// ensuring at least one padding byte, then it can often provide
/// prefix-freedom cheaper than hashing the length would.
#[inline]
#[unstable(feature = "hasher_prefixfree_extras", issue = "88888888")]
fn write_str(&mut self, s: &str) {
self.write_length_prefix(s.len());
self.write(s.as_bytes());
}
}
```
With updates to the `Hash` implementations for slices and containers to call `write_length_prefix` instead of `write_usize`.
`write_str` defaults to using `write_length_prefix` since, as was pointed out in the issue, the `write_u8(0xFF)` approach is insufficient for hashers that work in chunks, as those would hash `"a\u{0}"` and `"a"` to the same thing. But since `SipHash` works byte-wise (there's an internal buffer to accumulate bytes until a full chunk is available) it overrides `write_str` to continue to use the add-non-UTF-8-byte approach.
---
Compatibility:
Because the default implementation of `write_length_prefix` calls `write_usize`, the changed hash implementation for slices will do the same thing the old one did on existing `Hasher`s.
This accomplishes two main goals:
- Make it clear who is responsible for prefix-freedom, including how they should do it
- Make it feasible for a `Hasher` that *doesn't* care about Hash-DoS resistance to get better performance by not hashing lengths
This does not change rustc-hash, since that's in an external crate, but that could potentially use it in future.
Currently, the only API for creating errors from a diagnostic derive
will emit it immediately. This makes it difficult to add subdiagnostics
to diagnostics from the derive, so add `create_{err,warning}` functions
that return the diagnostic without emitting it.
Signed-off-by: David Wood <david.wood@huawei.com>
Diagnostics can have multiple primary spans, or have subdiagnostics
repeated at multiple locations, so support `Vec<..>` fields in the
diagnostic derive which become loops in the generated code.
Signed-off-by: David Wood <david.wood@huawei.com>
95444: Adding passes that include memory increase
Fix95444: Change the substraction with the abs_diff() method
Fix95444: Change the substraction with abs_diff() method
Fixes#96319
The logic around handling co-inductive cycles in the evaluation cache
is confusing and error prone. Fortunately, a perf run showed that it
doesn't actually appear to improve performance, so we can simplify
this code (and eliminate a source of ICEs) by just skipping caching
the evaluation results for co-inductive cycle participants.
This commit makes no changes to any of the other logic around
co-inductive cycle handling. Thus, while this commit could
potentially expose latent bugs that were being hidden by
caching, it should not introduce any new bugs.
interpret/validity: debug-check ScalarPair layout information
This would have caught https://github.com/rust-lang/rust/issues/96158.
I ran the Miri test suite and it still passes.
r? `@oli-obk`
Report that opaque types are not allowed in impls even in the presence of other errors
fixes #96569
before this PR those useful errors were hidden because either `unused parameter` or `only traits defined in the current crate can be implemented for arbitrary types` got emitted first.
Add a new Rust attribute to support embedding debugger visualizers
Implemented [this RFC](https://github.com/rust-lang/rfcs/pull/3191) to add support for embedding debugger visualizers into a PDB.
Added a new attribute `#[debugger_visualizer]` and updated the `CrateMetadata` to store debugger visualizers for crate dependencies.
RFC: https://github.com/rust-lang/rfcs/pull/3191
do not suggest when trait_ref is some
Update compiler/rustc_resolve/src/late/diagnostics.rs
Co-authored-by: lcnr <rust@lcnr.de>
use helper struct
add a test for functions with some params
refactor debug log
Enable tracing for all queries
This allows you to log everything within a specific query, e.g.
```
env RUSTC_LOG=[mir_borrowck]
```
dumping all borrowck queries may be a bit verbose, so you can also restrict it to just an item of your choice:
```
env RUSTC_LOG=[mir_borrowck{key=\.\*name_of_item\.\*}]
```
the regex `.*` in the key name are because the key is a debug printed DefId, so you'd get all kinds of things like hashes in there. The tracing logs will show you the key, so you can restrict it further if you want.
Revert "Prefer projection candidates instead of param_env candidates for Sized predicates"
Fixes#93262Reopens#89352
This was a hack that seemed to have no negative side-effects at the time. Given that the latter has a workaround and likely less common than the former, it makes sense to revert this change.
r? `@compiler-errors`
Overhaul `MacArgs`
Motivation:
- Clarify some code that I found hard to understand.
- Eliminate one use of three places where `TokenKind::Interpolated` values are created.
r? `@petrochenkov`
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
Update `ProjectionElem::Downcast` documentation
`ProjectionElem:::Downcast` is used when downcasting to a variant of
an enum or a generator, regardless of the number of variants.
Quick fix for #96223.
This PR is a quick fix regarding #96223.
As mentioned in the issue, others modification could be added to not elide types with bound vars from suggestions.
Special thanks to ``@jackh726`` for mentoring and ``@Manishearth`` for minimal test case.
r? ``@jackh726``
When suggesting to import an item, also suggest changing the path if appropriate
When we don't find an item we search all of them for an appropriate
import and suggest `use`ing it. This is sometimes done for expressions
that have paths with more than one segment. We now also suggest changing
that path to work with the `use`.
Fix#95413
The comment on this function explains that it's a specialized version of
`maybe_whole_expr`. But `maybe_whole_expr` doesn't do anything with
`NtIdent`, so `is_whole_expr` also doesn't need to.
Cleanup `DebuggerVisualizerFile` type and other minor cleanup of queries.
Merge the queries for debugger visualizers into a single query.
Revert move of `resolve_path` to `rustc_builtin_macros`. Update dependencies in Cargo.toml for `rustc_passes`.
Respond to PR comments. Load visualizer files into opaque bytes `Vec<u8>`. Debugger visualizers for dynamically linked crates should not be embedded in the current crate.
Update the unstable book with the new feature. Add the tracking issue for the debugger_visualizer feature.
Respond to PR comments and minor cleanups.
Use reverse postorder in `non_ssa_locals`
The reverse postorder, unlike preorder, is now cached inside the MIR
body. Code generation uses reverse postorder anyway, so it might be
a small perf improvement to use it here as well.
Mitigate impact of subtle invalid call suggestion logic
There's some subtle interaction between inferred expressions being
passed as an argument to fn calls with fewer than expected arguments. To
avoid the ICE, I'm changing indexing operations with `.get(idx)`, but
the underlying logic still needs to be audited as it was written with
the assumption that `final_arg_types` and `provided_args` have the right
length.
Address #96638.
Update `RValue::Discriminant` documentation
`RValue::Discriminant` returns zero for types without discriminant.
This guarantee is already documented for `discriminant_value`
intrinsics which is implemented in terms of `RValue::Discriminant`.
Use source callsite in check_argument_types suggestion
This makes the "remove extra arguement" suggestion valid when the function argument is a macro.
Additionally, this may fix#96225, but the only way I can reproduce that issue is using the playground, so we will need to wait until after this is merged to ensure it's fixed.
Refactor the WriteBackendMethods and ExtraBackendMethods traits
The new interface is slightly less confusing and is easier to implement for non-LLVM backends.
When we don't find an item we search all of them for an appropriate
import and suggest `use`ing it. This is sometimes done for expressions
that have paths with more than one segment. We now also suggest changing
that path to work with the `use`.
Fix#95413
There's some subtle interaction between inferred expressions being
passed as an argument to fn calls with fewer than expected arguments. To
avoid the ICE, I'm changing indexing operations with `.get(idx)`, but
the underlying logic still needs to be audited as it was written with
the assumption that `final_arg_types` and `provided_args` have the right
length.
Address 96638.
Fix -Zdump-mir-dataflow by implementing DebugWithContext for ChunkedBitSet
`DebugWithContext` is used to format changes to dataflow state along with MIR
in graphviz dot files. In the case of `ChunkedBitSet` it was left unimplemented,
so attempts to use `-Zdump-mir-dataflow -Zdump-mir=all` resulted in an ICE:
> thread 'rustc' panicked at 'not implemented: implement when/if needed',
Provide the missing implementation.
r? `@nnethercote`
rustc: Panic by default in `DefIdTree::parent`
Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.
Same applies to `local_parent`/`opt_local_parent`.
Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.
Same applies to `local_parent`/`opt_local_parent`.
rustdoc: Resolve doc links referring to `macro_rules` items
cc https://github.com/rust-lang/rust/issues/81633
UPD: the fallback to considering *all* `macro_rules` in the crate for unresolved names is not removed in this PR, it will be removed separately and will be run through crater.
The reverse postorder, unlike preorder, is now cached inside the MIR
body. Code generation uses reverse postorder anyway, so it might be
a small perf improvement to use it here as well.
Also report the call site of PME errors locally.
Note this does not produce a full stack all the way to the first call that specifies all monomorphic parameters, it's just shallowly mentioning the last call site.
previous work: https://github.com/rust-lang/rust/pull/85633
tracking issue: https://github.com/rust-lang/rust/issues/85155
r? `@lqd`
I figured we could get some improvement for traces in local crates without going into the backtrace hell you landed in last time
`RValue::Discriminant` returns zero for types without discriminant.
This guarantee is already documented for `discriminant_value`
intrinsics which is implemented in terms of `RValue::Discriminant`.
Using an obviously-placeholder syntax. An RFC would still be needed before this could have any chance at stabilization, and it might be removed at any point.
But I'd really like to have it in nightly at least to ensure it works well with try_trait_v2, especially as we refactor the traits.
Erase type params when suggesting fully qualified path
When suggesting the use of a fully qualified path for a method call that
is ambiguous because it has multiple candidates, erase type params in
the resulting code, as they would result in an error when applied. We
replace them with `_` in the output to rely on inference. There might be
cases where this still produces slighlty incomplete suggestions, but it
otherwise produces many more errors in relatively common cases.
Fix#96292
Note this does not produce a full stack all the way to the first call that specifies all monomorphic parameters, it's just shallowly mentioning the last call site.
Enforce static lifetimes in consts during late resolution
This PR moves the handling of implicitly and explicitly static lifetimes in constants from HIR to the AST.
Reduce duplication of RPO calculation of mir
Computing the RPO of mir is not a low-cost thing, but it is duplicate in many places. In particular the `iterate_to_fixpoint` method which is called multiple times when computing the data flow.
This PR reduces the number of times the RPO is recalculated as much as possible, which should save some compile time.
Fix duplicate directory separator in --remap-path-prefix.
The compiler will currently emit duplicate directory separators when `--remap-path-prefix` has an exact match of the working directory and it is invoked with a relative path to the main source file. For example
```bash
rustc src/main.rs -Cdebuginfo=2 --remap-path-prefix="$(pwd)=abc"
```
will produce the path `abc//src/main.rs` in debuginfo. This is because `some_path.join("")` will append a directory separator to `some_path` and then LLVM does not check if the working directory already ends a directory separator before concatenating it with the relative path.
RustWrapper: explicitly don't handle DXILPointerTyID
This new enum entry was introduced in https://reviews.llvm.org/D122268,
and if I'm reading correctly there's no case where we'd ever encounter
it in our uses of LLVM. To preserve the ability to compile this file
with -Werror -Wswitch we add an explicit case for this entry.
r? nikic
Enforce Copy bounds for repeat elements while considering lifetimes
fixes https://github.com/rust-lang/rust/issues/95477
this is a breaking change in order to fix a soundness bug.
Before this PR we only checked whether the repeat element type had an `impl Copy`, but not whether that impl also had the appropriate lifetimes. E.g. if the impl was for `YourType<'static>` and not a general `'a`, then copying any type other than a `'static` one should have been rejected, but wasn't.
r? `@lcnr`
macros: subdiagnostic derive
Add a new macro, `#[derive(SessionSubdiagnostic)]`, which can be applied to structs that represent subdiagnostics, such as labels, notes, helps or suggestions.
`#[derive(SessionSubdiagnostic)]` can be used with the existing `#[derive(SessionDiagnostic)]`. All diagnostics implemented using either derive are translatable, and this new derive should make it easier to port existing diagnostics to using these derives.
For example, consider the following subdiagnostic types...
```rust
#[derive(SessionSubdiagnostic)]
pub enum ExpectedIdentifierLabel<'tcx> {
#[label(slug = "parser-expected-identifier")]
WithoutFound {
#[primary_span]
span: Span,
}
#[label(slug = "parser-expected-identifier-found")]
WithFound {
#[primary_span]
span: Span,
found: String,
}
}
#[derive(SessionSubdiagnostic)]
#[suggestion_verbose(slug = "parser-raw-identifier")]
pub struct RawIdentifierSuggestion<'tcx> {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
ident: Ident,
}
```
...and the corresponding Fluent messages:
```fluent
parser-expected-identifier = expected identifier
parser-expected-identifier-found = expected identifier, found {$found}
parser-raw-identifier = escape `{$ident}` to use it as an identifier
```
These can be emitted using the new `subdiagnostic` function on `Diagnostic`...
```rust
diag.subdiagnostic(ExpectedIdentifierLabel::WithoutFound { span });
diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident });
```
...or as part of a larger `#[derive(SessionDiagnostic)]`:
```rust
#[derive(SessionDiagnostic)]
#[error(slug = "parser-expected-identifier")]
pub struct ExpectedIdentifier {
#[primary_span]
span: Span,
token_descr: String,
#[subdiagnostic]
label: ExpectedIdentifierLabel,
#[subdiagnostic]
raw_identifier_suggestion: Option<RawIdentifierSuggestion>,
}
```
```rust
sess.emit_err(ExpectedIdentifier { ... });
```
r? `@oli-obk`
cc `@pvdrz`
Revert diagnostic duplication and accidental stabilization
fixes#96460
this is an accidental stabilization that we should put into the beta. I believe it is low-risk, because it was literally what we had before #94081
The effect on tests is massive, but mostly deduplication of diagnostics and some minor span changes.
Update data layout string for wasm64-unknown-unknown
Looks like this changed in a recent LLVM update but wasm64 isn't built
on CI so it wasn't caught until now.
Closes#96463
The two paths are equivalent -- they both end up calling `visit_expr()`.
I have kept the more restrictive path, the one that requires that
`token` be an expression nonterminal. (The next commit will simplify this
function further.)
`make_tokenstream` has three commented hacks, and a comment at the top
referring to #67062. These hacks have no observable effect, at least as judged
by running the test suite. The hacks were added in #82608, with an explanation
[here](https://github.com/rust-lang/rust/pull/82608#issuecomment-812877329). It
appears that one of the following is true: (a) they never did anything useful,
(b) they do something useful but we have no test coverage for them, or (c)
something has changed in the meantime that means they are no longer necessary.
This commit removes the hacks and the comments, in the hope that (b) is not
true.
The `token` is always an interpolated non-terminal expression, and
always a literal in valid code. This commit simplifies the processing
accordingly, by directly extracting and using the literal.
This commit rearranges the `match`. The new code avoids testing for
`MacArgs::Eq` twice, at the cost of repeating the `self.print_path()`
call. I think this is worthwhile because it puts the `match` in a more
standard and readable form.
Add `#[subdiagnostic]` field attribute to the diagnostic derive which
is applied to fields that have types which use the subdiagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
In the initial implementation of the `SessionSubdiagnostic`, the
`Applicability` of a suggestion can be set both as a field and as part
of the attribute, this commit adds the same support to the original
`SessionDiagnostic` derive.
Signed-off-by: David Wood <david.wood@huawei.com>
`SetOnce` trait was introduced in the subdiagnostic derive to simplify
the code a little bit, re-use it in the diagnostic derive too.
Signed-off-by: David Wood <david.wood@huawei.com>
Remove some duplicated code between both diagnostic derives by
introducing helper functions for reporting an error in case of a invalid
attribute.
Signed-off-by: David Wood <david.wood@huawei.com>
Split `SessionDiagnostic` and `SessionSubdiagnostic` derives and the
various helper functions into multiple modules.
Signed-off-by: David Wood <david.wood@huawei.com>
Add a new derive, `#[derive(SessionSubdiagnostic)]`, which enables
deriving structs for labels, notes, helps and suggestions.
Signed-off-by: David Wood <david.wood@huawei.com>
Change `span_suggestion` (and variants) to take `impl ToString` rather
than `String` for the suggested code, as this simplifies the
requirements on the diagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
rustc_ast: Harmonize delimiter naming with `proc_macro::Delimiter`
Compiler cannot reuse `proc_macro::Delimiter` directly due to extra impls, but can at least use the same naming.
After this PR the only difference between these two enums is that `proc_macro::Delimiter::None` is turned into `token::Delimiter::Invisible`.
It's my mistake that the invisible delimiter is called `None` on stable, during the stabilization I audited the naming and wrote the docs, but missed the fact that the `None` naming gives a wrong and confusing impression about what this thing is.
cc https://github.com/rust-lang/rust/pull/96421
r? ``@nnethercote``
This new enum entry was introduced in https://reviews.llvm.org/D122268,
and if I'm reading correctly there's no case where we'd ever encounter
it in our uses of LLVM. To preserve the ability to compile this file
with -Werror -Wswitch we add an explicit case for this entry.
Implement Valtree to ConstValue conversion
Once we start to use `ValTree`s in the type system we will need to be able to convert them into `ConstValue` instances, which we want to continue to use after MIR construction.
r? `@oli-obk`
cc `@RalfJung`
Make sure `-Dunused-crate-dependencies --json unused-externs` makes rustc exit with error status
This PR:
- fixes compiletest to understand unused extern notifications
- adds tests for `--json unused-externs`
- makes sure that deny-level unused externs notifications are treated as compile errors
- refactors the `emit_unused_externs` callstack to plumb through the level as an enum as a string, and adds `Level::is_error`
Update: adds `--json unused-externs-silent` with the original behaviour since Cargo needs it. Should address `@est31's` concerns.
Fixes: https://github.com/rust-lang/rust/issues/96068
Add missing `target_feature` to the list of well known cfg names
This PR adds the missing `target_feature` cfg name to the list of well known cfg names.
It was notice missing in https://github.com/rust-lang/rust/issues/96472 thanks to `@bjorn3,` the reason being that `--check-cfg=names()` automatically inherit the names passed by `--cfg` (or internal to `rustc`) and is seems that the vast majority of targets have at least one target feature leading to `target_feature` being a well known name in most target but it should always be a well known name so this PR add it unconditionally to list.
r? `@petrochenkov`
not need `Option` for `dbg_scope`
This PR fixes a few FIXME about not using `Option` in `dbg_scope` field of `DebugScope`, during `create_function_debug_context` func in codegen parts.
Added a `BitSet<SourceScope>` parameter to `make_mir_scope` to indicate whether the `DebugScope` has been instantiated.
cc ````@eddyb````
Less `NoDelim`
Currently there are several places where `NoDelim` (which really means "implicit delimiter" or "invisible delimiter") is used to mean "no delimiter". The name `NoDelim` is a bit misleading, and may be a cause.
This PR changes these places, e.g. by changing a `DelimToken` to `Option<DelimToken>` and then using `None` to mean "no delimiter". As a result, the *only* place where `NoDelim` values are now produced is within:
- `Delimiter::to_internal()`, when converting from `Delimiter::None`.
- `FlattenNonterminals::process_token()`, when converting `TokenKind::Interpolated`.
r? ````@petrochenkov````
make `fn() -> _ { .. }` suggestion MachineApplicable
This might not be valid, but it would be nice to promote this to `MachineApplicable` so people can use rustfix here.
Also de65fcf009d07019689cfad7f327667e390a325d is to [restore the suggestion for `issue-77179.rs`](de65fcf009 (diff-12e43fb5d6d12ec7cb5c6b48204a18d113cf5de0e12eb71a358b639bd9aadaf0R8)). (though in this case, the code in that issue still doesn't compile, so it's not marked with rustfix).
Perform lifetime resolution on the AST for lowering
Lifetime resolution is currently implemented several times. Once during lowering in order to introduce in-band lifetimes, and once in the resolve_lifetimes query. However, due to the global nature of lifetime resolution and how it interferes with hygiene, it is better suited on the AST.
This PR implements a first draft of lifetime resolution on the AST. For now, we specifically target named lifetimes and everything we need to remove lifetime resolution from lowering. Some diagnostics have already been ported, and sometimes made more precise using available hygiene information. Follow-up PRs will address in particular the resolution of anonymous lifetimes on the AST.
We reuse the rib design of the current resolution framework. Specific `LifetimeRib` and `LifetimeRibKind` types are introduced. The most important variant is `LifetimeRibKind::Generics`, which happens each time we encounter something which may introduce generic lifetime parameters. It can be an item or a `for<...>` binder. The `LifetimeBinderKind` specifies how this rib behaves with respect to in-band lifetimes.
r? `@petrochenkov`
Since Cargo wants to do its own fatal error handling for unused
dependencies, add the option `--json unused-externs-silent` which
has the original behaviour of not indicating non-zero exit status for
`deny`/`forbid`-level unused dependencies.
Rollup of 6 pull requests
Successful merges:
- #92569 (Improve Error Messaging for Unconstructed Structs and Enum Variants in Generic Contexts)
- #96370 (Cleanup `report_method_error` a bit)
- #96383 (Fix erased region escaping into wfcheck due to #95395)
- #96385 (Recover most `impl Trait` and `dyn Trait` lifetime bound suggestions under NLL)
- #96410 (rustdoc: do not write `{{root}}` in `pub use ::foo` docs)
- #96430 (Fix handling of `!` in rustdoc search)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Recover most `impl Trait` and `dyn Trait` lifetime bound suggestions under NLL
This is done by replacing the duplicated (and very partial) implementation from borrowck with one inspsired from `NiceRegionError::try_report_static_impl_trait` and by re-using `suggest_new_region_bound`.
Fixes#96277
r? ```@jackh726```
Fix erased region escaping into wfcheck due to #95395
We can just use `liberate_late_bound_regions` instead of `erase_late_bound_regions`... This gives us `ReEarlyBound` instead of `ReErased`, the former being something typeck actually knows how to deal with...
Fixes#96381
Side-note: We only actually get far enough in the compiler pipeline to cause this ICE when we're invoking rustdoc. We actually abort rustc right before wfcheck because of the error that we emit (having `_` in the type signature). Why does rustdoc keep going even though we raise an error?
Cleanup `report_method_error` a bit
1. Remove an unnecessary indentation level
2. Split out a couple of large functions from this humongo function body
Fix incremental perf regression unsafety checking
Perf regression introduced in #96294
We will simply avoid emitting the name of the unsafe function in MIR unsafeck, since we're moving to THIR unsafeck anyway.
The code currently ignores the actual delimiter on the RHS and fakes up
a `NoDelim`/`DelimSpan::dummy()` one. This commit changes it to use the
actual delimiter.
The commit also reorders the fields for the `Delimited` variant to match
the `Sequence` variant.
Correct documentation for `Rvalue::ShallowInitBox`
As a part of the big MIR docs PR, I had added a comment indicating that `Rvalue::ShallowInitBox` is disallowed after drop elaboration, but this is not true (no idea why I thought it was). Codegen has support for it, and trying to enforce this rule in the validator causes compiling core to ICE on the very first `box` statement.
That being said, this `Rvalue` probably *should* be banned after drop elaboration - it doesn't seem like it's still useful for much. However, I do not have time right now to actually go investigate how difficult a change that is to make, so in the meantime fixing the docs to reflect the current situation seems like the right step.
r? rust-lang/mir-opt
simplify `describe_field` func in borrowck's diagnostics part
This PR simplify the `describe_field` func in borrowck's diagnostics part, besides fix the FIXME in it.
Suggest calling method on nested field when struct is missing method
Similar to the suggestion to change `x.field` to `x.nested.field`, implement a similar suggestion for when `x.method()` should be replaced with `x.nested.method()`.
Fix codegen bug in "ptx-kernel" abi related to arg passing
I found a codegen bug in the nvptx abi related to that args are passed as ptrs ([see comment](https://github.com/rust-lang/rust/issues/38788#issuecomment-1048999928)), this is not as specified in the [ptx-interoperability doc](https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/) or how C/C++ does it. It will also almost always fail in practice since device/host uses different memory spaces for most hardware.
This PR fixes the bug and add tests for passing structs to ptx kernels.
I observed that all nvptx assembly tests had been marked as [ignore a long time ago](https://github.com/rust-lang/rust/pull/59752#issuecomment-501713428). I'm not sure if the new one should be marked as ignore, it passed on my computer but it might fail if ptx-linker is missing on the server? I guess this is outside scope for this PR and should be looked at in a different issue/PR.
I only fixed the nvptx64-nvidia-cuda target and not the potential code paths for the non-existing 32bit target. Even though 32bit nvptx is not a supported target there are still some code under the hood supporting codegen for 32 bit ptx. I was advised to create an MCP to find out if this code should be removed or updated.
Perhaps ``@RDambrosio016`` would have interest in taking a quick look at this.
Fix incorrect suggestion for trait bounds involving binary operators
This PR fixes#93927, #92347, #93744 by replacing the bespoke trait-suggestion logic in `op.rs` with a more common code path.
The downside is that this fix causes some suggestions to not include an `Output=` type, reducing their usefulness.
Note that this causes one case in the `missing-bounds.rs` test to fail rustfix. So I would need to move that code into a separate non-fix test if this PR is otherwise acceptable.
Rollup of 6 pull requests
Successful merges:
- #90312 (Fix some confusing wording and improve slice-search-related docs)
- #96149 (Remove unused macro rules)
- #96279 (rustdoc: Remove .woff font files)
- #96355 (Better handle too many `#` recovery in raw str)
- #96379 (delay bug when adjusting `NeverToAny` twice during diagnostic code)
- #96384 (do not consider two extern types to be similar)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
delay bug when adjusting `NeverToAny` twice during diagnostic code
Addresses Issue 96335 (https://github.com/rust-lang/rust/issues/96335) by using `delay_span_bug` instead of an assert and returning an error type from `check_expr_meets_expectation_or_error`.
Fixes#96335
Better handle too many `#` recovery in raw str
Point at all the unnecessary trailing `#`.
Better handle interaction with outer attributes when `;` is missing.
Fix#95030.
Display function path in unsafety violations - E0133
adds `DefId` to `UnsafetyViolationDetails`
this enables consumers to access the function definition that was reported to be unsafe and also changes the output for some E0133 diagnostics
Generate synthetic object file to ensure all exported and used symbols participate in the linking
Fix#50007 and #47384
This is the synthetic object file approach that I described in https://github.com/rust-lang/rust/pull/95363#issuecomment-1079932354, allowing all exported and used symbols to be linked while still allowing them to be GCed.
Related #93791, #95363
r? `@petrochenkov`
cc `@carbotaniuman`
Add `BoundKind` in `visit_param_bounds` to check questions in bounds
From the FIXME in the impl of `AstValidator`. Better bound checks by adding `BoundCtxt` type parameter to `visit_param_bound`
cc `@ecstatic-morse`
Drop support for legacy PM with LLVM 15
LLVM 15 already removes some of the legacy PM APIs we're using. This patch forces use of NewPM with LLVM 15 (with `-Z new-llvm-pass-manager=no` throwing a warning) and stubs out various FFI methods with a report_fatal_error on LLVM 15.
For LLVMPassManagerBuilderPopulateLTOPassManager() I went with adding our own wrapper, as the alternative would be to muck about with weak symbols, which seems to be non-trivial as far as cross-platform support is concerned (std has `weak!` for this purpose, but only as an internal utility.)
Fixes#96072.
Fixes#96362.
Implement MIR opt unit tests
This implements rust-lang/compiler-team#502 .
There's not much to say here, this implementation does everything as proposed. I also added the flag to a bunch of existing tests (mostly those to which I could add it without causing huge diffs due to changes in line numbers). Summarizing the changes to test outputs:
- Every time an `MirPatch` is created, it adds a cleanup block to the body if it did not exist already. If this block is unused (as is usually the case), it usually gets removed soon after by some pass calling `SimplifyCFG` for unrelated reasons (in many cases this cycle happens quite a few times for a single body). We now run `SimplifyCFG` less often, so those blocks end up in some of our outputs. I looked at changing `MirPatch` to not do this, but that seemed too complicated for this PR. I may still do that in a follow-up.
- The `InstCombine` test had set `-C opt-level=0` in its flags and so there were no storage markers. I don't really see a good motivation for doing this, so bringing it back in line with what everything else does seems correct.
- One of the `EarlyOtherwiseBranch` tests had `UnreachableProp` running on it. Preventing that kind of thing is the goal of this feature, so this seems fine.
For the remaining tests for which this feature might be useful, we can gradually migrate them as opportunities present themselves.
In terms of documentation, I plan on submitting a PR to the rustc dev guide in the near future documenting this and other recent changes to MIR. If there's any other places to update, do let me know
r? `@nagisa`
Improve span for `consider adding an explicit lifetime bound` suggestions under NLL
Because NLL borrowck is run after typeck, `in_progress_typeck_results` was always `None` which was preventing the retrieval of the span to which the suggestion is suppose to add the lifetime bound.
We now manually pass the `LocalDefId` owner to `construct_generic_bound_failure` so that under NLL, we give the owner id of the current body.
This helps with #96332
make `classify_drop_access_kind` iterate
This PR:
1. fixes the FIXME of `classify_drop_access_kind` func in the borrowck part. The process of obtaining `StorageDeadOrDrop` has been changed from recursive to iterative.
2. gets `place_ty` in each iteration, avoid repeatedly getting the `ty` of the same place (O(n^2) => O(n))
Because NLL borrowck is run after typeck, `in_progress_typeck_results`
was always `None` which was preventing the retrieval of the span to which
the suggestion is suppose to add the lifetime bound.
We now manually pass the `LocalDefId` owner to `construct_generic_bound_failure`
so that under NLL, we give the owner id of the current body.
This adds `nounused` to the set of extern flags:
`--extern nounused:core=/path/to/core/libcore.rlib`.
The effect of this flag is to suppress `unused-crate-dependencies`
warnings relating to the crate.
Optimize `const_prop` mir-opt by accessing `local_decls` through `ecx`
From the FIXME in the impl of `ConstPropagator`. Accessing `local_decls` and `scource_scopes` from `ecx` can reduce `clone` calls and save compile time.
Besides, according to #96213 , the FIXME about writing `layouts` to `ecx` in advance can also be removed.
Remove visibility information from HIR
The resolver exports all the necessary visibility information through the `tcx.visibility` query.
This PR stops having a dedicated visibility field in HIR, in order to use this query.
We keep a `vis_span` field for diagnostic purposes.
When suggesting the use of a fully qualified path for a method call that
is ambiguous because it has multiple candidates, erase type params in
the resulting code, as they would result in an error when applied. We
replace them with `_` in the output to rely on inference. There might be
cases where this still produces slighlty incomplete suggestions, but it
otherwise produces many more errors in relatively common cases.
Fix#96292
Sync rustc_codegen_cranelift
Mostly fixing bugs this time, but also a Cranelift update.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
debuginfo: Emit ZST struct debuginfo for unit type when CPP-like debuginfo is enabled
As already discovered in 24a728a8eb, PDB does not play well with custom basic types. This PR extends to the fix to `()`: Instead of a custom basic type, we treat it like an empty tuple (i.e. it is described as a struct which happens to have no fields).
Before this change anything with a `()` in it would cause trouble, which is especially bad for `*const ()` and `*mut ()` which are often used for opaque pointers. E.g. the test case added in this PR would look like:
```
0:000> dx _ref
Error: Unable to bind name '_ref'
0:000> dx _ptr
Error: Unable to bind name '_ptr'
0:000> dx _local
Error: Unable to bind name '_local'
0:000> dx _field,d
_field,d [Type: unit_type::_TypeContainingUnitField]
[+0x008] _a : 123 [Type: unsigned int]
[+0x000] _unit : Unexpected failure to dereference object
[+0x000] _b : 456 [Type: unsigned __int64]
0:000> dx ((__int64 *)_ptr),x
Error: Unable to bind name '_ptr'
```
With the PR it produces the expected output:
```
0:000> dx _ref
_ref : 0x7ff6f2012230 : () [Type: tuple$<> *]
0:000> dx _ptr
_ptr : 0x7e8ddffc20 : () [Type: tuple$<> *]
0:000> dx _local
_local : () [Type: tuple$<>]
0:000> dx _field,d
_field,d [Type: unit_type::_TypeContainingUnitField]
[+0x008] _a : 123 [Type: unsigned int]
[+0x000] _unit : () [Type: tuple$<>]
[+0x000] _b : 456 [Type: unsigned __int64]
0:000> dx ((__int64 *)_ptr),x
((__int64 *)_ptr),x : 0x7e8ddffc20 : 0x1122334455667788 [Type: __int64 *]
```
r? `@wesleywiser`
self-profiler: record spans for proc-macro expansions
This PR is a follow-up to #95473, using the arg recorder feature from #95689:
- it adds support code to easily record spans in the event's arguments, when using `generic_activity_with_arg_recorder`.
- uses that to record the spans where proc-macro expansions happen in addition to their name.
As for the other 2 PRs, the goal here is to provide visibility into proc-macro expansion performance, so that users can diagnose which uses of proc-macros in their code could be causing compile time issues.
Some areas where I'd love feedback:
- [x] the API and names: the `SpannedEventArgRecorder` trait and its method, much like #95689 had the same question about the `EventArgRecorder` naming
- [x] we don't currently have a way to record the names of the event arguments, so should `record_arg_spanned` record the span as "location: {}" or similar ?
Make the lifetime accurate which is used in the region constraints part
This PR fixes the FIXME about lifetime using in the region constraints part.
We cannot write `<'graph, 'tcx, D>` because the definition of `Successors<'0, '1, D>` requires `'1 : '0`.
We cannot add bound to `'graph` either because `'graph` is required to be an arbitrary value in the definition of `WithSuccessors`
So the most accurate way is to use `<'s, 'tcx, D>`.
cc `@Aaron1011` who added this FIXME in #85343
The self-profiler's `EventArgRecorder` is general-purpose in its ability to record Strings (and `rustc_span` depends on the crate its defined in, `rustc_data_structure`).
Some generic activities could use recording locations where they happen in the user's code: to allow e.g. to track macro expansions and diagnose performance issues there.
This adds a `SpannedEventArgRecorder` that can record an argument given as a span, rather than a String, since turning spans into Strings can be tricky if you're not happy with its default Debug output. This way the recorder can have a `record_arg_spanned` method which will do that.
Make all thir types implement clone
This PR adds `Clone` impl to all of the `Thir<'tcx>` types.
I would like to be able to clone a `Thir` body so that I can make a copy in my rustc driver without breaking further compilation. Without this my driver is forced to run in the `after_expansion` callback and thus doesn't benefit from running all the safety checks that `rustc` usually does, instead i need to do them all myself.
errors: minor translation-related changes
- For one error in typeck, specifying "suggestion" as the attribute for the only suggestion is unnecessary, it's the default of the derive.
- The documentation comment for the `SessionDiagnostic` derive is out-of-date, it should have been updated in #95512.
r? `@oli-obk`
Only output DepKind in dump-dep-graph.
When printing the whole DepNode, the output file is simply too massive to
be actually useful for profiling.
This trimmed down version mixes a lot of information together, but it also
allows to ask questions such that "why does this query ever access HIR?".
bootstrap: add split-debuginfo config
Replace `run-dysutil` option with more general `split-debuginfo` option that works on all platforms.
r? `@Mark-Simulacrum`
This lets us clone just the parts within a `TokenTree` that need
cloning, rather than the entire thing. This is a surprisingly large
performance win, up to 4% on `async-std-1.10.0`.
Specifying "suggestion" as the attribute for the only suggestion is
unnecessary, it's the default of the derive.
Signed-off-by: David Wood <david.wood@huawei.com>
This makes `CloseDelim` handling more like `OpenDelim` handling, which
produces `OpenDelim` and pushes the stack at the same time. It requires
some adjustment to `parse_token_tree` now that we don't remain within
the frame after getting the `CloseDelim`.
Add an explicit `Span` field to `OutlivesConstraint`
Previously, we would retrieve the span from the `Body` using
the `locations` field. However, we may end up changing the
`locations` field when moving a constraint from a promoted
to a different body.
We now store the original `Span` in a dedication field, so that
changes to the `locations` do not affect the quality of our
diagnostics.
Check if call return type is visibly uninhabited when building MIR
The main motivation behind the change is to expose information about diverging
calls to the generator transform and match the precision of drop range tracking
which already understands that call expressions with visibly uninhabited types
diverges.
This change should also accept strictly more programs than before. That is
programs that were previously rejected due to errors raised by control-flow
sensitive checks in a code that is no longer considered reachable.
Fixes#93161.
A Google search of the error message fails to return any relevant
resuts, suggesting this has never occurred in practice. And removeing it
reduces instruction counts by up to 2% on some benchmarks.
Previously, we would retrieve the span from the `Body` using
the `locations` field. However, we may end up changing the
`locations` field when moving a constraint from a promoted
to a different body.
We now store the original `Span` in a dedication field, so that
changes to the `locations` do not affect the quality of our
diagnostics.
The loop is there to handle a `NoDelim` open/close token. This commit
changes `TokenCursor::inlined_next` so it never returns such a token.
This is a performance win because the conditional test in `bump()` is
removed.
If the parser needs changing in the future to handle `NoDelim` tokens,
then `inlined_next()` can easily be changed to return them.
The `DelimToken` here is `NoDelim`, which means the returned delim
tokens will just be ignored by `Parser::bump()`. This commit changes
things so the delim tokens won't be returned.
Miri provenance cleanup
Reviewing https://github.com/rust-lang/rust/pull/95826 by ``@carbotaniuman`` made me realize that we could clean things up a little here.
``@carbotaniuman`` please let me know if you're okay with landing this (it will create a lot of conflicts with your PR), or if you'd prefer incorporating the ideas from this PR into yours. I think we want to end up in a situation where the function you called `ptr_reify_alloc` returns just two things, a concrete tag and an offset. Getting an `AllocId` from a concrete tag should be infallible like now. However a concrete tag and `Tag` don't have to be the same type.
r? ``@oli-obk``
interpret: Fix writing uninit to an allocation
When calling `mark_init`, we need to also be mindful of what happens with the relocations! Specifically, when we de-init memory, we need to clear relocations in that range as well or else strange things will happen (and printing will not show the de-init, since relocations take precedence there).
Fixes https://github.com/rust-lang/miri/issues/2068.
Here's the Miri testcase that this fixes (requires `-Zmiri-disable-validation`):
```rust
use std::mem::MaybeUninit;
fn main() { unsafe {
let mut x = MaybeUninit::<i64>::uninit();
// Put in a ptr.
x.as_mut_ptr().cast::<&i32>().write_unaligned(&0);
// Overwrite parts of that pointer with 'uninit' through a Scalar.
let ptr = x.as_mut_ptr().cast::<i32>();
*ptr = MaybeUninit::uninit().assume_init();
// Reading this back should hence work fine.
let _c = *ptr;
} }
```
Previously this failed with
```
error: unsupported operation: unable to turn pointer into raw bytes
--> ../miri/uninit.rs:11:14
|
11 | let _c = *ptr;
| ^^^^ unable to turn pointer into raw bytes
|
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
= note: inside `main` at ../miri/uninit.rs:11:14
```
Refactor loop into iterator; simplify negation logic.
is_dummy should return when a non-dummy is found, but instead is iterated until completion. With some inspiration from line 323 this was refactored to a single line that returns once a single counterexample is found.
asm: Add a kreg0 register class on x86 which includes k0
Previously we only exposed a kreg register class which excludes the k0
register since it can't be used in many instructions. However k0 is a
valid register and we need to have a way of marking it as clobbered for
clobber_abi.
Fixes#94977
Previously we only exposed a kreg register class which excludes the k0
register since it can't be used in many instructions. However k0 is a
valid register and we need to have a way of marking it as clobbered for
clobber_abi.
Fixes#94977
Rollup of 6 pull requests
Successful merges:
- #94493 (Improved diagnostic on failure to meet send bound on future in a foreign crate)
- #95809 (Fix typo in bootstrap.py)
- #96086 (Remove `--extern-location` and all associated code)
- #96089 (`alloc`: make `vec!` unavailable under `no_global_oom_handling`)
- #96122 (Fix an invalid error for a suggestion to add a slice in pattern-matching)
- #96142 (Stop using CRATE_DEF_INDEX outside of metadata encoding.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Stop using CRATE_DEF_INDEX outside of metadata encoding.
`CRATE_DEF_ID` and `CrateNum::as_def_id` are almost always what we want. We should not manipulate raw `DefIndex` outside of metadata encoding.
Remove `--extern-location` and all associated code
`--extern-location` was an experiment to investigate the best way to
generate useful diagnostics for unused dependency warnings by enabling a
build system to identify the corresponding build config.
While I did successfully use this, I've since been convinced the
alternative `--json unused-externs` mechanism is the way to go, and
there's no point in having two mechanisms with basically the same
functionality.
This effectively reverts https://github.com/rust-lang/rust/pull/72603
Improved diagnostic on failure to meet send bound on future in a foreign crate
Provide a better diagnostic on failure to meet send bound on futures in a foreign crate.
fixes#78543
This will facilitate the change in the next commit.
`boolean` arguments aren't great, but the function is only used in three
places within this one file.
In particular, avoid wrapping a token within `TokenTree::Token` and then
immediately matching it and returning the token within. Just return the
token immediately.
show suggestion to replace generic bounds with associated types in more cases
Moves the hint to replace generic parameters with associated type bounds from the "not all associated type bounds are specified"(`E0191`) to "to many generic type parameters provided"(`E0107`).
Since `E0191` is only emitted in places where all associated types must be specified (when creating `dyn` types), the suggesting is currently not shown for other generic type uses (such as in generic type bounds). With this change the suggesting is always emitted when the number of excess generic parameters matches the number of unbound associated types.
Main motivation for the change was a lack of useful suggesting when doing
```rust
fn foo<I: Iterator<usize>>(i: I) {}
```
Report undeclared lifetimes during late resolution.
First step in https://github.com/rust-lang/rust/pull/91557
We reuse the rib design of the current resolution framework. Specific `LifetimeRib` and `LifetimeRibKind` types are introduced. The most important variant is `LifetimeRibKind::Generics`, which happens each time we encounter something which may introduce generic lifetime parameters. It can be an item or a `for<...>` binder. The `LifetimeBinderKind` specifies how this rib behaves with respect to in-band lifetimes.
r? `@petrochenkov`
Remove last vestiges of skippng ident span hashing
This removes a comment that no longer applies, and properly hashes
the full ident for path segments.
Refactor HIR item-like traversal (part 1)
Issue #95004
- Create hir_crate_items query which traverses tcx.hir_crate(()).owners to return a hir::ModuleItems
- use tcx.hir_crate_items in tcx.hir().items() to return an iterator of hir::ItemId
- use tcx.hir_crate_items to introduce a tcx.hir().par_items(impl Fn(hir::ItemId)) to traverse all items in parallel;
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
cc `@cjgillot`
Strict provenance lint diagnostics improvements
Use `multipart_suggestion` instead of `span_suggestion` and getting a snippet for the expression. Also don't suggest unnecessary parenthesis in `lossy_provenance_casts`.
cc ``@estebank``
``@rustbot`` label A-diagnostics
rustc_metadata: Do not encode unnecessary module children
This should remove the syntax context shift and the special case for `ExternCrate` in decoder in https://github.com/rust-lang/rust/pull/95880.
This PR also shifts some work from decoding to encoding, which is typically useful for performance (but probably not much in this case).
r? `@cjgillot`
Include Refs in Valtree Creation
This adds references to `const_to_valtree`, which isn't used in the compiler yet, but after the previous changes we made to the thir and mir representations and this change we should be able to finally introduce them in the next PR.
I wasn't able to properly test this code, except indirectly by including a call of `const_to_valtree` in the code that currently creates constants (`turn_into_const_value`).
r? `@lcnr`
cc `@oli-obk` `@RalfJung`
Parse inner attributes on inline const block
According to https://github.com/rust-lang/rust/pull/84414#issuecomment-826150936, inner attributes are intended to be supported *"in all containers for statements (or some subset of statements)"*.
This PR adds inner attribute parsing and pretty-printing for inline const blocks (https://github.com/rust-lang/rust/issues/76001), which contain statements just like an unsafe block or a loop body.
```rust
let _ = const {
#![allow(...)]
let x = ();
x
};
```
resolve: Create dummy bindings for all unresolved imports
Apparently such bindings weren't previously created for all unresolved imports, causing issues like https://github.com/rust-lang/rust/issues/95879.
In this PR I'm trying to create such dummy bindings in a more centralized way by calling `import_dummy_binding` once for all imports in `finalize_imports`.
Fixes https://github.com/rust-lang/rust/issues/95879.
Allow self-profiler to only record potentially costly arguments when argument recording is turned on
As discussed [on zulip](https://rust-lang.zulipchat.com/#narrow/stream/247081-t-compiler.2Fperformance/topic/Identifying.20proc-macro.20slowdowns/near/277304909) with `@wesleywiser,` I'd like to record proc-macro expansions in the self-profiler, with some detailed data (per-expansion spans for example, to follow #95473).
At the same time, I'd also like to avoid doing expensive things when tracking a generic activity's arguments, if they were not specifically opted into the event filter mask, to allow the self-profiler to be used in hotter contexts.
This PR tries to offer:
- a way to ensure a closure to record arguments will only be called in that situation, so that potentially costly arguments can still be recorded when needed. With the additional requirement that, if possible, it would offer a way to record non-owned data without adding many `generic_activity_with_arg_{...}`-style methods. This lead to the `generic_activity_with_arg_recorder` single entry-point, and the closure parameter would offer the new methods, able to be executed in a context where costly argument could be created without disturbing the profiled piece of code.
- some facilities/patterns allowing to record more rustc specific data in this situation, without making `rustc_data_structures` where the self-profiler is defined, depend on other rustc crates (causing circular dependencies): in particular, spans. They are quite tricky to turn into strings (if the default `Debug` impl output does not match the context one needs them for), and since I'd also like to avoid the allocation there when arg recording is turned off today, that has turned into another flexibility requirement for the API in this PR (separating the span-specific recording into an extension trait). **edit**: I've removed this from the PR so that it's easier to review, and opened https://github.com/rust-lang/rust/pull/95739.
- allow for extensibility in the future: other ways to record arguments, or additional data attached to them could be added in the future (e.g. recording the argument's name as well as its data).
Some areas where I'd love feedback:
- the API and names: the `EventArgRecorder` and its method for example. As well as the verbosity that comes from the increased flexibility.
- if I should convert the existing `generic_activity_with_arg{s}` to just forward to `generic_activity_with_arg_recorder` + `recorder.record_arg` (or remove them altogether ? Probably not): I've used the new API in the simple case I could find of allocating for an arg that may not be recorded, and the rest don't seem costly.
- [x] whether this API should panic if no arguments were recorded by the user-provided closure (like this PR currently does: it seems like an error to use an API dedicated to record arguments but not call the methods to then do so) or if this should just record a generic activity without arguments ?
- whether the `record_arg` function should be `#[inline(always)]`, like the `generic_activity_*` functions ?
As mentioned, r? `@wesleywiser` following our recent discussion.
Adding diagnostic data on generators to the crate metadata and using it to provide
a better diagnostic on failure to meet send bound on futures originated from a foreign crate
Rollup of 9 pull requests
Successful merges:
- #93969 (Only add codegen backend to dep info if -Zbinary-dep-depinfo is used)
- #94605 (Add missing links in platform support docs)
- #95372 (make unaligned_references lint deny-by-default)
- #95859 (Improve diagnostics for unterminated nested block comment)
- #95961 (implement SIMD gather/scatter via vector getelementptr)
- #96004 (Consider lifetimes when comparing types for equality in MIR validator)
- #96050 (Remove some now-dead code that was only relevant before deaggregation.)
- #96070 ([test] Add test cases for untested functions for BTreeMap)
- #96099 (MaybeUninit array cleanup)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Better method call error messages
Rebase/continuation of #71827
~Based on #92360~
~Based on #93118~
There's a decent description in #71827 that I won't copy here (for now at least)
In addition to rebasing, I've tried to restore most of the original suggestions for invalid arguments. Unfortunately, this does make some of the errors a bit verbose. To fix this will require a bit of refactoring to some of the generalized error suggestion functions, and I just don't have the time to go into it right now.
I think this is in a state that the error messages are overall better than before without a reduction in the suggestions given.
~I've tried to split out some of the easier and self-contained changes into separate commits (mostly in #92360, but also one here). There might be more than can be done here, but again just lacking time.~
r? `@estebank` as the original reviewer of #71827
This attempts to bring better error messages to invalid method calls, by applying some heuristics to identify common mistakes.
The algorithm is inspired by Levenshtein distance and longest common sub-sequence. In essence, we treat the types of the function, and the types of the arguments you provided as two "words" and compute the edits to get from one to the other.
We then modify that algorithm to detect 4 cases:
- A function input is missing
- An extra argument was provided
- The type of an argument is straight up invalid
- Two arguments have been swapped
- A subset of the arguments have been shuffled
(We detect the last two as separate cases so that we can detect two swaps, instead of 4 parameters permuted.)
It helps to understand this argument by paying special attention to terminology: "inputs" refers to the inputs being *expected* by the function, and "arguments" refers to what has been provided at the call site.
The basic sketch of the algorithm is as follows:
- Construct a boolean grid, with a row for each argument, and a column for each input. The cell [i, j] is true if the i'th argument could satisfy the j'th input.
- If we find an argument that could satisfy no inputs, provided for an input that can't be satisfied by any other argument, we consider this an "invalid type".
- Extra arguments are those that can't satisfy any input, provided for an input that *could* be satisfied by another argument.
- Missing inputs are inputs that can't be satisfied by any argument, where the provided argument could satisfy another input
- Swapped / Permuted arguments are identified with a cycle detection algorithm.
As each issue is found, we remove the relevant inputs / arguments and check for more issues. If we find no issues, we match up any "valid" arguments, and start again.
Note that there's a lot of extra complexity:
- We try to stay efficient on the happy path, only computing the diagonal until we find a problem, and then filling in the rest of the matrix.
- Closure arguments are wrapped in a tuple and need to be unwrapped
- We need to resolve closure types after the rest, to allow the most specific type constraints
- We need to handle imported C functions that might be variadic in their inputs.
I tried to document a lot of this in comments in the code and keep the naming clear.
Remove some now-dead code that was only relevant before deaggregation.
The code was broken anyway, if the deaggregator is disabled, it would have ICEd on any non-enum Adt
r? ```@RalfJung```
implement SIMD gather/scatter via vector getelementptr
Fixes https://github.com/rust-lang/portable-simd/issues/271
However, I don't *really* know what I am doing here... Cc ``@workingjubilee`` ``@calebzulawski``
I didn't do anything for cranelift -- ``@bjorn3`` not sure if it's okay for that backend to temporarily break. I'm happy to cherry-pick a patch that adds cranelift support. :)
Improve diagnostics for unterminated nested block comment
close#95283
(This is my first time try to messing around with rust compiler and might get a lot of things wrong... 🙇 )
make unaligned_references lint deny-by-default
This lint has been warn-by-default for a year now (since https://github.com/rust-lang/rust/pull/82525), so I think it is time to crank it up a bit. Code that triggers the lint causes UB (without `unsafe`) when executed, so we really don't want people to write code like this.
Only add codegen backend to dep info if -Zbinary-dep-depinfo is used
I am currently migrating the cg_clif build system from using a binary linked to the codegen backend as rustc replacement to passing `-Zcodegen-backend` instead. Without this PR this would force cargo to rebuild the sysroot on any change to the codegen backend even if I explicitly specify that I want it to be preserved, which would make development of cg_clif a lot slower. If you still want to have changes to the codegen backend invalidate the cargo build cache you can explicitly specify `-Zbinary-dep-depinfo`.
cc ``@eddyb`` as the codegen backend was initially added to the depinfo for rust-gpu.
Implement sym operands for global_asm!
Tracking issue: #93333
This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are:
- At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`.
- At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails).
- `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`.
- `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to.
- The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression.
- At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
- On Mach-O, all symbols have a leading underscore.
- On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
- No mangling is needed on other platforms.
r? `@nagisa`
cc `@eddyb`
only downgrade selection Error -> Ambiguous if type error is in predicate
That is, we don't care if there's a TypeError type in the ParamEnv.
Fixes#95408
remove find_use_placement
A more robust solution to finding where to place use suggestions was added in #94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`
Fixes#94941
Check var scope if it exist
Fixes#92893.
Added helper function to check the scope of a variable, if it doesn't have a scope call delay_span_bug, which avoids us trying to get a block/scope that doesn't exist.
Had to increase `ROOT_ENTRY_LIMIT` was getting tidy error
Create (unstable) 2024 edition
[On Zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Deprecating.20macro.20scoping.20shenanigans/near/272860652), there was a small aside regarding creating the 2024 edition now as opposed to later. There was a reasonable amount of support and no stated opposition.
This change creates the 2024 edition in the compiler and creates a prelude for the 2024 edition. There is no current difference between the 2021 and 2024 editions. Cargo and other tools will need to be updated separately, as it's not in the same repository. This change permits the vast majority of work towards the next edition to proceed _now_ instead of waiting until 2024.
For sanity purposes, I've merged the "hello" UI tests into a single file with multiple revisions. Otherwise we'd end up with a file per edition, despite them being essentially identical.
````@rustbot```` label +T-lang +S-waiting-on-review
Not sure on the relevant team, to be honest.
Stabilize `derive_default_enum`
This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](https://github.com/rust-lang/rfcs/pull/3107) and tracked in #87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility).
```````@rustbot``````` label +S-waiting-on-review +T-lang
`--extern-location` was an experiment to investigate the best way to
generate useful diagnostics for unused dependency warnings by enabling a
build system to identify the corresponding build config.
While I did successfully use this, I've since been convinced the
alternative `--json unused-externs` mechanism is the way to go, and
there's no point in having two mechanisms with basically the same
functionality.
This effectively reverts https://github.com/rust-lang/rust/pull/72603
when checking pointee metadata, canonicalize the `Sized` check
Use `infcx.predicate_must_hold_modulo_regions` with a `Sized` obligation instead of just calling `ty.is_sized`, because the latter does not canonicalize region and type vars (and in the test case I added in this PR, there's a region var in the `ParamEnv`).
Fixes#95311
Remove `<mbe::TokenTree as Clone>`
`mbe::TokenTree` doesn't really need to implement `Clone`, and getting rid of that impl leads to some speed-ups.
r? `@petrochenkov`
errors: lazily load fallback fluent bundle
Addresses (hopefully) https://github.com/rust-lang/rust/pull/95667#issuecomment-1094794087.
Loading the fallback bundle in compilation sessions that won't go on to emit any errors unnecessarily degrades compile time performance, so lazily create the Fluent bundle when it is first required.
r? `@ghost` (just for perf initially)
fix: wrong trait import suggestion for T:
The suggestion to bound `T` had an extra `:`.
```rust
fn foo<T:>(t: T) {
t.clone();
}
```
```
error[E0599]: no method named `clone` found for type parameter `T` in the current scope
--> src/lib.rs:2:7
|
2 | t.clone();
| ^^^^^ method not found in `T`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `clone`, perhaps you need to restrict type parameter `T` with it:
|
1 | fn foo<T: Clone:>(t: T) {
| ~~~~~~~~
```
Fixes: #95898
Use mir constant in thir instead of ty::Const
This is blocked on https://github.com/rust-lang/rust/pull/94059 (does include its changes, the first two commits in this PR correspond to those changes) and https://github.com/rust-lang/rust/pull/93800 being reinstated (which had to be reverted). Mainly opening since `@lcnr` offered to give some feedback and maybe also for a perf-run (if necessary).
This currently contains a lot of duplication since some of the logic of `ty::Const` had to be copied to `mir::ConstantKind`, but with the introduction of valtrees a lot of that functionality will disappear from `ty::Const`.
Only the last commit contains changes that need to be reviewed here. Did leave some `FIXME` comments regarding future implementation decisions and some things that might be incorrectly implemented.
r? `@oli-obk`
Loading the fallback bundle in compilation sessions that won't go on to
emit any errors unnecessarily degrades compile time performance, so
lazily create the Fluent bundle when it is first required.
Signed-off-by: David Wood <david.wood@huawei.com>
prevent opaque types from appearing in impl headers
cc `@lqd`
opaque types are not distinguishable from their hidden type at the codegen stage. So we could either end up with cases where the hidden type doesn't implement the trait (which will thus ICE) or where the hidden type does implement the trait (so we'd be using its impl instead of the one written for the opaque type). This can even lead to unsound behaviour without unsafe code.
Fixes https://github.com/rust-lang/rust/issues/86411.
Fixes https://github.com/rust-lang/rust/issues/84660.
rebase of #87382 plus some diagnostic tweaks
Fix suggestions in case of `T:` bounds
This PR fixes a corner case in `suggest_constraining_type_params` that was causing incorrect suggestions.
For the following functions:
```rust
fn a<T:>(t: T) { [t, t]; }
fn b<T>(t: T) where T: { [t, t]; }
```
We previously suggested the following:
```text
...
help: consider restricting type parameter `T`
|
1 | fn a<T: Copy:>(t: T) { [t, t]; }
| ++++++
...
help: consider further restricting this bound
|
2 | fn b<T>(t: T) where T: + Copy { [t, t]; }
| ++++++
```
Note that neither `T: Copy:` not `where T: + Copy` is a correct bound.
With this commit the suggestions are correct:
```text
...
help: consider restricting type parameter `T`
|
1 | fn a<T: Copy>(t: T) { [t, t]; }
| ++++
...
help: consider further restricting this bound
|
2 | fn b<T>(t: T) where T: Copy { [t, t]; }
| ++++
```
r? `@compiler-errors`
I've tried fixing #95898 here too, but got too confused with how `suggest_traits_to_import` works and what it does 😅
Move name resolution logic to a dedicated file
The code resolution logic from an Ident is scattered between several files.
The first commits creates `rustc_resolve::probe` module to hold the different mutually recursive functions together. Just a move, no code change.
The following commits attempt to make the logic a bit more readable.
The two fields `last_import_segment` and `unusable_binding` are replaced by function parameters.
In order to manage the fallout, `maybe_` variants of the function are added, dedicated to speculative resolution.
r? `@petrochenkov`
Rollup of 4 pull requests
Successful merges:
- #95783 (rustdoc doctest: include signal number in exit status)
- #95794 (`parse_tt`: a few more tweaks)
- #95963 ([bootstrap] Grab the right FileCheck binary for dist when cross-compiling.)
- #95975 (Don't test -Cdefault-linker-libraries=yes when cross compiling.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Skip `Lazy` for some metadata tables
Some metadata tables encode their entries indirectly, through the Lazy construct. This is useful when dealing with variable length encoding, but incurs the extra cost of one u32.
Meanwhile, some fields can be encoded in a single u8, or can use a short fixed-length encoding. This PR proposes to do so, and avoid the overhead.
`impl const Default for Box<[T]>` and `Box<str>`
The unstable `const_default_impls` (#87864) already include empty `Vec<T>` and `String`. Now we extend that concept to `Box<[T]>` and `Box<str>` as well.
This obviates a hack in `rustc_ast`'s `P::<[T]>::new`.
Instead of checking only the user provided sysroot or the default (when
no sysroot is provided), search user provided sysroot and then check
default sysroots for locale requested by the user.
Signed-off-by: David Wood <david.wood@huawei.com>
use `Span::find_ancestor_inside` to get right span in CastCheck
This is a quick fix. This bad suggestion likely lives in other places... but thought it would be useful to fix all of the CastCheck ones first.
Let me know if reviewer would prefer I add more tests for each of the diagnostics in CastCheck, or would like to do a more thorough review of other suggestions that use spans in typeck. I would also be open to further suggestions on how to better expose an API that gives us the "best" span for a diagnostic suggestion.
Fixed#95919
Fix crate_type attribute to not warn on duplicates
In #88681 I accidentally marked the `crate_type` attribute as only allowing a single attribute. However, multiple attributes are allowed (they are joined together [here](027a232755/compiler/rustc_interface/src/util.rs (L530-L542))). This fixes it to not report a warning if duplicates are found.
Closes#95902
Document the current MIR semantics that are clear from existing code
This PR adds documentation to places, operands, rvalues, statementkinds, and terminatorkinds that describes their existing semantics and requirements. In many places the semantics depend on the Rust memory model or other T-Lang decisions - when this is the case, it is just noted as such with links to UCG issues where possible. I'm hopeful that none of the documentation added here can be used to justify optimizations that depend on the memory model. The documentation for places and operands probably comes closest to running afoul of this - if people think that it cannot be merged as is, it can definitely also be taken out.
The goal here is to only document parts of MIR that seem to be decided already, or are at least depended on by existing code. That leaves quite a number of open questions - those are marked as "needs clarification." I'm not sure what to do with those in this PR - we obviously can't decide all these questions here. Should I just leave them in as is? Take them out? Keep them in but as `//` instead of `///` comments?
If this is too big to review at once, I can split this up.
r? rust-lang/mir-opt
Respect -Z verify-llvm-ir and other flags that add extra passes when combined with -C no-prepopulate-passes in the new LLVM Pass Manager.
As part of the switch to the new LLVM Pass Manager the behaviour of flags such as `-Z verify-llvm-ir` (e.g. sanitizer, instrumentation) was modified when combined with `-C no-prepopulate-passes`. With the old PM, rustc was the one manually constructing the pipeline and respected those flags but in the new pass manager, those flags are used to build a list of callbacks that get invoked at certain extension points in the pipeline. Unfortunately, `-C no-prepopulate-passes` would skip building the pipeline altogether meaning we'd never add the corresponding passes. The fix here is to just manually invoke those callbacks as needed.
Fixes#95874
Demonstrating the current vs fixed behaviour using the bug in #95864
```console
$ rustc +nightly asm-miscompile.rs --edition 2021 --emit=llvm-ir -C no-prepopulate-passes -Z verify-llvm-ir
$ echo $?
0
$ rustc +stage1 asm-miscompile.rs --edition 2021 --emit=llvm-ir -C no-prepopulate-passes -Z verify-llvm-ir
Basic Block in function '_ZN14asm_miscompile3foo28_$u7b$$u7b$closure$u7d$$u7d$17h360e2f7eee1275c5E' does not have terminator!
label %bb1
LLVM ERROR: Broken module found, compilation aborted!
```
Fix miscompilation of inline assembly with outputs in cases where we emit an invoke instead of call instruction.
We ran into this bug where rustc would segfault while trying to compile certain uses of inline assembly.
Here is a simple repro that demonstrates the issue:
```rust
#![feature(asm_unwind)]
fn main() {
let _x = String::from("string here just cause we need something with a non-trivial drop");
let foo: u64;
unsafe {
std::arch::asm!(
"mov {}, 1",
out(reg) foo,
options(may_unwind)
);
}
println!("{}", foo);
}
```
([playground link](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7d6641e83370d2536a07234aca2498ff))
But crucially `feature(asm_unwind)` is not actually needed and this can be triggered on stable as a result of the way async functions/generators are handled in the compiler. e.g.:
```rust
extern crate futures; // 0.3.21
async fn bar() {
let foo: u64;
unsafe {
std::arch::asm!(
"mov {}, 1",
out(reg) foo,
);
}
println!("{}", foo);
}
fn main() {
futures::executor::block_on(bar());
}
```
([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1c7781c34dd4a3e80ae4bd936a0c82fc))
An example of the incorrect LLVM generated:
```llvm
bb1: ; preds = %start
%1 = invoke i64 asm sideeffect alignstack inteldialect unwind "mov ${0:q}, 1", "=&r,~{dirflag},~{fpsr},~{flags},~{memory}"()
to label %bb2 unwind label %cleanup, !srcloc !9
store i64 %1, i64* %foo, align 8
bb2:
[...snip...]
```
The store should not be placed after the asm invoke but rather should be in the normal control flow basic block (`bb2` in this case).
[Here](https://gist.github.com/luqmana/be1af5b64d2cda5a533e3e23a7830b44) is a writeup of the investigation that lead to finding this.
[`let_chains`] Forbid `let` inside parentheses
Parenthesizes are mostly a no-op in let chains, in other words, they are mostly ignored.
```rust
let opt = Some(Some(1i32));
if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
println!("`b` is declared inside but used outside");
}
```
As seen above, such behavior can lead to confusion.
A proper fix or nested encapsulation would probably require research, time and a modified MIR graph so in this PR I simply denied any `let` inside parentheses. Non-let stuff are still allowed.
```rust
fn main() {
let fun = || true;
if let true = (true && fun()) && (true) {
println!("Allowed");
}
}
```
It is worth noting that `let ...` is not an expression and the RFC did not mention this specific situation.
cc `@matthewjasper`
Rollup of 7 pull requests
Successful merges:
- #95743 (Update binary_search example to instead redirect to partition_point)
- #95771 (Update linker-plugin-lto.md to 1.60)
- #95861 (Note that CI tests Windows 10)
- #95875 (bootstrap: show available paths help text for aliased subcommands)
- #95876 (Add a note for unsatisfied `~const Drop` bounds)
- #95907 (address fixme for diagnostic variable name)
- #95917 (thin_box test: import from std, not alloc)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Only suggest removing semicolon when expression is compatible with `impl Trait`
https://github.com/rust-lang/rust/issues/54771#issuecomment-476423690
> It still needs checking that the last statement's expr can actually conform to the trait, but the naïve behavior is there.
Only suggest removing a semicolon when the type behind the semicolon actually implements the trait in an RPIT `-> impl Trait`. Also upgrade the label that suggests removing the semicolon to a suggestion (should it be verbose?).
cc #54771
When a `macro_rules! foo { ... }` invocation is compiled the name used
is `foo`, not `macro_rules!`. This is different to all other macro
invocations, and confused me when I was inserted debugging println
statements for macro evaluation.
This commit changes it to `macro_rules` (or just `macro`), which is what
I expected. There are no externally visible changes.
Rollup of 7 pull requests
Successful merges:
- #95566 (Avoid duplication of doc comments in `std::char` constants and functions)
- #95784 (Suggest replacing `typeof(...)` with an actual type)
- #95807 (Suggest adding a local for vector to fix borrowck errors)
- #95849 (Check for git submodules in non-git source tree.)
- #95852 (Fix missing space in lossy provenance cast lint)
- #95857 (Allow multiple derefs to be splitted in deref_separator)
- #95868 (rustdoc: Reduce allocations in a `html::markdown` function)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Allow multiple derefs to be splitted in deref_separator
Previously in #95649 only a single deref within projection was supported and multiple derefs caused a bunch of issues, this PR fixes those issues.
```@oli-obk``` helped a ton again ❤️
Suggest replacing `typeof(...)` with an actual type
This PR adds suggestion to replace `typeof(...)` with an actual type of `...`, for example in case of `typeof(1)` we suggest replacing it with `i32`.
If the expression
1. Is not const (`{ let a = 1; let _: typeof(a); }`)
2. Can't be found (`let _: typeof(this_variable_does_not_exist)`)
3. Or has non-suggestable type (closure, generator, error, etc)
we don't suggest anything.
The 1 one is sad, but it's not clear how to support non-consts expressions for `typeof`.
_This PR is inspired by [this tweet]._
[this tweet]: https://twitter.com/compiler_errors/status/1511945354752638976
Make def names and HIR names consistent.
The name in the `DefKey` is interned to create the `DefId`, so it does not
require any query to access. This can be leveraged to avoid a few useless
HIR accesses for names.
~In order to achieve that, generic parameters created from universal
impl-trait are given the pretty-printed ast as a name, instead of
`{{opaque}}`.~
~Drive-by: the `TyCtxt::opt_item_name` used a dummy span for non-local
definitions. We have access to `def_ident_span`, so we use it.~
We may sometimes emit an `invoke` instead of a `call` for inline
assembly during the MIR -> LLVM IR lowering. But we failed to update
the IR builder's current basic block before writing the results to the
outputs. This would result in invalid IR because the basic block would
end in a `store` instruction, which isn't a valid terminator.