aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs2
-rw-r--r--crates/ra_parser/src/grammar/items.rs9
-rw-r--r--crates/ra_parser/src/grammar/params.rs111
-rw-r--r--crates/ra_parser/src/grammar/paths.rs4
-rw-r--r--crates/ra_parser/src/grammar/types.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt115
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt61
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs6
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt164
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs6
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt161
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt58
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0030_traits.rs4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0030_traits.txt154
17 files changed, 608 insertions, 255 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 2cc321473..f154077a8 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -229,7 +229,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
229 let m = p.start(); 229 let m = p.start();
230 p.eat(T![async]); 230 p.eat(T![async]);
231 p.eat(T![move]); 231 p.eat(T![move]);
232 params::param_list_opt_types(p); 232 params::param_list_closure(p);
233 if opt_fn_ret_type(p) { 233 if opt_fn_ret_type(p) {
234 if !p.at(T!['{']) { 234 if !p.at(T!['{']) {
235 p.error("expected `{`"); 235 p.error("expected `{`");
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 6e23d9b72..b20d224e8 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -164,7 +164,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
164 // async unsafe fn foo() {} 164 // async unsafe fn foo() {}
165 // unsafe const fn bar() {} 165 // unsafe const fn bar() {}
166 T![fn] => { 166 T![fn] => {
167 fn_def(p, flavor); 167 fn_def(p);
168 m.complete(p, FN_DEF); 168 m.complete(p, FN_DEF);
169 } 169 }
170 170
@@ -301,7 +301,7 @@ pub(crate) fn extern_item_list(p: &mut Parser) {
301 m.complete(p, EXTERN_ITEM_LIST); 301 m.complete(p, EXTERN_ITEM_LIST);
302} 302}
303 303
304fn fn_def(p: &mut Parser, flavor: ItemFlavor) { 304fn fn_def(p: &mut Parser) {
305 assert!(p.at(T![fn])); 305 assert!(p.at(T![fn]));
306 p.bump(T![fn]); 306 p.bump(T![fn]);
307 307
@@ -311,10 +311,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
311 type_params::opt_type_param_list(p); 311 type_params::opt_type_param_list(p);
312 312
313 if p.at(T!['(']) { 313 if p.at(T!['(']) {
314 match flavor { 314 params::param_list_fn(p);
315 ItemFlavor::Mod => params::param_list(p),
316 ItemFlavor::Trait => params::param_list_opt_patterns(p),
317 }
318 } else { 315 } else {
319 p.error("expected function arguments"); 316 p.error("expected function arguments");
320 } 317 }
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index c10b53316..897092a67 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -7,54 +7,59 @@ use super::*;
7// fn b(x: i32) {} 7// fn b(x: i32) {}
8// fn c(x: i32, ) {} 8// fn c(x: i32, ) {}
9// fn d(x: i32, y: ()) {} 9// fn d(x: i32, y: ()) {}
10pub(super) fn param_list(p: &mut Parser) { 10pub(super) fn param_list_fn(p: &mut Parser) {
11 list_(p, Flavor::Normal) 11 list_(p, Flavor::Function)
12} 12}
13 13
14// test param_list_opt_patterns 14// test param_list_opt_patterns
15// fn foo<F: FnMut(&mut Foo<'a>)>(){} 15// fn foo<F: FnMut(&mut Foo<'a>)>(){}
16pub(super) fn param_list_opt_patterns(p: &mut Parser) { 16pub(super) fn param_list_impl_fn(p: &mut Parser) {
17 list_(p, Flavor::OptionalPattern) 17 list_(p, Flavor::ImplFn)
18} 18}
19 19
20pub(super) fn param_list_opt_types(p: &mut Parser) { 20pub(super) fn param_list_fn_ptr(p: &mut Parser) {
21 list_(p, Flavor::OptionalType) 21 list_(p, Flavor::FnPointer)
22} 22}
23 23
24#[derive(Clone, Copy, Eq, PartialEq)] 24pub(super) fn param_list_closure(p: &mut Parser) {
25enum Flavor { 25 list_(p, Flavor::Closure)
26 OptionalType,
27 OptionalPattern,
28 Normal,
29} 26}
30 27
31impl Flavor { 28#[derive(Debug, Clone, Copy)]
32 fn type_required(self) -> bool { 29enum Flavor {
33 match self { 30 Function, // Includes trait fn params; omitted param idents are not supported
34 Flavor::OptionalType => false, 31 ImplFn,
35 _ => true, 32 FnPointer,
36 } 33 Closure
37 }
38} 34}
39 35
40fn list_(p: &mut Parser, flavor: Flavor) { 36fn list_(p: &mut Parser, flavor: Flavor) {
41 let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) }; 37 use Flavor::*;
42 assert!(p.at(bra)); 38
39 let (bra, ket) = match flavor {
40 Closure => (T![|], T![|]),
41 Function | ImplFn | FnPointer => (T!['('], T![')'])
42 };
43
43 let m = p.start(); 44 let m = p.start();
44 p.bump(bra); 45 p.bump(bra);
45 if flavor.type_required() { 46
47 if let Function = flavor {
46 // test self_param_outer_attr 48 // test self_param_outer_attr
47 // fn f(#[must_use] self) {} 49 // fn f(#[must_use] self) {}
48 attributes::outer_attributes(p); 50 attributes::outer_attributes(p);
49 opt_self_param(p); 51 opt_self_param(p);
50 } 52 }
53
51 while !p.at(EOF) && !p.at(ket) { 54 while !p.at(EOF) && !p.at(ket) {
52 // test param_outer_arg 55 // test param_outer_arg
53 // fn f(#[attr1] pat: Type) {} 56 // fn f(#[attr1] pat: Type) {}
54 attributes::outer_attributes(p); 57 attributes::outer_attributes(p);
55 58
56 if flavor.type_required() && p.at(T![...]) { 59 if let Function | FnPointer = flavor {
57 break; 60 if p.at(T![...]) {
61 break;
62 }
58 } 63 }
59 64
60 if !p.at_ts(VALUE_PARAMETER_FIRST) { 65 if !p.at_ts(VALUE_PARAMETER_FIRST) {
@@ -68,7 +73,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
68 } 73 }
69 // test param_list_vararg 74 // test param_list_vararg
70 // extern "C" { fn printf(format: *const i8, ...) -> i32; } 75 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
71 if flavor.type_required() { 76 if let Function | FnPointer = flavor {
72 p.eat(T![...]); 77 p.eat(T![...]);
73 } 78 }
74 p.expect(ket); 79 p.expect(ket);
@@ -80,36 +85,52 @@ const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYP
80fn value_parameter(p: &mut Parser, flavor: Flavor) { 85fn value_parameter(p: &mut Parser, flavor: Flavor) {
81 let m = p.start(); 86 let m = p.start();
82 match flavor { 87 match flavor {
83 Flavor::OptionalType | Flavor::Normal => { 88 // test trait_fn_placeholder_parameter
89 // trait Foo {
90 // fn bar(_: u64, mut x: i32);
91 // }
92
93 // test trait_fn_patterns
94 // trait T {
95 // fn f1((a, b): (usize, usize)) {}
96 // fn f2(S { a, b }: S) {}
97 // fn f3(NewType(a): NewType) {}
98 // fn f4(&&a: &&usize) {}
99 // }
100
101 // test fn_patterns
102 // impl U {
103 // fn f1((a, b): (usize, usize)) {}
104 // fn f2(S { a, b }: S) {}
105 // fn f3(NewType(a): NewType) {}
106 // fn f4(&&a: &&usize) {}
107 // }
108 Flavor::Function => {
84 patterns::pattern(p); 109 patterns::pattern(p);
85 if p.at(T![:]) && !p.at(T![::]) || flavor.type_required() { 110 types::ascription(p);
86 types::ascription(p)
87 }
88 } 111 }
89 // test value_parameters_no_patterns 112 // test value_parameters_no_patterns
90 // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; 113 // type F = Box<Fn(i32, &i32, &i32, ())>;
91 Flavor::OptionalPattern => { 114 Flavor::ImplFn => {
92 let la0 = p.current(); 115 types::type_(p);
93 let la1 = p.nth(1); 116 }
94 let la2 = p.nth(2); 117 // test fn_pointer_param_ident_path
95 let la3 = p.nth(3); 118 // type Foo = fn(Bar::Baz);
96 119 // type Qux = fn(baz: Bar::Baz);
97 // test trait_fn_placeholder_parameter 120 Flavor::FnPointer => {
98 // trait Foo { 121 if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
99 // fn bar(_: u64, mut x: i32);
100 // }
101 if (la0 == IDENT || la0 == T![_]) && la1 == T![:] && !p.nth_at(1, T![::])
102 || la0 == T![mut] && la1 == IDENT && la2 == T![:]
103 || la0 == T![&]
104 && (la1 == IDENT && la2 == T![:] && !p.nth_at(2, T![::])
105 || la1 == T![mut] && la2 == IDENT && la3 == T![:] && !p.nth_at(3, T![::]))
106 {
107 patterns::pattern(p); 122 patterns::pattern(p);
108 types::ascription(p); 123 types::ascription(p);
109 } else { 124 } else {
110 types::type_(p); 125 types::type_(p);
111 } 126 }
112 } 127 }
128 Flavor::Closure => {
129 patterns::pattern(p);
130 if p.at(T![:]) && !p.at(T![::]) {
131 types::ascription(p);
132 }
133 }
113 } 134 }
114 m.complete(p, PARAM); 135 m.complete(p, PARAM);
115} 136}
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs
index ca8e075a1..186064320 100644
--- a/crates/ra_parser/src/grammar/paths.rs
+++ b/crates/ra_parser/src/grammar/paths.rs
@@ -97,9 +97,9 @@ fn opt_path_type_args(p: &mut Parser, mode: Mode) {
97 Mode::Use => return, 97 Mode::Use => return,
98 Mode::Type => { 98 Mode::Type => {
99 // test path_fn_trait_args 99 // test path_fn_trait_args
100 // type F = Box<Fn(x: i32) -> ()>; 100 // type F = Box<Fn(i32) -> ()>;
101 if p.at(T!['(']) { 101 if p.at(T!['(']) {
102 params::param_list_opt_patterns(p); 102 params::param_list_impl_fn(p);
103 opt_fn_ret_type(p); 103 opt_fn_ret_type(p);
104 } else { 104 } else {
105 type_args::opt_type_arg_list(p, false) 105 type_args::opt_type_arg_list(p, false)
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index 9b2e440fb..2c00bce80 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -183,7 +183,7 @@ fn fn_pointer_type(p: &mut Parser) {
183 return; 183 return;
184 } 184 }
185 if p.at(T!['(']) { 185 if p.at(T!['(']) {
186 params::param_list_opt_patterns(p); 186 params::param_list_fn_ptr(p);
187 } else { 187 } else {
188 p.error("expected parameters") 188 p.error("expected parameters")
189 } 189 }
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs
index d8c23c76a..93636e926 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs
@@ -1 +1 @@
type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; type F = Box<Fn(i32, &i32, &i32, ())>;
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt
index 8cfba8420..9241f6fb2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 54) 1SOURCE_FILE@[0; 39)
2 TYPE_ALIAS_DEF@[0; 53) 2 TYPE_ALIAS_DEF@[0; 38)
3 TYPE_KW@[0; 4) "type" 3 TYPE_KW@[0; 4) "type"
4 WHITESPACE@[4; 5) " " 4 WHITESPACE@[4; 5) " "
5 NAME@[5; 6) 5 NAME@[5; 6)
@@ -7,75 +7,54 @@ SOURCE_FILE@[0; 54)
7 WHITESPACE@[6; 7) " " 7 WHITESPACE@[6; 7) " "
8 EQ@[7; 8) "=" 8 EQ@[7; 8) "="
9 WHITESPACE@[8; 9) " " 9 WHITESPACE@[8; 9) " "
10 PATH_TYPE@[9; 52) 10 PATH_TYPE@[9; 37)
11 PATH@[9; 52) 11 PATH@[9; 37)
12 PATH_SEGMENT@[9; 52) 12 PATH_SEGMENT@[9; 37)
13 NAME_REF@[9; 12) 13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "Box" 14 IDENT@[9; 12) "Box"
15 TYPE_ARG_LIST@[12; 52) 15 TYPE_ARG_LIST@[12; 37)
16 L_ANGLE@[12; 13) "<" 16 L_ANGLE@[12; 13) "<"
17 TYPE_ARG@[13; 51) 17 TYPE_ARG@[13; 36)
18 PATH_TYPE@[13; 51) 18 PATH_TYPE@[13; 36)
19 PATH@[13; 51) 19 PATH@[13; 36)
20 PATH_SEGMENT@[13; 51) 20 PATH_SEGMENT@[13; 36)
21 NAME_REF@[13; 15) 21 NAME_REF@[13; 15)
22 IDENT@[13; 15) "Fn" 22 IDENT@[13; 15) "Fn"
23 PARAM_LIST@[15; 51) 23 PARAM_LIST@[15; 36)
24 L_PAREN@[15; 16) "(" 24 L_PAREN@[15; 16) "("
25 PARAM@[16; 22) 25 PARAM@[16; 19)
26 BIND_PAT@[16; 17) 26 PATH_TYPE@[16; 19)
27 NAME@[16; 17) 27 PATH@[16; 19)
28 IDENT@[16; 17) "a" 28 PATH_SEGMENT@[16; 19)
29 COLON@[17; 18) ":" 29 NAME_REF@[16; 19)
30 WHITESPACE@[18; 19) " " 30 IDENT@[16; 19) "i32"
31 PATH_TYPE@[19; 22) 31 COMMA@[19; 20) ","
32 PATH@[19; 22) 32 WHITESPACE@[20; 21) " "
33 PATH_SEGMENT@[19; 22) 33 PARAM@[21; 25)
34 NAME_REF@[19; 22) 34 REFERENCE_TYPE@[21; 25)
35 IDENT@[19; 22) "i32" 35 AMP@[21; 22) "&"
36 COMMA@[22; 23) "," 36 PATH_TYPE@[22; 25)
37 WHITESPACE@[23; 24) " " 37 PATH@[22; 25)
38 PARAM@[24; 32) 38 PATH_SEGMENT@[22; 25)
39 REF_PAT@[24; 26) 39 NAME_REF@[22; 25)
40 AMP@[24; 25) "&" 40 IDENT@[22; 25) "i32"
41 BIND_PAT@[25; 26) 41 COMMA@[25; 26) ","
42 NAME@[25; 26) 42 WHITESPACE@[26; 27) " "
43 IDENT@[25; 26) "b" 43 PARAM@[27; 31)
44 COLON@[26; 27) ":" 44 REFERENCE_TYPE@[27; 31)
45 WHITESPACE@[27; 28) " " 45 AMP@[27; 28) "&"
46 REFERENCE_TYPE@[28; 32) 46 PATH_TYPE@[28; 31)
47 AMP@[28; 29) "&" 47 PATH@[28; 31)
48 PATH_TYPE@[29; 32) 48 PATH_SEGMENT@[28; 31)
49 PATH@[29; 32) 49 NAME_REF@[28; 31)
50 PATH_SEGMENT@[29; 32) 50 IDENT@[28; 31) "i32"
51 NAME_REF@[29; 32) 51 COMMA@[31; 32) ","
52 IDENT@[29; 32) "i32" 52 WHITESPACE@[32; 33) " "
53 COMMA@[32; 33) "," 53 PARAM@[33; 35)
54 WHITESPACE@[33; 34) " " 54 TUPLE_TYPE@[33; 35)
55 PARAM@[34; 46) 55 L_PAREN@[33; 34) "("
56 REF_PAT@[34; 40) 56 R_PAREN@[34; 35) ")"
57 AMP@[34; 35) "&" 57 R_PAREN@[35; 36) ")"
58 MUT_KW@[35; 38) "mut" 58 R_ANGLE@[36; 37) ">"
59 WHITESPACE@[38; 39) " " 59 SEMI@[37; 38) ";"
60 BIND_PAT@[39; 40) 60 WHITESPACE@[38; 39) "\n"
61 NAME@[39; 40)
62 IDENT@[39; 40) "c"
63 COLON@[40; 41) ":"
64 WHITESPACE@[41; 42) " "
65 REFERENCE_TYPE@[42; 46)
66 AMP@[42; 43) "&"
67 PATH_TYPE@[43; 46)
68 PATH@[43; 46)
69 PATH_SEGMENT@[43; 46)
70 NAME_REF@[43; 46)
71 IDENT@[43; 46) "i32"
72 COMMA@[46; 47) ","
73 WHITESPACE@[47; 48) " "
74 PARAM@[48; 50)
75 TUPLE_TYPE@[48; 50)
76 L_PAREN@[48; 49) "("
77 R_PAREN@[49; 50) ")"
78 R_PAREN@[50; 51) ")"
79 R_ANGLE@[51; 52) ">"
80 SEMI@[52; 53) ";"
81 WHITESPACE@[53; 54) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rs b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rs
index aef45e561..17ed20e5b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rs
@@ -1 +1 @@
type F = Box<Fn(x: i32) -> ()>; type F = Box<Fn(i32) -> ()>;
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt
index d6f196811..a983d5954 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 32) 1SOURCE_FILE@[0; 29)
2 TYPE_ALIAS_DEF@[0; 31) 2 TYPE_ALIAS_DEF@[0; 28)
3 TYPE_KW@[0; 4) "type" 3 TYPE_KW@[0; 4) "type"
4 WHITESPACE@[4; 5) " " 4 WHITESPACE@[4; 5) " "
5 NAME@[5; 6) 5 NAME@[5; 6)
@@ -7,40 +7,35 @@ SOURCE_FILE@[0; 32)
7 WHITESPACE@[6; 7) " " 7 WHITESPACE@[6; 7) " "
8 EQ@[7; 8) "=" 8 EQ@[7; 8) "="
9 WHITESPACE@[8; 9) " " 9 WHITESPACE@[8; 9) " "
10 PATH_TYPE@[9; 30) 10 PATH_TYPE@[9; 27)
11 PATH@[9; 30) 11 PATH@[9; 27)
12 PATH_SEGMENT@[9; 30) 12 PATH_SEGMENT@[9; 27)
13 NAME_REF@[9; 12) 13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "Box" 14 IDENT@[9; 12) "Box"
15 TYPE_ARG_LIST@[12; 30) 15 TYPE_ARG_LIST@[12; 27)
16 L_ANGLE@[12; 13) "<" 16 L_ANGLE@[12; 13) "<"
17 TYPE_ARG@[13; 29) 17 TYPE_ARG@[13; 26)
18 PATH_TYPE@[13; 29) 18 PATH_TYPE@[13; 26)
19 PATH@[13; 29) 19 PATH@[13; 26)
20 PATH_SEGMENT@[13; 29) 20 PATH_SEGMENT@[13; 26)
21 NAME_REF@[13; 15) 21 NAME_REF@[13; 15)
22 IDENT@[13; 15) "Fn" 22 IDENT@[13; 15) "Fn"
23 PARAM_LIST@[15; 23) 23 PARAM_LIST@[15; 20)
24 L_PAREN@[15; 16) "(" 24 L_PAREN@[15; 16) "("
25 PARAM@[16; 22) 25 PARAM@[16; 19)
26 BIND_PAT@[16; 17) 26 PATH_TYPE@[16; 19)
27 NAME@[16; 17) 27 PATH@[16; 19)
28 IDENT@[16; 17) "x" 28 PATH_SEGMENT@[16; 19)
29 COLON@[17; 18) ":" 29 NAME_REF@[16; 19)
30 WHITESPACE@[18; 19) " " 30 IDENT@[16; 19) "i32"
31 PATH_TYPE@[19; 22) 31 R_PAREN@[19; 20) ")"
32 PATH@[19; 22) 32 WHITESPACE@[20; 21) " "
33 PATH_SEGMENT@[19; 22) 33 RET_TYPE@[21; 26)
34 NAME_REF@[19; 22) 34 THIN_ARROW@[21; 23) "->"
35 IDENT@[19; 22) "i32" 35 WHITESPACE@[23; 24) " "
36 R_PAREN@[22; 23) ")" 36 TUPLE_TYPE@[24; 26)
37 WHITESPACE@[23; 24) " " 37 L_PAREN@[24; 25) "("
38 RET_TYPE@[24; 29) 38 R_PAREN@[25; 26) ")"
39 THIN_ARROW@[24; 26) "->" 39 R_ANGLE@[26; 27) ">"
40 WHITESPACE@[26; 27) " " 40 SEMI@[27; 28) ";"
41 TUPLE_TYPE@[27; 29) 41 WHITESPACE@[28; 29) "\n"
42 L_PAREN@[27; 28) "("
43 R_PAREN@[28; 29) ")"
44 R_ANGLE@[29; 30) ">"
45 SEMI@[30; 31) ";"
46 WHITESPACE@[31; 32) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs b/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs
new file mode 100644
index 000000000..b49e872d7
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs
@@ -0,0 +1,6 @@
1impl U {
2 fn f1((a, b): (usize, usize)) {}
3 fn f2(S { a, b }: S) {}
4 fn f3(NewType(a): NewType) {}
5 fn f4(&&a: &&usize) {}
6}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt
new file mode 100644
index 000000000..933f5b7bd
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt
@@ -0,0 +1,164 @@
1SOURCE_FILE@[0; 137)
2 IMPL_BLOCK@[0; 136)
3 IMPL_KW@[0; 4) "impl"
4 WHITESPACE@[4; 5) " "
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "U"
10 WHITESPACE@[6; 7) " "
11 ITEM_LIST@[7; 136)
12 L_CURLY@[7; 8) "{"
13 WHITESPACE@[8; 13) "\n "
14 FN_DEF@[13; 45)
15 FN_KW@[13; 15) "fn"
16 WHITESPACE@[15; 16) " "
17 NAME@[16; 18)
18 IDENT@[16; 18) "f1"
19 PARAM_LIST@[18; 42)
20 L_PAREN@[18; 19) "("
21 PARAM@[19; 41)
22 TUPLE_PAT@[19; 25)
23 L_PAREN@[19; 20) "("
24 BIND_PAT@[20; 21)
25 NAME@[20; 21)
26 IDENT@[20; 21) "a"
27 COMMA@[21; 22) ","
28 WHITESPACE@[22; 23) " "
29 BIND_PAT@[23; 24)
30 NAME@[23; 24)
31 IDENT@[23; 24) "b"
32 R_PAREN@[24; 25) ")"
33 COLON@[25; 26) ":"
34 WHITESPACE@[26; 27) " "
35 TUPLE_TYPE@[27; 41)
36 L_PAREN@[27; 28) "("
37 PATH_TYPE@[28; 33)
38 PATH@[28; 33)
39 PATH_SEGMENT@[28; 33)
40 NAME_REF@[28; 33)
41 IDENT@[28; 33) "usize"
42 COMMA@[33; 34) ","
43 WHITESPACE@[34; 35) " "
44 PATH_TYPE@[35; 40)
45 PATH@[35; 40)
46 PATH_SEGMENT@[35; 40)
47 NAME_REF@[35; 40)
48 IDENT@[35; 40) "usize"
49 R_PAREN@[40; 41) ")"
50 R_PAREN@[41; 42) ")"
51 WHITESPACE@[42; 43) " "
52 BLOCK_EXPR@[43; 45)
53 BLOCK@[43; 45)
54 L_CURLY@[43; 44) "{"
55 R_CURLY@[44; 45) "}"
56 WHITESPACE@[45; 50) "\n "
57 FN_DEF@[50; 73)
58 FN_KW@[50; 52) "fn"
59 WHITESPACE@[52; 53) " "
60 NAME@[53; 55)
61 IDENT@[53; 55) "f2"
62 PARAM_LIST@[55; 70)
63 L_PAREN@[55; 56) "("
64 PARAM@[56; 69)
65 RECORD_PAT@[56; 66)
66 PATH@[56; 57)
67 PATH_SEGMENT@[56; 57)
68 NAME_REF@[56; 57)
69 IDENT@[56; 57) "S"
70 WHITESPACE@[57; 58) " "
71 RECORD_FIELD_PAT_LIST@[58; 66)
72 L_CURLY@[58; 59) "{"
73 WHITESPACE@[59; 60) " "
74 BIND_PAT@[60; 61)
75 NAME@[60; 61)
76 IDENT@[60; 61) "a"
77 COMMA@[61; 62) ","
78 WHITESPACE@[62; 63) " "
79 BIND_PAT@[63; 64)
80 NAME@[63; 64)
81 IDENT@[63; 64) "b"
82 WHITESPACE@[64; 65) " "
83 R_CURLY@[65; 66) "}"
84 COLON@[66; 67) ":"
85 WHITESPACE@[67; 68) " "
86 PATH_TYPE@[68; 69)
87 PATH@[68; 69)
88 PATH_SEGMENT@[68; 69)
89 NAME_REF@[68; 69)
90 IDENT@[68; 69) "S"
91 R_PAREN@[69; 70) ")"
92 WHITESPACE@[70; 71) " "
93 BLOCK_EXPR@[71; 73)
94 BLOCK@[71; 73)
95 L_CURLY@[71; 72) "{"
96 R_CURLY@[72; 73) "}"
97 WHITESPACE@[73; 78) "\n "
98 FN_DEF@[78; 107)
99 FN_KW@[78; 80) "fn"
100 WHITESPACE@[80; 81) " "
101 NAME@[81; 83)
102 IDENT@[81; 83) "f3"
103 PARAM_LIST@[83; 104)
104 L_PAREN@[83; 84) "("
105 PARAM@[84; 103)
106 TUPLE_STRUCT_PAT@[84; 94)
107 PATH@[84; 91)
108 PATH_SEGMENT@[84; 91)
109 NAME_REF@[84; 91)
110 IDENT@[84; 91) "NewType"
111 L_PAREN@[91; 92) "("
112 BIND_PAT@[92; 93)
113 NAME@[92; 93)
114 IDENT@[92; 93) "a"
115 R_PAREN@[93; 94) ")"
116 COLON@[94; 95) ":"
117 WHITESPACE@[95; 96) " "
118 PATH_TYPE@[96; 103)
119 PATH@[96; 103)
120 PATH_SEGMENT@[96; 103)
121 NAME_REF@[96; 103)
122 IDENT@[96; 103) "NewType"
123 R_PAREN@[103; 104) ")"
124 WHITESPACE@[104; 105) " "
125 BLOCK_EXPR@[105; 107)
126 BLOCK@[105; 107)
127 L_CURLY@[105; 106) "{"
128 R_CURLY@[106; 107) "}"
129 WHITESPACE@[107; 112) "\n "
130 FN_DEF@[112; 134)
131 FN_KW@[112; 114) "fn"
132 WHITESPACE@[114; 115) " "
133 NAME@[115; 117)
134 IDENT@[115; 117) "f4"
135 PARAM_LIST@[117; 131)
136 L_PAREN@[117; 118) "("
137 PARAM@[118; 130)
138 REF_PAT@[118; 121)
139 AMP@[118; 119) "&"
140 REF_PAT@[119; 121)
141 AMP@[119; 120) "&"
142 BIND_PAT@[120; 121)
143 NAME@[120; 121)
144 IDENT@[120; 121) "a"
145 COLON@[121; 122) ":"
146 WHITESPACE@[122; 123) " "
147 REFERENCE_TYPE@[123; 130)
148 AMP@[123; 124) "&"
149 REFERENCE_TYPE@[124; 130)
150 AMP@[124; 125) "&"
151 PATH_TYPE@[125; 130)
152 PATH@[125; 130)
153 PATH_SEGMENT@[125; 130)
154 NAME_REF@[125; 130)
155 IDENT@[125; 130) "usize"
156 R_PAREN@[130; 131) ")"
157 WHITESPACE@[131; 132) " "
158 BLOCK_EXPR@[132; 134)
159 BLOCK@[132; 134)
160 L_CURLY@[132; 133) "{"
161 R_CURLY@[133; 134) "}"
162 WHITESPACE@[134; 135) "\n"
163 R_CURLY@[135; 136) "}"
164 WHITESPACE@[136; 137) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs b/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs
new file mode 100644
index 000000000..a94bf378a
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs
@@ -0,0 +1,6 @@
1trait T {
2 fn f1((a, b): (usize, usize)) {}
3 fn f2(S { a, b }: S) {}
4 fn f3(NewType(a): NewType) {}
5 fn f4(&&a: &&usize) {}
6}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt
new file mode 100644
index 000000000..b22df8dbe
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt
@@ -0,0 +1,161 @@
1SOURCE_FILE@[0; 138)
2 TRAIT_DEF@[0; 137)
3 TRAIT_KW@[0; 5) "trait"
4 WHITESPACE@[5; 6) " "
5 NAME@[6; 7)
6 IDENT@[6; 7) "T"
7 WHITESPACE@[7; 8) " "
8 ITEM_LIST@[8; 137)
9 L_CURLY@[8; 9) "{"
10 WHITESPACE@[9; 14) "\n "
11 FN_DEF@[14; 46)
12 FN_KW@[14; 16) "fn"
13 WHITESPACE@[16; 17) " "
14 NAME@[17; 19)
15 IDENT@[17; 19) "f1"
16 PARAM_LIST@[19; 43)
17 L_PAREN@[19; 20) "("
18 PARAM@[20; 42)
19 TUPLE_PAT@[20; 26)
20 L_PAREN@[20; 21) "("
21 BIND_PAT@[21; 22)
22 NAME@[21; 22)
23 IDENT@[21; 22) "a"
24 COMMA@[22; 23) ","
25 WHITESPACE@[23; 24) " "
26 BIND_PAT@[24; 25)
27 NAME@[24; 25)
28 IDENT@[24; 25) "b"
29 R_PAREN@[25; 26) ")"
30 COLON@[26; 27) ":"
31 WHITESPACE@[27; 28) " "
32 TUPLE_TYPE@[28; 42)
33 L_PAREN@[28; 29) "("
34 PATH_TYPE@[29; 34)
35 PATH@[29; 34)
36 PATH_SEGMENT@[29; 34)
37 NAME_REF@[29; 34)
38 IDENT@[29; 34) "usize"
39 COMMA@[34; 35) ","
40 WHITESPACE@[35; 36) " "
41 PATH_TYPE@[36; 41)
42 PATH@[36; 41)
43 PATH_SEGMENT@[36; 41)
44 NAME_REF@[36; 41)
45 IDENT@[36; 41) "usize"
46 R_PAREN@[41; 42) ")"
47 R_PAREN@[42; 43) ")"
48 WHITESPACE@[43; 44) " "
49 BLOCK_EXPR@[44; 46)
50 BLOCK@[44; 46)
51 L_CURLY@[44; 45) "{"
52 R_CURLY@[45; 46) "}"
53 WHITESPACE@[46; 51) "\n "
54 FN_DEF@[51; 74)
55 FN_KW@[51; 53) "fn"
56 WHITESPACE@[53; 54) " "
57 NAME@[54; 56)
58 IDENT@[54; 56) "f2"
59 PARAM_LIST@[56; 71)
60 L_PAREN@[56; 57) "("
61 PARAM@[57; 70)
62 RECORD_PAT@[57; 67)
63 PATH@[57; 58)
64 PATH_SEGMENT@[57; 58)
65 NAME_REF@[57; 58)
66 IDENT@[57; 58) "S"
67 WHITESPACE@[58; 59) " "
68 RECORD_FIELD_PAT_LIST@[59; 67)
69 L_CURLY@[59; 60) "{"
70 WHITESPACE@[60; 61) " "
71 BIND_PAT@[61; 62)
72 NAME@[61; 62)
73 IDENT@[61; 62) "a"
74 COMMA@[62; 63) ","
75 WHITESPACE@[63; 64) " "
76 BIND_PAT@[64; 65)
77 NAME@[64; 65)
78 IDENT@[64; 65) "b"
79 WHITESPACE@[65; 66) " "
80 R_CURLY@[66; 67) "}"
81 COLON@[67; 68) ":"
82 WHITESPACE@[68; 69) " "
83 PATH_TYPE@[69; 70)
84 PATH@[69; 70)
85 PATH_SEGMENT@[69; 70)
86 NAME_REF@[69; 70)
87 IDENT@[69; 70) "S"
88 R_PAREN@[70; 71) ")"
89 WHITESPACE@[71; 72) " "
90 BLOCK_EXPR@[72; 74)
91 BLOCK@[72; 74)
92 L_CURLY@[72; 73) "{"
93 R_CURLY@[73; 74) "}"
94 WHITESPACE@[74; 79) "\n "
95 FN_DEF@[79; 108)
96 FN_KW@[79; 81) "fn"
97 WHITESPACE@[81; 82) " "
98 NAME@[82; 84)
99 IDENT@[82; 84) "f3"
100 PARAM_LIST@[84; 105)
101 L_PAREN@[84; 85) "("
102 PARAM@[85; 104)
103 TUPLE_STRUCT_PAT@[85; 95)
104 PATH@[85; 92)
105 PATH_SEGMENT@[85; 92)
106 NAME_REF@[85; 92)
107 IDENT@[85; 92) "NewType"
108 L_PAREN@[92; 93) "("
109 BIND_PAT@[93; 94)
110 NAME@[93; 94)
111 IDENT@[93; 94) "a"
112 R_PAREN@[94; 95) ")"
113 COLON@[95; 96) ":"
114 WHITESPACE@[96; 97) " "
115 PATH_TYPE@[97; 104)
116 PATH@[97; 104)
117 PATH_SEGMENT@[97; 104)
118 NAME_REF@[97; 104)
119 IDENT@[97; 104) "NewType"
120 R_PAREN@[104; 105) ")"
121 WHITESPACE@[105; 106) " "
122 BLOCK_EXPR@[106; 108)
123 BLOCK@[106; 108)
124 L_CURLY@[106; 107) "{"
125 R_CURLY@[107; 108) "}"
126 WHITESPACE@[108; 113) "\n "
127 FN_DEF@[113; 135)
128 FN_KW@[113; 115) "fn"
129 WHITESPACE@[115; 116) " "
130 NAME@[116; 118)
131 IDENT@[116; 118) "f4"
132 PARAM_LIST@[118; 132)
133 L_PAREN@[118; 119) "("
134 PARAM@[119; 131)
135 REF_PAT@[119; 122)
136 AMP@[119; 120) "&"
137 REF_PAT@[120; 122)
138 AMP@[120; 121) "&"
139 BIND_PAT@[121; 122)
140 NAME@[121; 122)
141 IDENT@[121; 122) "a"
142 COLON@[122; 123) ":"
143 WHITESPACE@[123; 124) " "
144 REFERENCE_TYPE@[124; 131)
145 AMP@[124; 125) "&"
146 REFERENCE_TYPE@[125; 131)
147 AMP@[125; 126) "&"
148 PATH_TYPE@[126; 131)
149 PATH@[126; 131)
150 PATH_SEGMENT@[126; 131)
151 NAME_REF@[126; 131)
152 IDENT@[126; 131) "usize"
153 R_PAREN@[131; 132) ")"
154 WHITESPACE@[132; 133) " "
155 BLOCK_EXPR@[133; 135)
156 BLOCK@[133; 135)
157 L_CURLY@[133; 134) "{"
158 R_CURLY@[134; 135) "}"
159 WHITESPACE@[135; 136) "\n"
160 R_CURLY@[136; 137) "}"
161 WHITESPACE@[137; 138) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs
new file mode 100644
index 000000000..80a1701fd
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs
@@ -0,0 +1,2 @@
1type Foo = fn(Bar::Baz);
2type Qux = fn(baz: Bar::Baz);
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt
new file mode 100644
index 000000000..cb686854a
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt
@@ -0,0 +1,58 @@
1SOURCE_FILE@[0; 55)
2 TYPE_ALIAS_DEF@[0; 24)
3 TYPE_KW@[0; 4) "type"
4 WHITESPACE@[4; 5) " "
5 NAME@[5; 8)
6 IDENT@[5; 8) "Foo"
7 WHITESPACE@[8; 9) " "
8 EQ@[9; 10) "="
9 WHITESPACE@[10; 11) " "
10 FN_POINTER_TYPE@[11; 23)
11 FN_KW@[11; 13) "fn"
12 PARAM_LIST@[13; 23)
13 L_PAREN@[13; 14) "("
14 PARAM@[14; 22)
15 PATH_TYPE@[14; 22)
16 PATH@[14; 22)
17 PATH@[14; 17)
18 PATH_SEGMENT@[14; 17)
19 NAME_REF@[14; 17)
20 IDENT@[14; 17) "Bar"
21 COLONCOLON@[17; 19) "::"
22 PATH_SEGMENT@[19; 22)
23 NAME_REF@[19; 22)
24 IDENT@[19; 22) "Baz"
25 R_PAREN@[22; 23) ")"
26 SEMI@[23; 24) ";"
27 WHITESPACE@[24; 25) "\n"
28 TYPE_ALIAS_DEF@[25; 54)
29 TYPE_KW@[25; 29) "type"
30 WHITESPACE@[29; 30) " "
31 NAME@[30; 33)
32 IDENT@[30; 33) "Qux"
33 WHITESPACE@[33; 34) " "
34 EQ@[34; 35) "="
35 WHITESPACE@[35; 36) " "
36 FN_POINTER_TYPE@[36; 53)
37 FN_KW@[36; 38) "fn"
38 PARAM_LIST@[38; 53)
39 L_PAREN@[38; 39) "("
40 PARAM@[39; 52)
41 BIND_PAT@[39; 42)
42 NAME@[39; 42)
43 IDENT@[39; 42) "baz"
44 COLON@[42; 43) ":"
45 WHITESPACE@[43; 44) " "
46 PATH_TYPE@[44; 52)
47 PATH@[44; 52)
48 PATH@[44; 47)
49 PATH_SEGMENT@[44; 47)
50 NAME_REF@[44; 47)
51 IDENT@[44; 47) "Bar"
52 COLONCOLON@[47; 49) "::"
53 PATH_SEGMENT@[49; 52)
54 NAME_REF@[49; 52)
55 IDENT@[49; 52) "Baz"
56 R_PAREN@[52; 53) ")"
57 SEMI@[53; 54) ";"
58 WHITESPACE@[54; 55) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0030_traits.rs b/crates/ra_syntax/test_data/parser/ok/0030_traits.rs
index 23c4be0e1..ac30843ef 100644
--- a/crates/ra_syntax/test_data/parser/ok/0030_traits.rs
+++ b/crates/ra_syntax/test_data/parser/ok/0030_traits.rs
@@ -1,7 +1,3 @@
1pub trait WriteMessage {
2 fn write_message(&FrontendMessage);
3}
4
5trait Runnable { 1trait Runnable {
6 fn handler(); 2 fn handler();
7} 3}
diff --git a/crates/ra_syntax/test_data/parser/ok/0030_traits.txt b/crates/ra_syntax/test_data/parser/ok/0030_traits.txt
index b656c1a81..ac314ae50 100644
--- a/crates/ra_syntax/test_data/parser/ok/0030_traits.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0030_traits.txt
@@ -1,93 +1,61 @@
1SOURCE_FILE@[0; 164) 1SOURCE_FILE@[0; 96)
2 TRAIT_DEF@[0; 66) 2 TRAIT_DEF@[0; 36)
3 VISIBILITY@[0; 3) 3 TRAIT_KW@[0; 5) "trait"
4 PUB_KW@[0; 3) "pub" 4 WHITESPACE@[5; 6) " "
5 WHITESPACE@[3; 4) " " 5 NAME@[6; 14)
6 TRAIT_KW@[4; 9) "trait" 6 IDENT@[6; 14) "Runnable"
7 WHITESPACE@[9; 10) " " 7 WHITESPACE@[14; 15) " "
8 NAME@[10; 22) 8 ITEM_LIST@[15; 36)
9 IDENT@[10; 22) "WriteMessage" 9 L_CURLY@[15; 16) "{"
10 WHITESPACE@[22; 23) " " 10 WHITESPACE@[16; 21) "\n "
11 ITEM_LIST@[23; 66) 11 FN_DEF@[21; 34)
12 L_CURLY@[23; 24) "{" 12 FN_KW@[21; 23) "fn"
13 WHITESPACE@[24; 29) "\n " 13 WHITESPACE@[23; 24) " "
14 FN_DEF@[29; 64) 14 NAME@[24; 31)
15 FN_KW@[29; 31) "fn" 15 IDENT@[24; 31) "handler"
16 WHITESPACE@[31; 32) " " 16 PARAM_LIST@[31; 33)
17 NAME@[32; 45) 17 L_PAREN@[31; 32) "("
18 IDENT@[32; 45) "write_message" 18 R_PAREN@[32; 33) ")"
19 PARAM_LIST@[45; 63) 19 SEMI@[33; 34) ";"
20 L_PAREN@[45; 46) "(" 20 WHITESPACE@[34; 35) "\n"
21 PARAM@[46; 62) 21 R_CURLY@[35; 36) "}"
22 REFERENCE_TYPE@[46; 62) 22 WHITESPACE@[36; 38) "\n\n"
23 AMP@[46; 47) "&" 23 TRAIT_DEF@[38; 95)
24 PATH_TYPE@[47; 62) 24 TRAIT_KW@[38; 43) "trait"
25 PATH@[47; 62) 25 WHITESPACE@[43; 44) " "
26 PATH_SEGMENT@[47; 62) 26 NAME@[44; 57)
27 NAME_REF@[47; 62) 27 IDENT@[44; 57) "TraitWithExpr"
28 IDENT@[47; 62) "FrontendMessage" 28 WHITESPACE@[57; 58) " "
29 R_PAREN@[62; 63) ")" 29 ITEM_LIST@[58; 95)
30 SEMI@[63; 64) ";" 30 L_CURLY@[58; 59) "{"
31 WHITESPACE@[64; 65) "\n" 31 WHITESPACE@[59; 64) "\n "
32 R_CURLY@[65; 66) "}" 32 FN_DEF@[64; 93)
33 WHITESPACE@[66; 68) "\n\n" 33 FN_KW@[64; 66) "fn"
34 TRAIT_DEF@[68; 104) 34 WHITESPACE@[66; 67) " "
35 TRAIT_KW@[68; 73) "trait" 35 NAME@[67; 79)
36 WHITESPACE@[73; 74) " " 36 IDENT@[67; 79) "fn_with_expr"
37 NAME@[74; 82) 37 PARAM_LIST@[79; 92)
38 IDENT@[74; 82) "Runnable" 38 L_PAREN@[79; 80) "("
39 WHITESPACE@[82; 83) " " 39 PARAM@[80; 91)
40 ITEM_LIST@[83; 104) 40 BIND_PAT@[80; 81)
41 L_CURLY@[83; 84) "{" 41 NAME@[80; 81)
42 WHITESPACE@[84; 89) "\n " 42 IDENT@[80; 81) "x"
43 FN_DEF@[89; 102) 43 COLON@[81; 82) ":"
44 FN_KW@[89; 91) "fn" 44 WHITESPACE@[82; 83) " "
45 WHITESPACE@[91; 92) " " 45 ARRAY_TYPE@[83; 91)
46 NAME@[92; 99) 46 L_BRACK@[83; 84) "["
47 IDENT@[92; 99) "handler" 47 PATH_TYPE@[84; 87)
48 PARAM_LIST@[99; 101) 48 PATH@[84; 87)
49 L_PAREN@[99; 100) "(" 49 PATH_SEGMENT@[84; 87)
50 R_PAREN@[100; 101) ")" 50 NAME_REF@[84; 87)
51 SEMI@[101; 102) ";" 51 IDENT@[84; 87) "i32"
52 WHITESPACE@[102; 103) "\n" 52 SEMI@[87; 88) ";"
53 R_CURLY@[103; 104) "}" 53 WHITESPACE@[88; 89) " "
54 WHITESPACE@[104; 106) "\n\n" 54 LITERAL@[89; 90)
55 TRAIT_DEF@[106; 163) 55 INT_NUMBER@[89; 90) "1"
56 TRAIT_KW@[106; 111) "trait" 56 R_BRACK@[90; 91) "]"
57 WHITESPACE@[111; 112) " " 57 R_PAREN@[91; 92) ")"
58 NAME@[112; 125) 58 SEMI@[92; 93) ";"
59 IDENT@[112; 125) "TraitWithExpr" 59 WHITESPACE@[93; 94) "\n"
60 WHITESPACE@[125; 126) " " 60 R_CURLY@[94; 95) "}"
61 ITEM_LIST@[126; 163) 61 WHITESPACE@[95; 96) "\n"
62 L_CURLY@[126; 127) "{"
63 WHITESPACE@[127; 132) "\n "
64 FN_DEF@[132; 161)
65 FN_KW@[132; 134) "fn"
66 WHITESPACE@[134; 135) " "
67 NAME@[135; 147)
68 IDENT@[135; 147) "fn_with_expr"
69 PARAM_LIST@[147; 160)
70 L_PAREN@[147; 148) "("
71 PARAM@[148; 159)
72 BIND_PAT@[148; 149)
73 NAME@[148; 149)
74 IDENT@[148; 149) "x"
75 COLON@[149; 150) ":"
76 WHITESPACE@[150; 151) " "
77 ARRAY_TYPE@[151; 159)
78 L_BRACK@[151; 152) "["
79 PATH_TYPE@[152; 155)
80 PATH@[152; 155)
81 PATH_SEGMENT@[152; 155)
82 NAME_REF@[152; 155)
83 IDENT@[152; 155) "i32"
84 SEMI@[155; 156) ";"
85 WHITESPACE@[156; 157) " "
86 LITERAL@[157; 158)
87 INT_NUMBER@[157; 158) "1"
88 R_BRACK@[158; 159) "]"
89 R_PAREN@[159; 160) ")"
90 SEMI@[160; 161) ";"
91 WHITESPACE@[161; 162) "\n"
92 R_CURLY@[162; 163) "}"
93 WHITESPACE@[163; 164) "\n"