Improve anonymous lifetime note to indicate the target span
Improvement for #81650
Cc #81995
Message after this improvement:
(Improve note in the middle)
```
error[E0311]: the parameter type `T` may not live long enough
--> src/main.rs:25:11
|
24 | fn play_with<T: Animal + Send>(scope: &Scope, animal: T) {
| -- help: consider adding an explicit lifetime bound...: `T: 'a +`
25 | scope.spawn(move |_| {
| ^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime defined on the function body at 24:40...
--> src/main.rs:24:40
|
24 | fn play_with<T: Animal + Send>(scope: &Scope, animal: T) {
| ^^^^^
note: ...so that the type `[closure@src/main.rs:25:17: 27:6]` will meet its required lifetime bounds
--> src/main.rs:25:11
|
25 | scope.spawn(move |_| {
| ^^^^^
```
r? ``````@estebank``````
fix the false 'defined here' messages
Closes#80853.
Take this code:
```rust
struct S;
fn repro_ref(thing: S) {
thing();
}
```
Previously, the error message would be this:
```
error[E0618]: expected function, found `S`
--> src/lib.rs:4:5
|
3 | fn repro_ref(thing: S) {
| ----- `S` defined here
4 | thing();
| ^^^^^--
| |
| call expression requires function
error: aborting due to previous error
```
This is incorrect as `S` is not defined in the function arguments, `thing` is defined there. With this change, the following is emitted:
```
error[E0618]: expected function, found `S`
--> $DIR/80853.rs:4:5
|
LL | fn repro_ref(thing: S) {
| ----- is of type `S`
LL | thing();
| ^^^^^--
| |
| call expression requires function
|
= note: local variable `S` is not a function
error: aborting due to previous error
```
As you can see, this error message points out that `thing` is of type `S` and later in a note, that `S` is not a function. This change does seem like a downside for some error messages. Take this example:
```
LL | struct Empty2;
| -------------- is of type `Empty2`
```
As you can see, the error message shows that the definition of `Empty2` is of type `Empty2`. Although this isn't wrong, it would be more helpful if it would say something like this (which was there previously):
```
LL | struct Empty2;
| -------------- `Empty2` defined here
```
If there is a better way of doing this, where the `Empty2` example would stay the same as without this change, please inform me.
**Update: This is now fixed**
CC `@camelid`
Improve suggestion for tuple struct pattern matching errors.
Closes#80174
This change allows numbers to be parsed as field names when pattern matching on structs, which allows us to provide better error messages when tuple structs are matched using a struct pattern.
r? ``@estebank``
Make "missing field" error message more natural
```rust
struct A {
x: i32,
y: i32,
z: i32,
}
fn main() {
A { };
}
```
```
error[E0063]: missing fields `x`, `y`, `z` in initializer of `A`
--> src/main.rs:8:5
|
8 | A { };
| ^ missing `x`, `y`, `z`
```
This error is now:
```
error[E0063]: missing fields `x`, `y` and `z` in initializer of `A`
--> src/main.rs:8:5
|
8 | A { };
| ^ missing `x`, `y` and `z`
```
I thought it looked nicer and more natural this way. Also, if there is >3 fields missing, there is an "and" as well ("missing \`x\`, \`y\`, \`z\` *and* 1 other field"), but for <=3 there is not. As such it improves consistency too.
As for the implementation, originally I ended up with a chunky `push_str` algorithm but then I figured I could just do the formatting manually since it's just 3 field names at maximum. It is comparatively readable.
As a sidenote, one thing I was wondering about is, isn't there more cases where you have a list of things like field names? Maybe this whole thing can at some point later be made into a more general function to be used in multiple areas.
Improve assert_eq! and assert_ne!
This PR improves `assert_eq!` and `assert_ne!` by moving the panicking code in an external function.
It does not change the fast path, but the move of the formatting in the cold path (the panic) may have a positive effect on in instruction cache use and with inlining.
Moreover, the use of trait objects instead of generic may improve compile times for `assert_eq!`-heavy code.
Godbolt link: ~~https://rust.godbolt.org/z/TYa9MT~~ \
Updated: https://rust.godbolt.org/z/bzE84x
ast: Keep expansion status for out-of-line module items
I.e. whether a module `mod foo;` is already loaded from a file or not.
This is a pre-requisite to correctly treating inner attributes on such modules (https://github.com/rust-lang/rust/issues/81661).
With this change AST structures for `mod` items diverge even more for AST structure for the crate root, which previously used `ast::Mod`.
Therefore this PR removes `ast::Mod` from `ast::Crate` in the first commit, these two things are sufficiently different from each other, at least at syntactic level.
Customization points for visiting a "`mod` item or crate root" were also removed from AST visitors (`fn visit_mod`).
`ast::Mod` itself was refactored away in the second commit in favor of `ItemKind::Mod(Unsafe, ModKind)`.
Replace if-let and while-let with `if let` and `while let`
This pull request replaces if-let and while-let with `if let` and `while let`.
closes https://github.com/rust-lang/rust/issues/82205
Crate root is sufficiently different from `mod` items, at least at syntactic level.
Also remove customization point for "`mod` item or crate root" from AST visitors.
Placeholder lifetime error cleanup
- Remove note of trait definition
- Avoid repeating the same self type
- Use original region names when possible
- Use this error kind more often
- Print closure signatures when they are suppose to implement `Fn*` traits
Works towards #57374
r? ```@nikomatsakis```
Add 'consider using' message to overflowing_literals
Fixes#79744.
Ironically, the `overflowing_literals` handler for binary or hex already
had this message! You would think it would be the other way around :)
cc ```@scottmcm```
Fixing bad suggestion for `_` in `const` type when a function #81885Closes#81885
```
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item_help.rs:13:22
|
LL | const TEST4: fn() -> _ = 42;
| ^
| |
| not allowed in type signatures
| help: use type parameters instead: `T`
```
Do not show the suggestion `help: use type parameters instead: T` when `fn`
If we have a cause containing `ValuePairs::PolyTraitRefs` but neither
TraitRef has any escaping bound regions then we report the same error as
for `ValuePairs::TraitRefs`.
Fix derived PartialOrd operators
The derived implementation of `partial_cmp` compares matching fields one
by one, stopping the computation when the result of a comparison is not
equal to `Some(Equal)`.
On the other hand the derived implementation for `lt`, `le`, `gt` and
`ge` continues the computation when the result of a field comparison is
`None`, consequently those operators are not transitive and inconsistent
with `partial_cmp`.
Fix the inconsistency by using the default implementation that fall-backs
to the `partial_cmp`. This also avoids creating very deeply nested
closures that were quite costly to compile.
Fixes#81373.
Helps with #81278, #80118.
Allow Trait inheritance with cycles on associated types take 2
This reverts the revert of #79209 and fixes the ICEs that's occasioned by that PR exposing some problems that are addressed in #80648 and #79811.
For easier review I'd say, check only the last commit, the first one is just a revert of the revert of #79209 which was already approved.
This also could be considered part or the actual fix of #79560 but I guess for that to be closed and fixed completely we would need to land #80648 and #79811 too.
r? `@nikomatsakis`
cc `@Aaron1011`
parse_format: treat r" as a literal
This PR changes `format_args!` internal parsing machinery to treat raw strings starting `r"` as a literal.
Currently `"` and `r#` are recognised as valid starting combinations for string literals, but `r"` is not.
This was noticed when debugging https://github.com/rust-lang/rust/issues/67984#issuecomment-753413156
As well as fixing the behavior observed in that comment, this improves diagnostic spans for `r"` formatting strings.
Improve SIMD type element count validation
Resolvesrust-lang/stdsimd#53.
These changes are motivated by `stdsimd` moving in the direction of const generic vectors, e.g.:
```rust
#[repr(simd)]
struct SimdF32<const N: usize>([f32; N]);
```
This makes a few changes:
* Establishes a maximum SIMD lane count of 2^16 (65536). This value is arbitrary, but attempts to validate lane count before hitting potential errors in the backend. It's not clear what LLVM's maximum lane count is, but cranelift's appears to be much less than `usize::MAX`, at least.
* Expands some SIMD intrinsics to support arbitrary lane counts. This resolves the ICE in the linked issue.
* Attempts to catch invalid-sized vectors during typeck when possible.
Unresolved questions:
* Generic-length vectors can't be validated in typeck and are only validated after monomorphization while computing layout. This "works", but the errors simply bail out with no context beyond the name of the type. Should these errors instead return `LayoutError` or otherwise provide context in some way? As it stands, users of `stdsimd` could trivially produce monomorphization errors by making zero-length vectors.
cc `@bjorn3`
expand/resolve: Turn `#[derive]` into a regular macro attribute
This PR turns `#[derive]` into a regular attribute macro declared in libcore and defined in `rustc_builtin_macros`, like it was previously done with other "active" attributes in https://github.com/rust-lang/rust/pull/62086, https://github.com/rust-lang/rust/pull/62735 and other PRs.
This PR is also a continuation of #65252, #69870 and other PRs linked from them, which layed the ground for converting `#[derive]` specifically.
`#[derive]` still asks `rustc_resolve` to resolve paths inside `derive(...)`, and `rustc_expand` gets those resolution results through some backdoor (which I'll try to address later), but otherwise `#[derive]` is treated as any other macro attributes, which simplifies the resolution-expansion infra pretty significantly.
The change has several observable effects on language and library.
Some of the language changes are **feature-gated** by [`feature(macro_attributes_in_derive_output)`](https://github.com/rust-lang/rust/issues/81119).
#### Library
- `derive` is now available through standard library as `{core,std}::prelude::v1::derive`.
#### Language
- `derive` now goes through name resolution, so it can now be renamed - `use derive as my_derive; #[my_derive(Debug)] struct S;`.
- `derive` now goes through name resolution, so this resolution can fail in corner cases. Crater found one such regression, where import `use foo as derive` goes into a cycle with `#[derive(Something)]`.
- **[feature-gated]** `#[derive]` is now expanded as any other attributes in left-to-right order. This allows to remove the restriction on other macro attributes following `#[derive]` (https://github.com/rust-lang/reference/issues/566). The following macro attributes become a part of the derive's input (this is not a change, non-macro attributes following `#[derive]` were treated in the same way previously).
- `#[derive]` is now expanded as any other attributes in left-to-right order. This means two derive attributes `#[derive(Foo)] #[derive(Bar)]` are now expanded separately rather than together. It doesn't generally make difference, except for esoteric cases. For example `#[derive(Foo)]` can now produce an import bringing `Bar` into scope, but previously both `Foo` and `Bar` were required to be resolved before expanding any of them.
- **[feature-gated]** `#[derive()]` (with empty list in parentheses) actually becomes useful. For historical reasons `#[derive]` *fully configures* its input, eagerly evaluating `cfg` everywhere in its target, for example on fields.
Expansion infra doesn't do that for other attributes, but now when macro attributes attributes are allowed to be written after `#[derive]`, it means that derive can *fully configure* items for them.
```rust
#[derive()]
#[my_attr]
struct S {
#[cfg(FALSE)] // this field in removed by `#[derive()]` and not observed by `#[my_attr]`
field: u8
}
```
- `#[derive]` on some non-item targets is now prohibited. This was accidentally allowed as noop in the past, but was warned about since early 2018 (#50092), despite that crater found a few such cases in unmaintained crates.
- Derive helper attributes used before their introduction are now reported with a deprecation lint. This change is long overdue (since macro modularization, https://github.com/rust-lang/rust/issues/52226#issuecomment-422605033), but it was hard to do without fixing expansion order for derives. The deprecation is tracked by #79202.
```rust
#[trait_helper] // warning: derive helper attribute is used before it is introduced
#[derive(Trait)]
struct S {}
```
Crater analysis: https://github.com/rust-lang/rust/pull/79078#issuecomment-731436821
Add test for #75158
This also shifts some type-size related tests into a new directory, so that we keep the number of files at the root down.
Closes#75158
And tuple variant syntax, but that didn't fit in the subject :)
Now the fact that these are suggestions is exposed both to the layout
engine and to IDEs and rustfix for automatic application.