mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Detect struct S(ty = val);
Emit a specific error for unsupported default field value syntax in tuple structs.
This commit is contained in:
parent
9ac95c10c0
commit
550bcae8aa
@ -53,6 +53,9 @@ ast_lowering_closure_cannot_be_static = closures cannot be static
|
||||
ast_lowering_coroutine_too_many_parameters =
|
||||
too many parameters for a coroutine (expected 0 or 1 parameters)
|
||||
|
||||
ast_lowering_default_field_in_tuple = default field in tuple struct
|
||||
.label = default fields are only supported on structs
|
||||
|
||||
ast_lowering_does_not_support_modifiers =
|
||||
the `{$class_name}` register class does not support template modifiers
|
||||
|
||||
|
@ -38,6 +38,14 @@ pub(crate) struct InvalidAbi {
|
||||
pub suggestion: Option<InvalidAbiSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_lowering_default_field_in_tuple)]
|
||||
pub(crate) struct TupleStructWithDefault {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub(crate) struct InvalidAbiReason(pub &'static str);
|
||||
|
||||
impl Subdiagnostic for InvalidAbiReason {
|
||||
|
@ -17,7 +17,10 @@ use smallvec::{SmallVec, smallvec};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::instrument;
|
||||
|
||||
use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
|
||||
use super::errors::{
|
||||
InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound,
|
||||
TupleStructWithDefault,
|
||||
};
|
||||
use super::{
|
||||
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
|
||||
ResolverAstLoweringExt,
|
||||
@ -690,13 +693,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
VariantData::Tuple(fields, id) => {
|
||||
let ctor_id = self.lower_node_id(*id);
|
||||
self.alias_attrs(ctor_id, parent_id);
|
||||
hir::VariantData::Tuple(
|
||||
self.arena.alloc_from_iter(
|
||||
fields.iter().enumerate().map(|f| self.lower_field_def(f)),
|
||||
),
|
||||
ctor_id,
|
||||
self.local_def_id(*id),
|
||||
)
|
||||
let fields = self
|
||||
.arena
|
||||
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
|
||||
for field in &fields[..] {
|
||||
if let Some(default) = field.default {
|
||||
// Default values in tuple struct and tuple variants are not allowed by the
|
||||
// RFC due to concerns about the syntax, both in the item definition and the
|
||||
// expression. We could in the future allow `struct S(i32 = 0);` and force
|
||||
// users to construct the value with `let _ = S { .. };`.
|
||||
if self.tcx.features().default_field_values() {
|
||||
self.dcx().emit_err(TupleStructWithDefault { span: default.span });
|
||||
} else {
|
||||
let _ = self.dcx().span_delayed_bug(
|
||||
default.span,
|
||||
"expected `default values on `struct` fields aren't supported` \
|
||||
feature-gate error but none was produced",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))
|
||||
}
|
||||
VariantData::Unit(id) => {
|
||||
let ctor_id = self.lower_node_id(*id);
|
||||
|
@ -1836,6 +1836,22 @@ impl<'a> Parser<'a> {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let mut default = None;
|
||||
if p.token == token::Eq {
|
||||
let mut snapshot = p.create_snapshot_for_diagnostic();
|
||||
snapshot.bump();
|
||||
match snapshot.parse_expr_anon_const() {
|
||||
Ok(const_expr) => {
|
||||
let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
|
||||
p.psess.gated_spans.gate(sym::default_field_values, sp);
|
||||
p.restore_snapshot(snapshot);
|
||||
default = Some(const_expr);
|
||||
}
|
||||
Err(err) => {
|
||||
err.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((
|
||||
FieldDef {
|
||||
@ -1845,7 +1861,7 @@ impl<'a> Parser<'a> {
|
||||
ident: None,
|
||||
id: DUMMY_NODE_ID,
|
||||
ty,
|
||||
default: None,
|
||||
default,
|
||||
attrs,
|
||||
is_placeholder: false,
|
||||
},
|
||||
|
@ -23,6 +23,8 @@ pub struct Qux<const C: i32> {
|
||||
bay: i32 = C,
|
||||
}
|
||||
|
||||
pub struct Rak(i32 = 42); //~ ERROR default field in tuple struct
|
||||
|
||||
impl<const C: i32> Qux<C> {
|
||||
const S: S = S;
|
||||
}
|
||||
|
@ -7,6 +7,12 @@ LL | bat: i32 = <Qux<{ C }> as T>::K,
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `C`
|
||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: default field in tuple struct
|
||||
--> $DIR/default-field-values-failures.rs:26:22
|
||||
|
|
||||
LL | pub struct Rak(i32 = 42);
|
||||
| ^^ default fields are only supported on structs
|
||||
|
||||
error[E0277]: the trait bound `S: Default` is not satisfied
|
||||
--> $DIR/default-field-values-failures.rs:14:5
|
||||
|
|
||||
@ -24,7 +30,7 @@ LL | pub struct S;
|
||||
|
|
||||
|
||||
error: missing mandatory field `bar`
|
||||
--> $DIR/default-field-values-failures.rs:45:21
|
||||
--> $DIR/default-field-values-failures.rs:47:21
|
||||
|
|
||||
LL | let _ = Bar { .. };
|
||||
| ^
|
||||
@ -35,6 +41,6 @@ error: generic `Self` types are currently not permitted in anonymous constants
|
||||
LL | bar: S = Self::S,
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user