diff options
| author | John Wrenn <john_wrenn@brown.edu> | 2019-05-09 17:08:55 -0400 |
|---|---|---|
| committer | John Wrenn <john_wrenn@brown.edu> | 2019-06-21 11:00:10 -0400 |
| commit | ac98342e846e79985f0c4969a2d546dee24a70d1 (patch) | |
| tree | 8c2ff20debabdd8f9c9f7476f1b2d3868192f6cd /src/libsyntax/parse | |
| parent | 38cd9489f75f4a4387296ee304e2287f7c32c211 (diff) | |
| download | rust-ac98342e846e79985f0c4969a2d546dee24a70d1.tar.gz rust-ac98342e846e79985f0c4969a2d546dee24a70d1.zip | |
Implement arbitrary_enum_discriminant
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/diagnostics.rs | 48 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 31 |
2 files changed, 43 insertions, 36 deletions
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 60544cca877..07fe521edb0 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -2,7 +2,7 @@ use crate::ast::{ self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData, }; -use crate::parse::{SeqSep, PResult, Parser}; +use crate::parse::{SeqSep, PResult, Parser, ParseSess}; use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType}; use crate::parse::token::{self, TokenKind}; use crate::print::pprust; @@ -539,8 +539,7 @@ impl<'a> Parser<'a> { } crate fn maybe_report_invalid_custom_discriminants( - &mut self, - discriminant_spans: Vec<Span>, + sess: &ParseSess, variants: &[Spanned<ast::Variant_>], ) { let has_fields = variants.iter().any(|variant| match variant.node.data { @@ -548,28 +547,39 @@ impl<'a> Parser<'a> { VariantData::Unit(..) => false, }); + let discriminant_spans = variants.iter().filter(|variant| match variant.node.data { + VariantData::Tuple(..) | VariantData::Struct(..) => false, + VariantData::Unit(..) => true, + }) + .filter_map(|variant| variant.node.disr_expr.as_ref().map(|c| c.value.span)) + .collect::<Vec<_>>(); + if !discriminant_spans.is_empty() && has_fields { - let mut err = self.struct_span_err( + let mut err = crate::feature_gate::feature_err( + sess, + sym::arbitrary_enum_discriminant, discriminant_spans.clone(), - "custom discriminant values are not allowed in enums with fields", + crate::feature_gate::GateIssue::Language, + "custom discriminant values are not allowed in enums with tuple or struct variants", ); for sp in discriminant_spans { - err.span_label(sp, "invalid custom discriminant"); + err.span_label(sp, "disallowed 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), - ); - + match &variant.node.data { + VariantData::Struct(..) => { + err.span_label( + variant.span, + "struct variant defined here", + ); + } + VariantData::Tuple(..) => { + err.span_label( + variant.span, + "tuple variant defined here", + ); + } + VariantData::Unit(..) => {} } } err.emit(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fa697e06d26..2718ddded29 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6963,36 +6963,34 @@ impl<'a> Parser<'a> { /// 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 any_disr = vec![]; while self.token != token::CloseDelim(token::Brace) { let variant_attrs = self.parse_outer_attributes()?; let vlo = self.token.span; - let struct_def; - let mut disr_expr = None; self.eat_bad_pub(); let ident = self.parse_ident()?; - if self.check(&token::OpenDelim(token::Brace)) { + + let struct_def = if self.check(&token::OpenDelim(token::Brace)) { // Parse a struct variant. let (fields, recovered) = self.parse_record_struct_body()?; - struct_def = VariantData::Struct(fields, recovered); + VariantData::Struct(fields, recovered) } else if self.check(&token::OpenDelim(token::Paren)) { - struct_def = VariantData::Tuple( + VariantData::Tuple( self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID, - ); - } else if self.eat(&token::Eq) { - disr_expr = Some(AnonConst { + ) + } else { + VariantData::Unit(ast::DUMMY_NODE_ID) + }; + + let disr_expr = if self.eat(&token::Eq) { + Some(AnonConst { id: ast::DUMMY_NODE_ID, value: self.parse_expr()?, - }); - if let Some(sp) = disr_expr.as_ref().map(|c| c.value.span) { - any_disr.push(sp); - } - struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); + }) } else { - struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); - } + None + }; let vr = ast::Variant_ { ident, @@ -7020,7 +7018,6 @@ impl<'a> Parser<'a> { } } self.expect(&token::CloseDelim(token::Brace))?; - self.maybe_report_invalid_custom_discriminants(any_disr, &variants); Ok(ast::EnumDef { variants }) } |
