aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-12-27 10:08:34 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-12-27 10:08:34 +0000
commit1d6dcef5c584d0dffdf5386eec993e41daad0210 (patch)
tree1e67675b7031115b1811863d0f186ad1f98b1fce /crates/ra_syntax/src
parent700165cf17290561dea511565278b9869ed61625 (diff)
parentbc745a139674f289386f3081458793f756cab5b9 (diff)
Merge #332
332: Struct types r=matklad a=flodiebold Infer types for struct fields, and add basic field completions. There's also some code for enums, but I focused on getting structs working. There's still ways to go before this becomes useful: There's no autoderef (or even reference types) and no inference for `self`, for example. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs70
-rw-r--r--crates/ra_syntax/src/ast/generated.rs321
-rw-r--r--crates/ra_syntax/src/grammar.ron38
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs16
4 files changed, 399 insertions, 46 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index f12479fb4..8fb6b6408 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -363,3 +363,73 @@ impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> {
363 } 363 }
364 } 364 }
365} 365}
366
367#[derive(Debug, Clone, PartialEq, Eq)]
368pub enum StructFlavor<'a> {
369 Tuple(PosFieldList<'a>),
370 Named(NamedFieldDefList<'a>),
371 Unit,
372}
373
374impl<'a> StructFlavor<'a> {
375 fn from_node<N: AstNode<'a>>(node: N) -> StructFlavor<'a> {
376 if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) {
377 StructFlavor::Named(nfdl)
378 } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) {
379 StructFlavor::Tuple(pfl)
380 } else {
381 StructFlavor::Unit
382 }
383 }
384}
385
386impl<'a> StructDef<'a> {
387 pub fn flavor(self) -> StructFlavor<'a> {
388 StructFlavor::from_node(self)
389 }
390}
391
392impl<'a> EnumVariant<'a> {
393 pub fn flavor(self) -> StructFlavor<'a> {
394 StructFlavor::from_node(self)
395 }
396}
397
398impl<'a> PointerType<'a> {
399 pub fn is_mut(&self) -> bool {
400 self.syntax().children().any(|n| n.kind() == MUT_KW)
401 }
402}
403
404impl<'a> ReferenceType<'a> {
405 pub fn is_mut(&self) -> bool {
406 self.syntax().children().any(|n| n.kind() == MUT_KW)
407 }
408}
409
410impl<'a> RefExpr<'a> {
411 pub fn is_mut(&self) -> bool {
412 self.syntax().children().any(|n| n.kind() == MUT_KW)
413 }
414}
415
416#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
417pub enum PrefixOp {
418 /// The `*` operator for dereferencing
419 Deref,
420 /// The `!` operator for logical inversion
421 Not,
422 /// The `-` operator for negation
423 Neg,
424}
425
426impl<'a> PrefixExpr<'a> {
427 pub fn op(&self) -> Option<PrefixOp> {
428 match self.syntax().first_child()?.kind() {
429 STAR => Some(PrefixOp::Deref),
430 EXCL => Some(PrefixOp::Not),
431 MINUS => Some(PrefixOp::Neg),
432 _ => None,
433 }
434 }
435}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index c73533861..c22e026cf 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -131,7 +131,15 @@ impl<R: TreeRoot<RaTypes>> ArrayTypeNode<R> {
131} 131}
132 132
133 133
134impl<'a> ArrayType<'a> {} 134impl<'a> ArrayType<'a> {
135 pub fn type_ref(self) -> Option<TypeRef<'a>> {
136 super::child_opt(self)
137 }
138
139 pub fn expr(self) -> Option<Expr<'a>> {
140 super::child_opt(self)
141 }
142}
135 143
136// Attr 144// Attr
137#[derive(Debug, Clone, Copy,)] 145#[derive(Debug, Clone, Copy,)]
@@ -806,7 +814,94 @@ impl<'a> ast::NameOwner<'a> for EnumDef<'a> {}
806impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} 814impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {}
807impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} 815impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {}
808impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {} 816impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {}
809impl<'a> EnumDef<'a> {} 817impl<'a> EnumDef<'a> {
818 pub fn variant_list(self) -> Option<EnumVariantList<'a>> {
819 super::child_opt(self)
820 }
821}
822
823// EnumVariant
824#[derive(Debug, Clone, Copy,)]
825pub struct EnumVariantNode<R: TreeRoot<RaTypes> = OwnedRoot> {
826 pub(crate) syntax: SyntaxNode<R>,
827}
828pub type EnumVariant<'a> = EnumVariantNode<RefRoot<'a>>;
829
830impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantNode<R1>> for EnumVariantNode<R2> {
831 fn eq(&self, other: &EnumVariantNode<R1>) -> bool { self.syntax == other.syntax }
832}
833impl<R: TreeRoot<RaTypes>> Eq for EnumVariantNode<R> {}
834impl<R: TreeRoot<RaTypes>> Hash for EnumVariantNode<R> {
835 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
836}
837
838impl<'a> AstNode<'a> for EnumVariant<'a> {
839 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
840 match syntax.kind() {
841 ENUM_VARIANT => Some(EnumVariant { syntax }),
842 _ => None,
843 }
844 }
845 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
846}
847
848impl<R: TreeRoot<RaTypes>> EnumVariantNode<R> {
849 pub fn borrowed(&self) -> EnumVariant {
850 EnumVariantNode { syntax: self.syntax.borrowed() }
851 }
852 pub fn owned(&self) -> EnumVariantNode {
853 EnumVariantNode { syntax: self.syntax.owned() }
854 }
855}
856
857
858impl<'a> ast::NameOwner<'a> for EnumVariant<'a> {}
859impl<'a> EnumVariant<'a> {
860 pub fn expr(self) -> Option<Expr<'a>> {
861 super::child_opt(self)
862 }
863}
864
865// EnumVariantList
866#[derive(Debug, Clone, Copy,)]
867pub struct EnumVariantListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
868 pub(crate) syntax: SyntaxNode<R>,
869}
870pub type EnumVariantList<'a> = EnumVariantListNode<RefRoot<'a>>;
871
872impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantListNode<R1>> for EnumVariantListNode<R2> {
873 fn eq(&self, other: &EnumVariantListNode<R1>) -> bool { self.syntax == other.syntax }
874}
875impl<R: TreeRoot<RaTypes>> Eq for EnumVariantListNode<R> {}
876impl<R: TreeRoot<RaTypes>> Hash for EnumVariantListNode<R> {
877 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
878}
879
880impl<'a> AstNode<'a> for EnumVariantList<'a> {
881 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
882 match syntax.kind() {
883 ENUM_VARIANT_LIST => Some(EnumVariantList { syntax }),
884 _ => None,
885 }
886 }
887 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
888}
889
890impl<R: TreeRoot<RaTypes>> EnumVariantListNode<R> {
891 pub fn borrowed(&self) -> EnumVariantList {
892 EnumVariantListNode { syntax: self.syntax.borrowed() }
893 }
894 pub fn owned(&self) -> EnumVariantListNode {
895 EnumVariantListNode { syntax: self.syntax.owned() }
896 }
897}
898
899
900impl<'a> EnumVariantList<'a> {
901 pub fn variants(self) -> impl Iterator<Item = EnumVariant<'a>> + 'a {
902 super::children(self)
903 }
904}
810 905
811// Expr 906// Expr
812#[derive(Debug, Clone, Copy, PartialEq, Eq)] 907#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -1036,7 +1131,15 @@ impl<R: TreeRoot<RaTypes>> FieldExprNode<R> {
1036} 1131}
1037 1132
1038 1133
1039impl<'a> FieldExpr<'a> {} 1134impl<'a> FieldExpr<'a> {
1135 pub fn expr(self) -> Option<Expr<'a>> {
1136 super::child_opt(self)
1137 }
1138
1139 pub fn name_ref(self) -> Option<NameRef<'a>> {
1140 super::child_opt(self)
1141 }
1142}
1040 1143
1041// FieldPatList 1144// FieldPatList
1042#[derive(Debug, Clone, Copy,)] 1145#[derive(Debug, Clone, Copy,)]
@@ -1163,7 +1266,15 @@ impl<R: TreeRoot<RaTypes>> FnPointerTypeNode<R> {
1163} 1266}
1164 1267
1165 1268
1166impl<'a> FnPointerType<'a> {} 1269impl<'a> FnPointerType<'a> {
1270 pub fn param_list(self) -> Option<ParamList<'a>> {
1271 super::child_opt(self)
1272 }
1273
1274 pub fn ret_type(self) -> Option<RetType<'a>> {
1275 super::child_opt(self)
1276 }
1277}
1167 1278
1168// ForExpr 1279// ForExpr
1169#[derive(Debug, Clone, Copy,)] 1280#[derive(Debug, Clone, Copy,)]
@@ -1246,7 +1357,11 @@ impl<R: TreeRoot<RaTypes>> ForTypeNode<R> {
1246} 1357}
1247 1358
1248 1359
1249impl<'a> ForType<'a> {} 1360impl<'a> ForType<'a> {
1361 pub fn type_ref(self) -> Option<TypeRef<'a>> {
1362 super::child_opt(self)
1363 }
1364}
1250 1365
1251// IfExpr 1366// IfExpr
1252#[derive(Debug, Clone, Copy,)] 1367#[derive(Debug, Clone, Copy,)]
@@ -1935,6 +2050,10 @@ impl<'a> MethodCallExpr<'a> {
1935 pub fn expr(self) -> Option<Expr<'a>> { 2050 pub fn expr(self) -> Option<Expr<'a>> {
1936 super::child_opt(self) 2051 super::child_opt(self)
1937 } 2052 }
2053
2054 pub fn name_ref(self) -> Option<NameRef<'a>> {
2055 super::child_opt(self)
2056 }
1938} 2057}
1939 2058
1940// Module 2059// Module
@@ -2142,7 +2261,15 @@ impl<R: TreeRoot<RaTypes>> NamedFieldNode<R> {
2142} 2261}
2143 2262
2144 2263
2145impl<'a> NamedField<'a> {} 2264impl<'a> NamedField<'a> {
2265 pub fn name_ref(self) -> Option<NameRef<'a>> {
2266 super::child_opt(self)
2267 }
2268
2269 pub fn expr(self) -> Option<Expr<'a>> {
2270 super::child_opt(self)
2271 }
2272}
2146 2273
2147// NamedFieldDef 2274// NamedFieldDef
2148#[derive(Debug, Clone, Copy,)] 2275#[derive(Debug, Clone, Copy,)]
@@ -2181,7 +2308,52 @@ impl<R: TreeRoot<RaTypes>> NamedFieldDefNode<R> {
2181 2308
2182impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} 2309impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {}
2183impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} 2310impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {}
2184impl<'a> NamedFieldDef<'a> {} 2311impl<'a> NamedFieldDef<'a> {
2312 pub fn type_ref(self) -> Option<TypeRef<'a>> {
2313 super::child_opt(self)
2314 }
2315}
2316
2317// NamedFieldDefList
2318#[derive(Debug, Clone, Copy,)]
2319pub struct NamedFieldDefListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
2320 pub(crate) syntax: SyntaxNode<R>,
2321}
2322pub type NamedFieldDefList<'a> = NamedFieldDefListNode<RefRoot<'a>>;
2323
2324impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<NamedFieldDefListNode<R1>> for NamedFieldDefListNode<R2> {
2325 fn eq(&self, other: &NamedFieldDefListNode<R1>) -> bool { self.syntax == other.syntax }
2326}
2327impl<R: TreeRoot<RaTypes>> Eq for NamedFieldDefListNode<R> {}
2328impl<R: TreeRoot<RaTypes>> Hash for NamedFieldDefListNode<R> {
2329 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
2330}
2331
2332impl<'a> AstNode<'a> for NamedFieldDefList<'a> {
2333 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2334 match syntax.kind() {
2335 NAMED_FIELD_DEF_LIST => Some(NamedFieldDefList { syntax }),
2336 _ => None,
2337 }
2338 }
2339 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2340}
2341
2342impl<R: TreeRoot<RaTypes>> NamedFieldDefListNode<R> {
2343 pub fn borrowed(&self) -> NamedFieldDefList {
2344 NamedFieldDefListNode { syntax: self.syntax.borrowed() }
2345 }
2346 pub fn owned(&self) -> NamedFieldDefListNode {
2347 NamedFieldDefListNode { syntax: self.syntax.owned() }
2348 }
2349}
2350
2351
2352impl<'a> NamedFieldDefList<'a> {
2353 pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a {
2354 super::children(self)
2355 }
2356}
2185 2357
2186// NamedFieldList 2358// NamedFieldList
2187#[derive(Debug, Clone, Copy,)] 2359#[derive(Debug, Clone, Copy,)]
@@ -2218,7 +2390,11 @@ impl<R: TreeRoot<RaTypes>> NamedFieldListNode<R> {
2218} 2390}
2219 2391
2220 2392
2221impl<'a> NamedFieldList<'a> {} 2393impl<'a> NamedFieldList<'a> {
2394 pub fn fields(self) -> impl Iterator<Item = NamedField<'a>> + 'a {
2395 super::children(self)
2396 }
2397}
2222 2398
2223// NeverType 2399// NeverType
2224#[derive(Debug, Clone, Copy,)] 2400#[derive(Debug, Clone, Copy,)]
@@ -2451,7 +2627,11 @@ impl<R: TreeRoot<RaTypes>> ParenTypeNode<R> {
2451} 2627}
2452 2628
2453 2629
2454impl<'a> ParenType<'a> {} 2630impl<'a> ParenType<'a> {
2631 pub fn type_ref(self) -> Option<TypeRef<'a>> {
2632 super::child_opt(self)
2633 }
2634}
2455 2635
2456// Pat 2636// Pat
2457#[derive(Debug, Clone, Copy, PartialEq, Eq)] 2637#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -2816,7 +2996,94 @@ impl<R: TreeRoot<RaTypes>> PointerTypeNode<R> {
2816} 2996}
2817 2997
2818 2998
2819impl<'a> PointerType<'a> {} 2999impl<'a> PointerType<'a> {
3000 pub fn type_ref(self) -> Option<TypeRef<'a>> {
3001 super::child_opt(self)
3002 }
3003}
3004
3005// PosField
3006#[derive(Debug, Clone, Copy,)]
3007pub struct PosFieldNode<R: TreeRoot<RaTypes> = OwnedRoot> {
3008 pub(crate) syntax: SyntaxNode<R>,
3009}
3010pub type PosField<'a> = PosFieldNode<RefRoot<'a>>;
3011
3012impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldNode<R1>> for PosFieldNode<R2> {
3013 fn eq(&self, other: &PosFieldNode<R1>) -> bool { self.syntax == other.syntax }
3014}
3015impl<R: TreeRoot<RaTypes>> Eq for PosFieldNode<R> {}
3016impl<R: TreeRoot<RaTypes>> Hash for PosFieldNode<R> {
3017 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
3018}
3019
3020impl<'a> AstNode<'a> for PosField<'a> {
3021 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
3022 match syntax.kind() {
3023 POS_FIELD => Some(PosField { syntax }),
3024 _ => None,
3025 }
3026 }
3027 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
3028}
3029
3030impl<R: TreeRoot<RaTypes>> PosFieldNode<R> {
3031 pub fn borrowed(&self) -> PosField {
3032 PosFieldNode { syntax: self.syntax.borrowed() }
3033 }
3034 pub fn owned(&self) -> PosFieldNode {
3035 PosFieldNode { syntax: self.syntax.owned() }
3036 }
3037}
3038
3039
3040impl<'a> ast::AttrsOwner<'a> for PosField<'a> {}
3041impl<'a> PosField<'a> {
3042 pub fn type_ref(self) -> Option<TypeRef<'a>> {
3043 super::child_opt(self)
3044 }
3045}
3046
3047// PosFieldList
3048#[derive(Debug, Clone, Copy,)]
3049pub struct PosFieldListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
3050 pub(crate) syntax: SyntaxNode<R>,
3051}
3052pub type PosFieldList<'a> = PosFieldListNode<RefRoot<'a>>;
3053
3054impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldListNode<R1>> for PosFieldListNode<R2> {
3055 fn eq(&self, other: &PosFieldListNode<R1>) -> bool { self.syntax == other.syntax }
3056}
3057impl<R: TreeRoot<RaTypes>> Eq for PosFieldListNode<R> {}
3058impl<R: TreeRoot<RaTypes>> Hash for PosFieldListNode<R> {
3059 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
3060}
3061
3062impl<'a> AstNode<'a> for PosFieldList<'a> {
3063 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
3064 match syntax.kind() {
3065 POS_FIELD_LIST => Some(PosFieldList { syntax }),
3066 _ => None,
3067 }
3068 }
3069 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
3070}
3071
3072impl<R: TreeRoot<RaTypes>> PosFieldListNode<R> {
3073 pub fn borrowed(&self) -> PosFieldList {
3074 PosFieldListNode { syntax: self.syntax.borrowed() }
3075 }
3076 pub fn owned(&self) -> PosFieldListNode {
3077 PosFieldListNode { syntax: self.syntax.owned() }
3078 }
3079}
3080
3081
3082impl<'a> PosFieldList<'a> {
3083 pub fn fields(self) -> impl Iterator<Item = PosField<'a>> + 'a {
3084 super::children(self)
3085 }
3086}
2820 3087
2821// PrefixExpr 3088// PrefixExpr
2822#[derive(Debug, Clone, Copy,)] 3089#[derive(Debug, Clone, Copy,)]
@@ -3046,7 +3313,11 @@ impl<R: TreeRoot<RaTypes>> ReferenceTypeNode<R> {
3046} 3313}
3047 3314
3048 3315
3049impl<'a> ReferenceType<'a> {} 3316impl<'a> ReferenceType<'a> {
3317 pub fn type_ref(self) -> Option<TypeRef<'a>> {
3318 super::child_opt(self)
3319 }
3320}
3050 3321
3051// RetType 3322// RetType
3052#[derive(Debug, Clone, Copy,)] 3323#[derive(Debug, Clone, Copy,)]
@@ -3239,7 +3510,11 @@ impl<R: TreeRoot<RaTypes>> SliceTypeNode<R> {
3239} 3510}
3240 3511
3241 3512
3242impl<'a> SliceType<'a> {} 3513impl<'a> SliceType<'a> {
3514 pub fn type_ref(self) -> Option<TypeRef<'a>> {
3515 super::child_opt(self)
3516 }
3517}
3243 3518
3244// SourceFile 3519// SourceFile
3245#[derive(Debug, Clone, Copy,)] 3520#[derive(Debug, Clone, Copy,)]
@@ -3426,11 +3701,7 @@ impl<'a> ast::NameOwner<'a> for StructDef<'a> {}
3426impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} 3701impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
3427impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} 3702impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
3428impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {} 3703impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {}
3429impl<'a> StructDef<'a> { 3704impl<'a> StructDef<'a> {}
3430 pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a {
3431 super::children(self)
3432 }
3433}
3434 3705
3435// StructLit 3706// StructLit
3436#[derive(Debug, Clone, Copy,)] 3707#[derive(Debug, Clone, Copy,)]
@@ -3467,7 +3738,15 @@ impl<R: TreeRoot<RaTypes>> StructLitNode<R> {
3467} 3738}
3468 3739
3469 3740
3470impl<'a> StructLit<'a> {} 3741impl<'a> StructLit<'a> {
3742 pub fn path(self) -> Option<Path<'a>> {
3743 super::child_opt(self)
3744 }
3745
3746 pub fn named_field_list(self) -> Option<NamedFieldList<'a>> {
3747 super::child_opt(self)
3748 }
3749}
3471 3750
3472// StructPat 3751// StructPat
3473#[derive(Debug, Clone, Copy,)] 3752#[derive(Debug, Clone, Copy,)]
@@ -3770,7 +4049,11 @@ impl<R: TreeRoot<RaTypes>> TupleTypeNode<R> {
3770} 4049}
3771 4050
3772 4051
3773impl<'a> TupleType<'a> {} 4052impl<'a> TupleType<'a> {
4053 pub fn fields(self) -> impl Iterator<Item = TypeRef<'a>> + 'a {
4054 super::children(self)
4055 }
4056}
3774 4057
3775// TypeDef 4058// TypeDef
3776#[derive(Debug, Clone, Copy,)] 4059#[derive(Debug, Clone, Copy,)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index e3b9032a0..4bcff4e14 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -261,18 +261,20 @@ Grammar(
261 "TypeParamsOwner", 261 "TypeParamsOwner",
262 "AttrsOwner", 262 "AttrsOwner",
263 "DocCommentsOwner" 263 "DocCommentsOwner"
264 ],
265 collections: [
266 ["fields", "NamedFieldDef"]
267 ] 264 ]
268 ), 265 ),
269 "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), 266 "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]),
267 "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"], options: ["TypeRef"] ),
268 "PosFieldList": (collections: [["fields", "PosField"]]),
269 "PosField": ( traits: ["AttrsOwner"], options: ["TypeRef"]),
270 "EnumDef": ( traits: [ 270 "EnumDef": ( traits: [
271 "NameOwner", 271 "NameOwner",
272 "TypeParamsOwner", 272 "TypeParamsOwner",
273 "AttrsOwner", 273 "AttrsOwner",
274 "DocCommentsOwner" 274 "DocCommentsOwner"
275 ] ), 275 ], options: [["variant_list", "EnumVariantList"]] ),
276 "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
277 "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ),
276 "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), 278 "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ),
277 "Module": ( 279 "Module": (
278 traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], 280 traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ],
@@ -301,17 +303,17 @@ Grammar(
301 ] ), 303 ] ),
302 "ImplItem": (), 304 "ImplItem": (),
303 305
304 "ParenType": (), 306 "ParenType": (options: ["TypeRef"]),
305 "TupleType": (), 307 "TupleType": ( collections: [["fields", "TypeRef"]] ),
306 "NeverType": (), 308 "NeverType": (),
307 "PathType": (options: ["Path"]), 309 "PathType": (options: ["Path"]),
308 "PointerType": (), 310 "PointerType": (options: ["TypeRef"]),
309 "ArrayType": (), 311 "ArrayType": ( options: ["TypeRef", "Expr"] ),
310 "SliceType": (), 312 "SliceType": ( options: ["TypeRef"] ),
311 "ReferenceType": (), 313 "ReferenceType": (options: ["TypeRef"]),
312 "PlaceholderType": (), 314 "PlaceholderType": (),
313 "FnPointerType": (), 315 "FnPointerType": (options: ["ParamList", "RetType"]),
314 "ForType": (), 316 "ForType": (options: ["TypeRef"]),
315 "ImplTraitType": (), 317 "ImplTraitType": (),
316 "DynTraitType": (), 318 "DynTraitType": (),
317 319
@@ -392,19 +394,19 @@ Grammar(
392 collections: [ [ "pats", "Pat" ] ] 394 collections: [ [ "pats", "Pat" ] ]
393 ), 395 ),
394 "MatchGuard": (), 396 "MatchGuard": (),
395 "StructLit": (), 397 "StructLit": (options: ["Path", "NamedFieldList"]),
396 "NamedFieldList": (), 398 "NamedFieldList": (collections: [ ["fields", "NamedField"] ]),
397 "NamedField": (), 399 "NamedField": (options: ["NameRef", "Expr"]),
398 "CallExpr": ( 400 "CallExpr": (
399 traits: ["ArgListOwner"], 401 traits: ["ArgListOwner"],
400 options: [ "Expr" ], 402 options: [ "Expr" ],
401 ), 403 ),
402 "MethodCallExpr": ( 404 "MethodCallExpr": (
403 traits: ["ArgListOwner"], 405 traits: ["ArgListOwner"],
404 options: [ "Expr" ], 406 options: [ "Expr", "NameRef" ],
405 ), 407 ),
406 "IndexExpr": (), 408 "IndexExpr": (),
407 "FieldExpr": (), 409 "FieldExpr": (options: ["Expr", "NameRef"]),
408 "TryExpr": (options: ["Expr"]), 410 "TryExpr": (options: ["Expr"]),
409 "CastExpr": (options: ["Expr", "TypeRef"]), 411 "CastExpr": (options: ["Expr", "TypeRef"]),
410 "RefExpr": (options: ["Expr"]), 412 "RefExpr": (options: ["Expr"]),
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs
index da78d85a2..2d1f17491 100644
--- a/crates/ra_syntax/src/grammar/expressions.rs
+++ b/crates/ra_syntax/src/grammar/expressions.rs
@@ -283,14 +283,10 @@ fn postfix_expr(
283 // } 283 // }
284 L_PAREN if allow_calls => call_expr(p, lhs), 284 L_PAREN if allow_calls => call_expr(p, lhs),
285 L_BRACK if allow_calls => index_expr(p, lhs), 285 L_BRACK if allow_calls => index_expr(p, lhs),
286 DOT if p.nth(1) == IDENT => { 286 DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => {
287 if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { 287 method_call_expr(p, lhs)
288 method_call_expr(p, lhs)
289 } else {
290 field_expr(p, lhs)
291 }
292 } 288 }
293 DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), 289 DOT => field_expr(p, lhs),
294 // test postfix_range 290 // test postfix_range
295 // fn foo() { let x = 1..; } 291 // fn foo() { let x = 1..; }
296 DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { 292 DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => {
@@ -355,13 +351,15 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
355// x.0.bar; 351// x.0.bar;
356// } 352// }
357fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 353fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
358 assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); 354 assert!(p.at(DOT));
359 let m = lhs.precede(p); 355 let m = lhs.precede(p);
360 p.bump(); 356 p.bump();
361 if p.at(IDENT) { 357 if p.at(IDENT) {
362 name_ref(p) 358 name_ref(p)
363 } else { 359 } else if p.at(INT_NUMBER) {
364 p.bump() 360 p.bump()
361 } else {
362 p.error("expected field name or number")
365 } 363 }
366 m.complete(p, FIELD_EXPR) 364 m.complete(p, FIELD_EXPR)
367} 365}