-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce default_field_values
feature
#129514
Conversation
This comment has been minimized.
This comment has been minimized.
It just occurred to me to try how the following fails, and it Just Works™️ 😄: pub struct Foo {
pub baz: i32 = Self::X,
}
impl Foo {
const X: i32 = 1;
} |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a first pass. I don't have anything substantial to say, that's a great pr.
Just an avalanche of nits. An additional one: could you prefer matching on Rest
now there are >2 cases?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
// We use `Default::default()`. | ||
None => default_call(cx, field.span), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given this, I filed rust-lang/rfcs#3683 as this bit is independent of the default values RFC.
This comment has been minimized.
This comment has been minimized.
This comment was marked as resolved.
This comment was marked as resolved.
0f49c94
to
3a64e38
Compare
This comment has been minimized.
This comment has been minimized.
d59696d
to
27549fb
Compare
This comment was marked as outdated.
This comment was marked as outdated.
27549fb
to
e9c76a3
Compare
This comment was marked as outdated.
This comment was marked as outdated.
@@ -1104,6 +1104,23 @@ fn check_type_defn<'tcx>( | |||
for variant in variants.iter() { | |||
// All field types must be well-formed. | |||
for field in &variant.fields { | |||
if let Some(def_id) = field.value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the record, erroring eagerly even if we don't instantiate the default is consistent with how defaults in struct const generics works:
struct Foo<const N: u8 = {130 + 130}> {}
which errors with:
error[E0080]: evaluation of constant value failed
--> src/lib.rs:1:27
|
1 | struct Foo<const N: u8 = {130 + 130}> {}
| ^^^^^^^^^ attempt to compute `130_u8 + 130_u8`, which would overflow
For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (lib) due to 1 previous error
Not totally certain why the RFC specified that it would only be linted against, but this seems to me to be the correct behavior.
Please address nits and then please clean up the history a bit (that Then r=me |
Initial implementation of `#[feature(default_field_values]`, proposed in rust-lang/rfcs#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.
Emit a specific error for unsupported default field value syntax in tuple structs.
People might extrapolate from `Struct { .. }` that `Struct(..)` would work, but it doesn't.
…errors Emit E0080 always on struct definition with default fields that have unconditional const errors and remove `default_field_always_invalid_const` lint.
e37271d
to
fa331f4
Compare
@bors r+ rollup=never |
@bors p=10 bitrotty |
☀️ Test successful - checks-actions |
Finished benchmarking commit (974ccc1): comparison URL. Overall result: ❌✅ regressions and improvements - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -0.0%, secondary 2.4%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary 2.2%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 0.1%, secondary 0.0%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 767.262s -> 767.421s (0.02%) |
@estebank @compiler-errors I'm not sure how, but this change broken rustfmt macro formatting. rust-lang/rustfmt#6424 was recently reported and I bisected the change in behavior back to this PR. |
I'll look into it. Probably has to do with changes to the compiler representation of that default value. |
…ue-fmt, r=ytmimi Make sure we don't lose default struct value when formatting struct The reason why rust-lang/rustfmt#6424 broke when rust-lang#129514 landed is because the parser now *successfully* parses default struct values. That means that where we used to fail in `rewrite_macro_inner`: https://github.com/rust-lang/rust/blob/e108481f74ff123ad98a63bd107a18d13035b275/src/tools/rustfmt/src/macros.rs#L263-L267 ... we now succeed, and we now proceed to format the inner struct as a macro arg. Since formatting was never implemented for default struct values, this means that we’ll always rewrite the struct to exclude the default value. This PR makes it so that we simply don’t rewrite struct fields if they have a default value. r? `@ytmimi`
Rollup merge of rust-lang#134668 - compiler-errors:default-struct-value-fmt, r=ytmimi Make sure we don't lose default struct value when formatting struct The reason why rust-lang/rustfmt#6424 broke when rust-lang#129514 landed is because the parser now *successfully* parses default struct values. That means that where we used to fail in `rewrite_macro_inner`: https://github.com/rust-lang/rust/blob/e108481f74ff123ad98a63bd107a18d13035b275/src/tools/rustfmt/src/macros.rs#L263-L267 ... we now succeed, and we now proceed to format the inner struct as a macro arg. Since formatting was never implemented for default struct values, this means that we’ll always rewrite the struct to exclude the default value. This PR makes it so that we simply don’t rewrite struct fields if they have a default value. r? `@ytmimi`
Initial implementation of
#[feature(default_field_values]
, proposed in rust-lang/rfcs#3681.We now parse const expressions after a
=
in a field definition, to specify astruct
field default value.We now allow
Struct { field, .. }
where there's no base after..
.#[derive(Default)]
now uses the default value if present, continuing to useDefault::default()
if not.