about summary refs log tree commit diff
path: root/src/libsyntax/parse/diagnostics.rs
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2019-05-22 16:56:51 -0400
committerAndy Russell <arussell123@gmail.com>2019-05-23 11:13:48 -0400
commit3cbf5864a6b7088eb28da30b9ccf61ba8d90054f (patch)
tree7afa8409d7057cf1b860df2ead27eb85cda61fab /src/libsyntax/parse/diagnostics.rs
parentf688ba608923bdbf6b46ec65af2f6464b6233a75 (diff)
downloadrust-3cbf5864a6b7088eb28da30b9ccf61ba8d90054f.tar.gz
rust-3cbf5864a6b7088eb28da30b9ccf61ba8d90054f.zip
tweak discriminant on non-nullary enum diagnostic
Adds notes pointing at the non-nullary variants, and uses "custom
discriminant" language to be consistent with the Reference.
Diffstat (limited to 'src/libsyntax/parse/diagnostics.rs')
-rw-r--r--src/libsyntax/parse/diagnostics.rs47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index d48fcbbd672..8ac5beb21b5 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1,16 +1,19 @@
 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;
@@ -79,6 +82,44 @@ impl<'a> Parser<'a> {
         }
     }
 
+    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,