Introduce default_field_values
feature
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.
This commit is contained in:
parent
f6cb952dc1
commit
9ac95c10c0
70 changed files with 1469 additions and 392 deletions
|
@ -1021,12 +1021,12 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_variant(
|
||||
tcx: TyCtxt<'_>,
|
||||
fn lower_variant<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
variant_did: Option<LocalDefId>,
|
||||
ident: Ident,
|
||||
discr: ty::VariantDiscr,
|
||||
def: &hir::VariantData<'_>,
|
||||
def: &hir::VariantData<'tcx>,
|
||||
adt_kind: ty::AdtKind,
|
||||
parent_did: LocalDefId,
|
||||
) -> ty::VariantDef {
|
||||
|
@ -1042,6 +1042,7 @@ fn lower_variant(
|
|||
name: f.ident.name,
|
||||
vis: tcx.visibility(f.def_id),
|
||||
safety: f.safety,
|
||||
value: f.default.map(|v| v.def_id.to_def_id()),
|
||||
})
|
||||
.collect();
|
||||
let recovered = match def {
|
||||
|
|
|
@ -125,6 +125,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
|||
return ty;
|
||||
}
|
||||
|
||||
Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
|
||||
if c.hir_id == hir_id =>
|
||||
{
|
||||
tcx.type_of(field_def_id).instantiate_identity()
|
||||
}
|
||||
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
span,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue