diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 33 |
3 files changed, 43 insertions, 1 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fcb99444957..4394fb0e143 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1886,7 +1886,7 @@ pub enum ItemKind { /// A union definition (`union` or `pub union`). /// /// E.g. `union Foo<A, B> { x: A, y: B }` - Union(VariantData, Generics), // FIXME: not yet implemented + Union(VariantData, Generics), /// A Trait declaration (`trait` or `pub trait`). /// /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }` diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 683d5277359..287d33cc3e5 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -292,6 +292,9 @@ declare_features! ( // Macros 1.1 (active, rustc_macro, "1.13.0", Some(35900)), + + // Allows untagged unions `union U { ... }` + (active, untagged_unions, "1.13.0", Some(32836)), ); declare_features! ( @@ -953,6 +956,12 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { } } + ast::ItemKind::Union(..) => { + gate_feature_post!(&self, untagged_unions, + i.span, + "unions are unstable and possibly buggy"); + } + ast::ItemKind::DefaultImpl(..) => { gate_feature_post!(&self, optin_builtin_traits, i.span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 92ec0fdb3de..ec9dc1bae5a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5102,6 +5102,25 @@ impl<'a> Parser<'a> { Ok((class_name, ItemKind::Struct(vdata, generics), None)) } + /// Parse union Foo { ... } + fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> { + let class_name = self.parse_ident()?; + let mut generics = self.parse_generics()?; + + let vdata = if self.token.is_keyword(keywords::Where) { + generics.where_clause = self.parse_where_clause()?; + VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + } else if self.token == token::OpenDelim(token::Brace) { + VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) + } else { + let token_str = self.this_token_to_string(); + return Err(self.fatal(&format!("expected `where` or `{{` after union \ + name, found `{}`", token_str))) + }; + + Ok((class_name, ItemKind::Union(vdata, generics), None)) + } + pub fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> { let mut fields = Vec::new(); if self.eat(&token::OpenDelim(token::Brace)) { @@ -5938,6 +5957,20 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } + if self.check_keyword(keywords::Union) && + self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) { + // UNION ITEM + self.bump(); + let (ident, item_, extra_attrs) = self.parse_item_union()?; + let last_span = self.last_span; + let item = self.mk_item(lo, + last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return Ok(Some(item)); + } self.parse_macro_use_or_failure(attrs,macros_allowed,attributes_allowed,lo,visibility) } |
