Try to point of macro expansion from resolver and method errors if it involves macro var
In the case that a macro caller passes an identifier into a macro generating a path or method expression, point out that identifier in the context of the *macro* so it's a bit more clear how the macro is involved in causing the error.
r? ``````````@estebank`````````` or reassign
Allow struct field default values to reference struct's generics
Right now, the default field value feature (https://github.com/rust-lang/rust/issues/132162) lowers anon consts whose types may reference ADT params that the const doesn't inherit.
This PR fixes this, so that these defaults can reference ADTs' generics, and sets the `generics_of` parenting up correctly.
There doesn't seem to be a good reason not to support this, since the anon const has a well-defined type from the field, and the anon const doesn't interact with the type system like generic parameter defaults do.
r? `````@boxyuwu````` or reassign
I could also make this into an error if this seems problematic (https://github.com/rust-lang/rust/compare/master...compiler-errors:rust:default-field-value-implicit-param?expand=1)...... but I'd rather make this work and register an open question on the tracking issue about validating that this is well-vetted.
Fixes#137896
Previously, we included a redundant prefix on the panic message and a postfix of the location of the panic. The prefix didn't carry any additional information beyond "something failed", and the location of the panic is redundant with the diagnostic's span, which gets printed out even if its code is not shown.
```
error[E0080]: evaluation of constant value failed
--> $DIR/assert-type-intrinsics.rs:11:9
|
LL | MaybeUninit::<!>::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to instantiate uninhabited type `!`
```
```
error[E0080]: evaluation of `Fail::<i32>::C` failed
--> $DIR/collect-in-dead-closure.rs:9:19
|
LL | const C: () = panic!();
| ^^^^^^^^ evaluation panicked: explicit panic
|
= note: this error originates in the macro
`$crate::panic::panic_2015` which comes from the expansion of the macro
`panic` (in Nightly builds, run with -Z macro-backtrace for more info)
```
```
error[E0080]: evaluation of constant value failed
--> $DIR/uninhabited.rs:41:9
|
LL | assert!(false);
| ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false
|
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
```
---
When the primary span for a const error is the same as the first frame in the const error report, skip it.
```
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^ evaluation panicked: explicit panic
|
note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>`
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | panic!()
| ^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
```
instead of
```
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | panic!()
| ^^^^^^^^ explicit panic
|
note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>`
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | panic!()
| ^^^^^^^^
note: inside `_CONST`
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
```
---
Revert order of constant evaluation errors
Point at the code the user wrote first and std functions last.
```
error[E0080]: evaluation of constant value failed
--> $DIR/const-errs-dont-conflict-103369.rs:5:25
|
LL | impl ConstGenericTrait<{my_fn(1)}> for () {}
| ^^^^^^^^ evaluation panicked: Some error occurred
|
note: called from `my_fn`
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
```
instead of
```
error[E0080]: evaluation of constant value failed
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some error occurred
|
note: called from `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}`
--> $DIR/const-errs-dont-conflict-103369.rs:5:25
|
LL | impl ConstGenericTrait<{my_fn(1)}> for () {}
| ^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Do not ICE on default_field_value const with lifetimes
`#![feature(default_field_values)]` uses a `const` body that should be treated as inline `const`s, but is actually being detected otherwise. This is similar to the situation in #78174, so we take the same solution: we check if the const actually comes from a field, and if it does, we use that logic to get the appropriate lifetimes and not ICE during borrowck.
Fix#135649.
```
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
--> $DIR/attempted-access-non-fatal.rs:7:15
|
LL | let _ = 2.l;
| ^
|
help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
|
LL - let _ = 2.l;
LL + let _ = 2.0f64;
|
```
- `check-pass` test for a MRE of #135020
- fail test for #135138
- switch to `TooGeneric` for checking CMSE fn signatures
- switch to `TooGeneric` for compute `SizeSkeleton` (for transmute)
- fix broken tests
When a struct definition has default field values, and the use struct ctor has missing field, if all those missing fields have defaults suggest `..`:
```
error[E0063]: missing fields `field1` and `field2` in initializer of `S`
--> $DIR/non-exhaustive-ctor.rs:16:13
|
LL | let _ = S { field: () };
| ^ missing `field1` and `field2`
|
help: all remaining fields have defaults, use `..`
|
LL | let _ = S { field: (), .. };
| ++++
```
Emit single privacy error for struct literal with multiple private fields and add test for `default_field_values` privacy
Add test ensuring that struct with default field values is not constructable if the fields are not accessible.
Collect all unreachable fields in a single struct literal struct and emit a single error, instead of one error per private field.
```
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
--> $DIR/visibility.rs:18:13
|
LL | let _x = Alpha {
| ----- in this type
LL | beta: 0,
| ^^^^^^^ private field
LL | ..
| ^^ field `gamma` is private
```
```
error: `A` has no fields, `..` needs at least one default field in the struct definition
--> $DIR/empty-struct.rs:16:17
|
LL | let _ = A { .. };
| - ^^
| |
| this type has no fields
```
Collect all unreachable fields in a single struct literal struct and emit a single error, instead of one error per private field.
```
error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private
--> $DIR/visibility.rs:18:13
|
LL | let _x = Alpha {
| ----- in this type
LL | beta: 0,
| ^^^^^^^ private field
LL | ..
| ^^ field `gamma` is private
```
```
error[E0451]: field `x` of struct `S` is private
--> $DIR/visibility.rs:24:9
|
LL | let a = baz::S {
| ------ in this type
LL | ..
| ^^ field `x` is private
```
```
error[E0451]: field `beta` of struct `Alpha` is private
--> $DIR/visibility.rs:11:37
|
LL | let x = crate::foo::Alpha { .. };
| ^^ field `beta` is private
```
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:28:1
|
LL | / impl Default for B {
LL | | fn default() -> Self {
LL | | B {
LL | | x: s(),
| | --- this field has a default value
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
help: to avoid divergence in behavior between `Struct { .. }` and `<Struct as Default>::default()`, derive the `Default`
|
LL ~ #[derive(Default)] struct B {
|
```
Note that above the structured suggestion also includes completely removing the manual `impl`, but the rendering doesn't.
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Add a test case for using the result of a fn call of an associated
function of a `const` trait in a struct default field.
```rust
struct X;
trait Trait {
fn value() -> Self;
}
impl const Trait for X {
fn value() -> Self { X }
}
struct S<T: const Trait> {
a: T = T::value(),
}
```
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
Support default fields in enum struct variant
Allow default values in an enum struct variant definition:
```rust
pub enum Bar {
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Allow using `..` without a base on an enum struct variant
```rust
Bar::Foo { .. }
```
`#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants.
Support `#[derive(Default)]` on enum struct variants with all defaulted fields
```rust
pub enum Bar {
#[default]
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Check for missing fields in typeck instead of mir_build.
Expand test with `const` param case (needs `generic_const_exprs` enabled).
Properly instantiate MIR const
The following works:
```rust
struct S<A> {
a: Vec<A> = Vec::new(),
}
S::<i32> { .. }
```
Add lint for default fields that will always fail const-eval
We *allow* this to happen for API writers that might want to rely on users'
getting a compile error when using the default field, different to the error
that they would get when the field isn't default. We could change this to
*always* error instead of being a lint, if we wanted.
This will *not* catch errors for partially evaluated consts, like when the
expression relies on a const parameter.
Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`:
- Suggest adding a base expression if there are missing fields.
- Suggest enabling the feature if all the missing fields have optional values.
- Suggest removing `..` if there are no missing fields.
Rustc of course already WF-checked the field types at the definition
site, but for error tainting of consts to work properly, there needs to
be an error emitted at the use site. Previously, with no use-site error,
we proceeded with CTFE and ran into ICEs since we are running code with
type errors.
Emitting use-site errors also brings struct-like constructors more in
line with fn-like constructors since they already emit use-site errors
for WF issues.
Note that the test output is currently *incorrect*. We should be
emitting an error at the use site too, not just at the definition. This
is partly for UI reasons, but mainly to fix a related ICE where a const
generic body is not tainted with an error since no usage error is
reported.
Go over all structured parser suggestions and make them verbose style.
When suggesting to add or remove delimiters, turn them into multiple suggestion parts.
Suggest field typo through derefs
Take into account implicit dereferences when suggesting fields.
```
error[E0609]: no field `longname` on type `Arc<S>`
--> $DIR/suggest-field-through-deref.rs:10:15
|
LL | let _ = x.longname;
| ^^^^^^^^ help: a field with a similar name exists: `long_name`
```
CC https://github.com/rust-lang/rust/issues/78374#issuecomment-719564114