Skip to content

Commit f622831

Browse files
committed
1 parent 912776f commit f622831

File tree

5 files changed

+54
-56
lines changed

5 files changed

+54
-56
lines changed

crates/ra_parser/src/grammar/expressions/atom.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
229229
let m = p.start();
230230
p.eat(T![async]);
231231
p.eat(T![move]);
232-
params::param_list_opt_types(p);
232+
params::param_list_closure(p);
233233
if opt_fn_ret_type(p) {
234234
if !p.at(T!['{']) {
235235
p.error("expected `{`");

crates/ra_parser/src/grammar/items.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
164164
// async unsafe fn foo() {}
165165
// unsafe const fn bar() {}
166166
T![fn] => {
167-
fn_def(p, flavor);
167+
fn_def(p);
168168
m.complete(p, FN_DEF);
169169
}
170170

@@ -301,7 +301,7 @@ pub(crate) fn extern_item_list(p: &mut Parser) {
301301
m.complete(p, EXTERN_ITEM_LIST);
302302
}
303303

304-
fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
304+
fn fn_def(p: &mut Parser) {
305305
assert!(p.at(T![fn]));
306306
p.bump(T![fn]);
307307

@@ -311,10 +311,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
311311
type_params::opt_type_param_list(p);
312312

313313
if p.at(T!['(']) {
314-
match flavor {
315-
ItemFlavor::Mod => params::param_list(p),
316-
ItemFlavor::Trait => params::param_list_opt_patterns(p),
317-
}
314+
params::param_list_fn(p);
318315
} else {
319316
p.error("expected function arguments");
320317
}

crates/ra_parser/src/grammar/params.rs

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,67 @@
11
//! FIXME: write short doc here
22
3+
// general TODO: `cargo xtask codegen && cargo test`
4+
35
use super::*;
46

57
// test param_list
68
// fn a() {}
79
// fn b(x: i32) {}
810
// fn c(x: i32, ) {}
911
// fn d(x: i32, y: ()) {}
10-
pub(super) fn param_list(p: &mut Parser) {
11-
list_(p, Flavor::Normal)
12+
pub(super) fn param_list_fn(p: &mut Parser) {
13+
list_(p, Flavor::Function)
1214
}
1315

1416
// test param_list_opt_patterns
1517
// fn foo<F: FnMut(&mut Foo<'a>)>(){}
16-
pub(super) fn param_list_opt_patterns(p: &mut Parser) {
17-
list_(p, Flavor::OptionalPattern)
18+
pub(super) fn param_list_impl_fn(p: &mut Parser) {
19+
list_(p, Flavor::ImplFn)
1820
}
1921

20-
pub(super) fn param_list_opt_types(p: &mut Parser) {
21-
list_(p, Flavor::OptionalType)
22+
pub(super) fn param_list_fn_ptr(p: &mut Parser) {
23+
list_(p, Flavor::FnPointer)
2224
}
2325

24-
#[derive(Clone, Copy, Eq, PartialEq)]
25-
enum Flavor {
26-
OptionalType,
27-
OptionalPattern,
28-
Normal,
26+
pub(super) fn param_list_closure(p: &mut Parser) {
27+
list_(p, Flavor::Closure)
2928
}
3029

31-
impl Flavor {
32-
fn type_required(self) -> bool {
33-
match self {
34-
Flavor::OptionalType => false,
35-
_ => true,
36-
}
37-
}
30+
#[derive(Debug, Clone, Copy)]
31+
enum Flavor {
32+
Function, // Includes trait fn params; omitted param idents are not supported
33+
ImplFn,
34+
FnPointer,
35+
Closure
3836
}
3937

4038
fn list_(p: &mut Parser, flavor: Flavor) {
41-
let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) };
42-
assert!(p.at(bra));
39+
use Flavor::*;
40+
41+
let (bra, ket) = match flavor {
42+
Closure => (T![|], T![|]),
43+
Function | ImplFn | FnPointer => (T!['('], T![')'])
44+
};
45+
4346
let m = p.start();
4447
p.bump(bra);
45-
if flavor.type_required() {
48+
49+
if let Function = flavor {
4650
// test self_param_outer_attr
4751
// fn f(#[must_use] self) {}
4852
attributes::outer_attributes(p);
4953
opt_self_param(p);
5054
}
55+
5156
while !p.at(EOF) && !p.at(ket) {
5257
// test param_outer_arg
5358
// fn f(#[attr1] pat: Type) {}
5459
attributes::outer_attributes(p);
5560

56-
if flavor.type_required() && p.at(T![...]) {
57-
break;
61+
if let Function | FnPointer = flavor {
62+
if p.at(T![...]) {
63+
break;
64+
}
5865
}
5966

6067
if !p.at_ts(VALUE_PARAMETER_FIRST) {
@@ -68,7 +75,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
6875
}
6976
// test param_list_vararg
7077
// extern "C" { fn printf(format: *const i8, ...) -> i32; }
71-
if flavor.type_required() {
78+
if let Function | FnPointer = flavor {
7279
p.eat(T![...]);
7380
}
7481
p.expect(ket);
@@ -77,39 +84,31 @@ fn list_(p: &mut Parser, flavor: Flavor) {
7784

7885
const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
7986

87+
// TODO tests
8088
fn value_parameter(p: &mut Parser, flavor: Flavor) {
8189
let m = p.start();
8290
match flavor {
83-
Flavor::OptionalType | Flavor::Normal => {
91+
Flavor::Function => {
8492
patterns::pattern(p);
85-
if p.at(T![:]) && !p.at(T![::]) || flavor.type_required() {
86-
types::ascription(p)
87-
}
93+
types::ascription(p);
94+
}
95+
Flavor::ImplFn => {
96+
types::type_(p);
8897
}
89-
// test value_parameters_no_patterns
90-
// type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
91-
Flavor::OptionalPattern => {
92-
let la0 = p.current();
93-
let la1 = p.nth(1);
94-
let la2 = p.nth(2);
95-
let la3 = p.nth(3);
96-
97-
// test trait_fn_placeholder_parameter
98-
// trait Foo {
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-
{
98+
Flavor::FnPointer => {
99+
if p.at(IDENT) {
107100
patterns::pattern(p);
108101
types::ascription(p);
109102
} else {
110103
types::type_(p);
111104
}
112105
}
106+
Flavor::Closure => {
107+
patterns::pattern(p);
108+
if p.at(T![:]) && !p.at(T![::]) {
109+
types::ascription(p);
110+
}
111+
}
113112
}
114113
m.complete(p, PARAM);
115114
}

crates/ra_parser/src/grammar/paths.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@ fn opt_path_type_args(p: &mut Parser, mode: Mode) {
9797
Mode::Use => return,
9898
Mode::Type => {
9999
// test path_fn_trait_args
100-
// type F = Box<Fn(x: i32) -> ()>;
100+
// type F = Box<Fn(i32) -> ()>;
101101
if p.at(T!['(']) {
102-
params::param_list_opt_patterns(p);
102+
// No binding allowed (test above shouldn't pass)
103+
params::param_list_impl_fn(p);
103104
opt_fn_ret_type(p);
104105
} else {
105106
type_args::opt_type_arg_list(p, false)

crates/ra_parser/src/grammar/types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ fn fn_pointer_type(p: &mut Parser) {
183183
return;
184184
}
185185
if p.at(T!['(']) {
186-
params::param_list_opt_patterns(p);
186+
// optional binding, pattern not allowed
187+
params::param_list_fn_ptr(p);
187188
} else {
188189
p.error("expected parameters")
189190
}

0 commit comments

Comments
 (0)