use crate::ast;
-use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
-use crate::parse::parser::{BlockMode, PathStyle, TokenType, SemiColonMode};
+use crate::ast::{
+ BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind, VariantData,
+};
+use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType};
use crate::parse::token;
use crate::parse::PResult;
use crate::parse::Parser;
use crate::print::pprust;
use crate::ptr::P;
+use crate::source_map::Spanned;
use crate::symbol::kw;
use crate::ThinVec;
use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::Span;
use log::debug;
+use syntax_pos::Span;
pub trait RecoverQPath: Sized + 'static {
const PATH_STYLE: PathStyle = PathStyle::Expr;
}
}
+ crate fn maybe_report_invalid_custom_discriminants(
+ &mut self,
+ discriminant_spans: Vec<Span>,
+ variants: &[Spanned<ast::Variant_>],
+ ) {
+ let has_fields = variants.iter().any(|variant| match variant.node.data {
+ VariantData::Tuple(..) | VariantData::Struct(..) => true,
+ VariantData::Unit(..) => false,
+ });
+
+ if !discriminant_spans.is_empty() && has_fields {
+ let mut err = self.struct_span_err(
+ discriminant_spans.clone(),
+ "custom discriminant values are not allowed in enums with fields",
+ );
+ for sp in discriminant_spans {
+ err.span_label(sp, "invalid custom discriminant");
+ }
+ for variant in variants.iter() {
+ if let VariantData::Struct(fields, ..) | VariantData::Tuple(fields, ..) =
+ &variant.node.data
+ {
+ let fields = if fields.len() > 1 {
+ "fields"
+ } else {
+ "a field"
+ };
+ err.span_label(
+ variant.span,
+ &format!("variant with {fields} defined here", fields = fields),
+ );
+
+ }
+ }
+ err.emit();
+ }
+ }
+
crate fn maybe_recover_from_bad_type_plus(
&mut self,
allow_plus: bool,
/// Parses the part of an enum declaration following the `{`.
fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
let mut variants = Vec::new();
- let mut all_nullary = true;
let mut any_disr = vec![];
while self.token != token::CloseDelim(token::Brace) {
let variant_attrs = self.parse_outer_attributes()?;
let ident = self.parse_ident()?;
if self.check(&token::OpenDelim(token::Brace)) {
// Parse a struct variant.
- all_nullary = false;
let (fields, recovered) = self.parse_record_struct_body()?;
struct_def = VariantData::Struct(fields, recovered);
} else if self.check(&token::OpenDelim(token::Paren)) {
- all_nullary = false;
struct_def = VariantData::Tuple(
self.parse_tuple_struct_body()?,
ast::DUMMY_NODE_ID,
}
}
self.expect(&token::CloseDelim(token::Brace))?;
- if !any_disr.is_empty() && !all_nullary {
- let mut err = self.struct_span_err(
- any_disr.clone(),
- "discriminator values can only be used with a field-less enum",
- );
- for sp in any_disr {
- err.span_label(sp, "only valid in field-less enums");
- }
- err.emit();
- }
+ self.maybe_report_invalid_custom_discriminants(any_disr, &variants);
Ok(ast::EnumDef { variants })
}
enum X {
A = 3,
- //~^ ERROR discriminator values can only be used with a field-less enum
+ //~^ ERROR custom discriminant values are not allowed in enums with fields
B(usize)
}
-error: discriminator values can only be used with a field-less enum
+error: custom discriminant values are not allowed in enums with fields
--> $DIR/issue-17383.rs:2:9
|
LL | A = 3,
- | ^ only valid in field-less enums
+ | ^ invalid custom discriminant
+LL |
+LL | B(usize)
+ | -------- variant with a field defined here
error: aborting due to previous error
enum Color {
Red = 0xff0000,
- //~^ ERROR discriminator values can only be used with a field-less enum
+ //~^ ERROR custom discriminant values are not allowed in enums with fields
Green = 0x00ff00,
Blue = 0x0000ff,
Black = 0x000000,
White = 0xffffff,
Other(usize),
+ Other2(usize, usize),
}
fn main() {}
-error: discriminator values can only be used with a field-less enum
+error: custom discriminant values are not allowed in enums with fields
--> $DIR/tag-variant-disr-non-nullary.rs:2:11
|
LL | Red = 0xff0000,
- | ^^^^^^^^ only valid in field-less enums
+ | ^^^^^^^^ invalid custom discriminant
LL |
LL | Green = 0x00ff00,
- | ^^^^^^^^ only valid in field-less enums
+ | ^^^^^^^^ invalid custom discriminant
LL | Blue = 0x0000ff,
- | ^^^^^^^^ only valid in field-less enums
+ | ^^^^^^^^ invalid custom discriminant
LL | Black = 0x000000,
- | ^^^^^^^^ only valid in field-less enums
+ | ^^^^^^^^ invalid custom discriminant
LL | White = 0xffffff,
- | ^^^^^^^^ only valid in field-less enums
+ | ^^^^^^^^ invalid custom discriminant
+LL | Other(usize),
+ | ------------ variant with a field defined here
+LL | Other2(usize, usize),
+ | -------------------- variant with fields defined here
error: aborting due to previous error