diff --git a/src/grammar.ron b/src/grammar.ron index fca29f1efe..e10e5aaf46 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -158,6 +158,7 @@ Grammar( "TYPE_ARG_LIST", "PARAM_LIST", + "SELF_PARAM", "ARG_LIST", ] ) diff --git a/src/parser/grammar/items/traits.rs b/src/parser/grammar/items/traits.rs index 812cacfb7e..7d657ced03 100644 --- a/src/parser/grammar/items/traits.rs +++ b/src/parser/grammar/items/traits.rs @@ -29,6 +29,17 @@ pub(super) fn impl_item(p: &mut Parser) { } type_params::where_clause(p); p.expect(L_CURLY); + + // test impl_item_items + // impl F { + // type A = i32; + // const B: i32 = 92; + // fn foo() {} + // fn bar(&self) {} + // } + while !p.at(EOF) && !p.at(R_CURLY) { + item(p); + } p.expect(R_CURLY); } diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index 498b45d443..b8847fb68b 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs @@ -104,6 +104,7 @@ fn fn_value_parameters(p: &mut Parser) { assert!(p.at(L_PAREN)); let m = p.start(); p.bump(); + self_param(p); while !p.at(EOF) && !p.at(R_PAREN) { value_parameter(p); if !p.at(R_PAREN) { @@ -120,6 +121,29 @@ fn fn_value_parameters(p: &mut Parser) { types::type_(p); m.complete(p, VALUE_PARAMETER); } + + // test self_param + // impl S { + // fn a(self) {} + // fn b(&self,) {} + // fn c(&mut self, x: i32) {} + // } + fn self_param(p: &mut Parser) { + let la1 = p.nth(1); + let la2 = p.nth(2); + let n_toks = match (p.current(), la1, la2) { + (SELF_KW, _, _) => 1, + (AMPERSAND, SELF_KW, _) => 2, + (AMPERSAND, MUT_KW, SELF_KW) => 3, + _ => return, + }; + let m = p.start(); + for _ in 0..n_toks { p.bump(); } + m.complete(p, SELF_PARAM); + if !p.at(R_PAREN) { + p.expect(COMMA); + } + } } fn fn_ret_type(p: &mut Parser) { diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 699f5282e7..0603f53fdc 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -145,6 +145,7 @@ pub enum SyntaxKind { TYPE_PARAM_LIST, TYPE_ARG_LIST, PARAM_LIST, + SELF_PARAM, ARG_LIST, // Technical SyntaxKinds: they appear temporally during parsing, // but never end up in the final tree @@ -298,6 +299,7 @@ impl SyntaxKind { TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" }, PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" }, + SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, EOF => &SyntaxInfo { name: "EOF" }, diff --git a/tests/data/parser/inline/0054_impl_item_items.rs b/tests/data/parser/inline/0054_impl_item_items.rs new file mode 100644 index 0000000000..f108514879 --- /dev/null +++ b/tests/data/parser/inline/0054_impl_item_items.rs @@ -0,0 +1,6 @@ +impl F { + type A = i32; + const B: i32 = 92; + fn foo() {} + fn bar(&self) {} +} diff --git a/tests/data/parser/inline/0054_impl_item_items.txt b/tests/data/parser/inline/0054_impl_item_items.txt new file mode 100644 index 0000000000..739f3d0f9b --- /dev/null +++ b/tests/data/parser/inline/0054_impl_item_items.txt @@ -0,0 +1,77 @@ +FILE@[0; 89) + IMPL_ITEM@[0; 89) + IMPL_KW@[0; 4) + PATH_TYPE@[4; 7) + PATH@[4; 7) + PATH_SEGMENT@[4; 7) + NAME_REF@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "F" + WHITESPACE@[6; 7) + L_CURLY@[7; 8) + TYPE_ITEM@[8; 31) + WHITESPACE@[8; 13) + TYPE_KW@[13; 17) + NAME@[17; 20) + WHITESPACE@[17; 18) + IDENT@[18; 19) "A" + WHITESPACE@[19; 20) + EQ@[20; 21) + PATH_TYPE@[21; 25) + PATH@[21; 25) + PATH_SEGMENT@[21; 25) + NAME_REF@[21; 25) + WHITESPACE@[21; 22) + IDENT@[22; 25) "i32" + SEMI@[25; 26) + WHITESPACE@[26; 31) + CONST_ITEM@[31; 54) + CONST_KW@[31; 36) + NAME@[36; 38) + WHITESPACE@[36; 37) + IDENT@[37; 38) "B" + COLON@[38; 39) + PATH_TYPE@[39; 44) + PATH@[39; 44) + PATH_SEGMENT@[39; 44) + NAME_REF@[39; 44) + WHITESPACE@[39; 40) + IDENT@[40; 43) "i32" + WHITESPACE@[43; 44) + EQ@[44; 45) + LITERAL@[45; 48) + WHITESPACE@[45; 46) + INT_NUMBER@[46; 48) + SEMI@[48; 49) + WHITESPACE@[49; 54) + FN_ITEM@[54; 70) + FN_KW@[54; 56) + NAME@[56; 60) + WHITESPACE@[56; 57) + IDENT@[57; 60) "foo" + PARAM_LIST@[60; 63) + L_PAREN@[60; 61) + R_PAREN@[61; 62) + WHITESPACE@[62; 63) + BLOCK@[63; 70) + L_CURLY@[63; 64) + R_CURLY@[64; 65) + WHITESPACE@[65; 70) + FN_ITEM@[70; 87) + FN_KW@[70; 72) + NAME@[72; 76) + WHITESPACE@[72; 73) + IDENT@[73; 76) "bar" + PARAM_LIST@[76; 84) + L_PAREN@[76; 77) + SELF_PARAM@[77; 82) + AMPERSAND@[77; 78) + SELF_KW@[78; 82) + R_PAREN@[82; 83) + WHITESPACE@[83; 84) + BLOCK@[84; 87) + L_CURLY@[84; 85) + R_CURLY@[85; 86) + WHITESPACE@[86; 87) + R_CURLY@[87; 88) + WHITESPACE@[88; 89) diff --git a/tests/data/parser/inline/0055_self_param.rs b/tests/data/parser/inline/0055_self_param.rs new file mode 100644 index 0000000000..2890c27e2f --- /dev/null +++ b/tests/data/parser/inline/0055_self_param.rs @@ -0,0 +1,5 @@ +impl S { + fn a(self) {} + fn b(&self,) {} + fn c(&mut self, x: i32) {} +}