Rollup merge of #145399 - estebank:resolve-error-wording-2, r=petrochenkov
Unify wording of resolve error
Remove "failed to resolve" from the main error message and use the same format we use in other resolution errors "cannot find `name`":
```
error[E0433]: cannot find `nonexistent` in `existent`
--> $DIR/custom_attr_multisegment_error.rs:5:13
|
LL | #[existent::nonexistent]
| ^^^^^^^^^^^ could not find `nonexistent` in `existent`
```
The intent behind this is to end up with all resolve errors eventually be on the form of
```
error[ECODE]: cannot find `{NAME}` in {SCOPE}
--> $DIR/file.rs:5:13
|
LL | #[existent::nonexistent]
| ^^^^^^^^^^^ {SPECIFIC LABEL}
```
A category of errors that is interest are those that involve keywords. For example:
```
error[E0433]: cannot find `Self` in this scope
--> $DIR/issue-97194.rs:2:35
|
LL | fn bget(&self, index: [usize; Self::DIM]) -> bool {
| ^^^^ `Self` is only available in impls, traits, and type definitions
```
and
```
error[E0433]: cannot find `super` in this scope
--> $DIR/keyword-super.rs:2:9
|
LL | let super: isize;
| ^^^^^ there are too many leading `super` keywords
```
For these the label provides the actual help, while the message is less informative beyond telling you "couldn't find `name`".
This is an off-shoot of https://github.com/rust-lang/rust/pull/126810 and https://github.com/rust-lang/rust/pull/128086, a subset of the intended changes there with review comments applied.
r? @petrochenkov
Remove "failed to resolve" and use the same format we use in other resolution errors "cannot find `name`".
```
error[E0433]: cannot find `nonexistent` in `existent`
--> $DIR/custom_attr_multisegment_error.rs:5:13
|
LL | #[existent::nonexistent]
| ^^^^^^^^^^^ could not find `nonexistent` in `existent`
```
remove `#![allow(stable_features)]` from most tests
The only remaining usages are tests that specifically deal with feature gates.
This also deletes the very weird `#![feature(issue_5723_bootstrap)]`, a 13 year old "temporary fix" (rust-lang/rust#5723).
Revert "Fix an ICE in the vtable iteration for a trait reference"
The ICE fix appears to be unsound, causing a miscompilation involving `dyn Trait` and `async {}` which induces segfaults in safe Rust code. As the patch only hid an ICE, it does not seem worth the risk.
This addresses the problem in rust-lang/rust#152735 but it may still merit team discussion even if this PR is merged.
This reverts commit 8afd63610b, reversing changes made to 19122c03c7.
Suppress unstable-trait notes under `-Zforce-unstable-if-unmarked`
- Fixes https://github.com/rust-lang/rust/issues/152692.
---
https://github.com/rust-lang/rust/pull/151036 adds extra diagnostic text (“the nightly-only, unstable trait”) to note when a not-implemented trait is unstable.
However, that extra text is usually unhelpful when building a crate graph with `-Zforce-unstable-if-unmarked` (such as the compiler or stdlib), because *any* trait not explicitly marked stable will be treated as unstable.
(For typical compiler contributors using the stage0 compiler, this fix won't take effect until the next bootstrap beta bump.)
Avoid ICE in From/TryFrom diagnostic under -Znext-solver
Fixesrust-lang/rust#152518.
Under `-Znext-solver=globally`, `trait_ref.args` may contain fewer
elements than expected. The diagnostic logic in
`fulfillment_errors.rs` assumed at least two elements and
unconditionally called `type_at(1)`, which could lead to an
index out-of-bounds panic during error reporting.
This change adds a defensive check before accessing the second
argument to avoid the ICE. A UI regression test has been added.
Implement RFC 3678: Final trait methods
Tracking: https://github.com/rust-lang/rust/issues/131179
This PR is based on rust-lang/rust#130802, with some minor changes and conflict resolution.
Futhermore, this PR excludes final methods from the vtable of a dyn Trait.
And some excerpt from the original PR description:
> Implements the surface part of https://github.com/rust-lang/rfcs/pull/3678.
>
> I'm using the word "method" in the title, but in the diagnostics and the feature gate I used "associated function", since that's more accurate.
cc @joshtriplett
The ICE fix appears to be unsound, causing a miscompilation involving
`dyn Trait` and `async {}` which induces segfaults in safe Rust code.
As the patch only hid an ICE, it does not seem worth the risk.
This reverts commit 8afd63610b, reversing
changes made to 19122c03c7.
replace box_new with lower-level intrinsics
The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).
This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.
To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)
See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.
This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.
I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.
### `vec!` FAQ
- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
Consider captures to be used by closures that unwind
Assignments to a captured variable within a diverging closure should not be considered unused if the divergence is caught.
This patch considers such assignments/captures to be used by diverging closures irrespective of whether the divergence is caught, but better a false negative unused lint than a false positive one (the latter having caused a stable-to-stable regression).
Fixesrust-lang/rust#152079
r? compiler
support c-variadic functions in `rustc_const_eval`
tracking issue: https://github.com/rust-lang/rust/issues/44930
The new `GlobalAlloc::VaList` is used to create an `AllocId` that represents the variable argument list of a frame. The allocation itself does not store any data, all we need is the unique identifier.
The actual variable argument list is stored in `Memory`, and keyed by the `AllocId`. The `Frame` also stores this `AllocId`, so that when a frame is popped, it can deallocate the variable arguments.
At "runtime" a `VaList` value stores a pointer to the global allocation in its first bytes. The provenance on this pointer can be used to retrieve its `AllocId`, and the offset of the pointer is used to store the index of the next argument to read from the variable argument list.
Miri does not yet support `va_arg`, but I think that can be done separetely?
r? @RalfJung
cc @workingjubilee
feat: show what lint was overruled
We can't `#[allow]` a whole lint group if any of its members is forbidden, but the offending member is not currently shown if it was forbidden from the command line.
Before/after:
```diff
$ rustc -F dead_code - <<< '#![allow(unused)]'
error[E0453]: allow(unused) incompatible with previous forbid
--> <anon>:1:10
|
1 | #![allow(unused)]
| ^^^^^^ overruled by previous forbid
|
- = note: `forbid` lint level was set on command line
+ = note: `forbid` lint level was set on command line (`-F dead_code`)
error: aborting due to 1 previous error
```
@rustbot label +A-diagnostics +A-lints +D-terse
Add regression test for #141738Closesrust-lang/rust#141738
- Add a regression test for rust-lang/rust#141738
- Using a struct constructor (`DefKind::Ctor(Struct, Const)`) as an array repeat count with `#![feature(min_generic_const_args)]` used to ICE in const alias normalization
- Fixed by rust-lang/rust#150704, which added const constructor support for mGCA. This test covers the **error path** (struct ctor where `usize` is expected), which was not covered by the tests in rust-lang/rust#150704
Improve write! and writeln! error when called without destination
Fixesrust-lang/rust#152493
Adds catch-all arms to `write!` and `writeln!` macros so that calling them without a destination (e.g., `write!("S")` instead of `write!(f, "S")`) gives a clear error instead of the cryptic "unexpected end of macro invocation" pointing at macro internals.
r? @estebank
diagnostics: add note when param-env shadows global impl
This PR adds a diagnostics note when param-env shadows global impl as discussed in https://github.com/rust-lang/rust/issues/149910
It adds a note explaining that the definition is hidden by the generic bound.
r?lcnr
Optimize indexing slices and strs with inclusive ranges
Instead of separately checking for `end == usize::MAX` and `end + 1 > slice.len()`, we can check for `end >= slice.len()`. Also consolidate all the str indexing related panic functions into a single function which reports the correct error depending on the arguments, as the slice indexing code already does.
The downside of all this is that the panic message is slightly less specific when trying to index with `[..=usize::MAX]`: instead of saying "attempted to index str up to maximum usize" it just says "end byte index {end} out of bounds". But this is a rare enough case that I think it is acceptable
Using a struct constructor (DefKind::Ctor(Struct, Const)) as an array
repeat count with `#![feature(min_generic_const_args)]` used to trigger
an ICE in const alias normalization. Add a regression test to ensure
the compiler produces a proper type error instead of panicking.
Don't ICE on layout error in vtable computation
Fixesrust-lang/rust#152030.
Note: I'm including a more general testcase that doesn't use the feature in the original report, but only reproduces with debuginfo disabled. Does it make sense to also include the original testcase?