Introduce dedicated AST node for union
Although structs and unions have the same syntax and differ only in the keyword, re-using the single syntax node for both of them leads to confusion in practice, and propagates further down the hir in an upleasent way. Moreover, static and consts also share syntax, but we use different nodes for them.
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
mod consts;
|
||||
mod nominal;
|
||||
mod adt;
|
||||
mod traits;
|
||||
mod use_item;
|
||||
|
||||
pub(crate) use self::{
|
||||
expressions::{match_arm_list, record_field_list},
|
||||
nominal::{enum_variant_list, record_field_def_list},
|
||||
adt::{enum_variant_list, record_field_def_list},
|
||||
traits::{impl_item_list, trait_item_list},
|
||||
use_item::use_tree_list,
|
||||
};
|
||||
@@ -247,7 +247,7 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
|
||||
// a: i32,
|
||||
// b: f32,
|
||||
// }
|
||||
nominal::struct_def(p, m, T![struct]);
|
||||
adt::struct_def(p, m);
|
||||
}
|
||||
IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => {
|
||||
// test union_items
|
||||
@@ -256,9 +256,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
|
||||
// a: i32,
|
||||
// b: f32,
|
||||
// }
|
||||
nominal::struct_def(p, m, T![union]);
|
||||
adt::union_def(p, m);
|
||||
}
|
||||
T![enum] => nominal::enum_def(p, m),
|
||||
T![enum] => adt::enum_def(p, m),
|
||||
T![use] => use_item::use_item(p, m),
|
||||
T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m),
|
||||
T![static] => consts::static_def(p, m),
|
||||
|
||||
@@ -2,10 +2,19 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
|
||||
assert!(p.at(T![struct]) || p.at_contextual_kw("union"));
|
||||
p.bump_remap(kind);
|
||||
pub(super) fn struct_def(p: &mut Parser, m: Marker) {
|
||||
assert!(p.at(T![struct]));
|
||||
p.bump(T![struct]);
|
||||
struct_or_union(p, m, T![struct], STRUCT_DEF);
|
||||
}
|
||||
|
||||
pub(super) fn union_def(p: &mut Parser, m: Marker) {
|
||||
assert!(p.at_contextual_kw("union"));
|
||||
p.bump_remap(T![union]);
|
||||
struct_or_union(p, m, T![union], UNION_DEF);
|
||||
}
|
||||
|
||||
fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
|
||||
name_r(p, ITEM_RECOVERY_SET);
|
||||
type_params::opt_type_param_list(p);
|
||||
match p.current() {
|
||||
@@ -22,11 +31,11 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
|
||||
}
|
||||
}
|
||||
}
|
||||
T![;] if kind == T![struct] => {
|
||||
T![;] if kw == T![struct] => {
|
||||
p.bump(T![;]);
|
||||
}
|
||||
T!['{'] => record_field_def_list(p),
|
||||
T!['('] if kind == T![struct] => {
|
||||
T!['('] if kw == T![struct] => {
|
||||
tuple_field_def_list(p);
|
||||
// test tuple_struct_where
|
||||
// struct Test<T>(T) where T: Clone;
|
||||
@@ -34,14 +43,14 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
|
||||
type_params::opt_where_clause(p);
|
||||
p.expect(T![;]);
|
||||
}
|
||||
_ if kind == T![struct] => {
|
||||
_ if kw == T![struct] => {
|
||||
p.error("expected `;`, `{`, or `(`");
|
||||
}
|
||||
_ => {
|
||||
p.error("expected `{`");
|
||||
}
|
||||
}
|
||||
m.complete(p, STRUCT_DEF);
|
||||
m.complete(p, def);
|
||||
}
|
||||
|
||||
pub(super) fn enum_def(p: &mut Parser, m: Marker) {
|
||||
@@ -122,6 +122,7 @@ pub enum SyntaxKind {
|
||||
R_DOLLAR,
|
||||
SOURCE_FILE,
|
||||
STRUCT_DEF,
|
||||
UNION_DEF,
|
||||
ENUM_DEF,
|
||||
FN_DEF,
|
||||
RET_TYPE,
|
||||
|
||||
Reference in New Issue
Block a user