From 022a0f061e887bd27f54c028f9a23018b8eb2b8b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 17 Mar 2021 18:20:32 +0100 Subject: [PATCH] Correctly parse attributes on fn parameters --- crates/parser/src/grammar/params.rs | 29 +++++-- .../inline/ok/0139_param_outer_arg.rast | 20 ++--- .../parser/ok/0051_parameter_attrs.rast | 78 +++++++++---------- 3 files changed, 71 insertions(+), 56 deletions(-) diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs index e313f6fb7f1..9e2f02d4356 100644 --- a/crates/parser/src/grammar/params.rs +++ b/crates/parser/src/grammar/params.rs @@ -41,22 +41,32 @@ fn list_(p: &mut Parser, flavor: Flavor) { FnDef | FnTrait | FnPointer => (T!['('], T![')']), }; - let m = p.start(); + let list_marker = p.start(); p.bump(bra); + let mut param_marker = None; if let FnDef = flavor { // test self_param_outer_attr // fn f(#[must_use] self) {} let m = p.start(); attributes::outer_attrs(p); - opt_self_param(p, m); + match opt_self_param(p, m) { + Ok(()) => {} + Err(m) => param_marker = Some(m), + } } while !p.at(EOF) && !p.at(ket) { // test param_outer_arg // fn f(#[attr1] pat: Type) {} - let m = p.start(); - attributes::outer_attrs(p); + let m = match param_marker.take() { + Some(m) => m, + None => { + let m = p.start(); + attributes::outer_attrs(p); + m + } + }; if !p.at_ts(PARAM_FIRST) { p.error("expected value parameter"); @@ -72,8 +82,12 @@ fn list_(p: &mut Parser, flavor: Flavor) { } } + if let Some(m) = param_marker { + m.abandon(p); + } + p.expect(ket); - m.complete(p, PARAM_LIST); + list_marker.complete(p, PARAM_LIST); } const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); @@ -153,7 +167,7 @@ fn variadic_param(p: &mut Parser) -> bool { // fn d(&'a mut self, x: i32) {} // fn e(mut self) {} // } -fn opt_self_param(p: &mut Parser, m: Marker) { +fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> { if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] { p.eat(T![mut]); self_as_name(p); @@ -176,7 +190,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) { | (T![&], LIFETIME_IDENT, T![self], _) | (T![&], LIFETIME_IDENT, T![mut], T![self]) ) { - return m.abandon(p); + return Err(m); } p.bump(T![&]); if p.at(LIFETIME_IDENT) { @@ -189,6 +203,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) { if !p.at(T![')']) { p.expect(T![,]); } + Ok(()) } fn self_as_name(p: &mut Parser) { diff --git a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast index 495e4c51b58..a84088bf30d 100644 --- a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast +++ b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast @@ -6,16 +6,16 @@ SOURCE_FILE@0..28 IDENT@3..4 "f" PARAM_LIST@4..24 L_PAREN@4..5 "(" - ATTR@5..13 - POUND@5..6 "#" - L_BRACK@6..7 "[" - PATH@7..12 - PATH_SEGMENT@7..12 - NAME_REF@7..12 - IDENT@7..12 "attr1" - R_BRACK@12..13 "]" - WHITESPACE@13..14 " " - PARAM@14..23 + PARAM@5..23 + ATTR@5..13 + POUND@5..6 "#" + L_BRACK@6..7 "[" + PATH@7..12 + PATH_SEGMENT@7..12 + NAME_REF@7..12 + IDENT@7..12 "attr1" + R_BRACK@12..13 "]" + WHITESPACE@13..14 " " IDENT_PAT@14..17 NAME@14..17 IDENT@14..17 "pat" diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast index e10521d8532..88470c41c04 100644 --- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast +++ b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast @@ -6,25 +6,25 @@ SOURCE_FILE@0..519 IDENT@3..5 "g1" PARAM_LIST@5..34 L_PAREN@5..6 "(" - ATTR@6..14 - POUND@6..7 "#" - L_BRACK@7..8 "[" - PATH@8..13 - PATH_SEGMENT@8..13 - NAME_REF@8..13 - IDENT@8..13 "attr1" - R_BRACK@13..14 "]" - WHITESPACE@14..15 " " - ATTR@15..23 - POUND@15..16 "#" - L_BRACK@16..17 "[" - PATH@17..22 - PATH_SEGMENT@17..22 - NAME_REF@17..22 - IDENT@17..22 "attr2" - R_BRACK@22..23 "]" - WHITESPACE@23..24 " " - PARAM@24..33 + PARAM@6..33 + ATTR@6..14 + POUND@6..7 "#" + L_BRACK@7..8 "[" + PATH@8..13 + PATH_SEGMENT@8..13 + NAME_REF@8..13 + IDENT@8..13 "attr1" + R_BRACK@13..14 "]" + WHITESPACE@14..15 " " + ATTR@15..23 + POUND@15..16 "#" + L_BRACK@16..17 "[" + PATH@17..22 + PATH_SEGMENT@17..22 + NAME_REF@17..22 + IDENT@17..22 "attr2" + R_BRACK@22..23 "]" + WHITESPACE@23..24 " " IDENT_PAT@24..27 NAME@24..27 IDENT@24..27 "pat" @@ -48,16 +48,16 @@ SOURCE_FILE@0..519 IDENT@41..43 "g2" PARAM_LIST@43..59 L_PAREN@43..44 "(" - ATTR@44..52 - POUND@44..45 "#" - L_BRACK@45..46 "[" - PATH@46..51 - PATH_SEGMENT@46..51 - NAME_REF@46..51 - IDENT@46..51 "attr1" - R_BRACK@51..52 "]" - WHITESPACE@52..53 " " - PARAM@53..58 + PARAM@44..58 + ATTR@44..52 + POUND@44..45 "#" + L_BRACK@45..46 "[" + PATH@46..51 + PATH_SEGMENT@46..51 + NAME_REF@46..51 + IDENT@46..51 "attr1" + R_BRACK@51..52 "]" + WHITESPACE@52..53 " " IDENT_PAT@53..54 NAME@53..54 IDENT@53..54 "x" @@ -203,16 +203,16 @@ SOURCE_FILE@0..519 IDENT@193..196 "bar" PARAM_LIST@196..233 L_PAREN@196..197 "(" - ATTR@197..204 - POUND@197..198 "#" - L_BRACK@198..199 "[" - PATH@199..203 - PATH_SEGMENT@199..203 - NAME_REF@199..203 - IDENT@199..203 "attr" - R_BRACK@203..204 "]" - WHITESPACE@204..205 " " - PARAM@205..211 + PARAM@197..211 + ATTR@197..204 + POUND@197..198 "#" + L_BRACK@198..199 "[" + PATH@199..203 + PATH_SEGMENT@199..203 + NAME_REF@199..203 + IDENT@199..203 "attr" + R_BRACK@203..204 "]" + WHITESPACE@204..205 " " WILDCARD_PAT@205..206 UNDERSCORE@205..206 "_" COLON@206..207 ":"