Skip to content

Commit 39eaeb4

Browse files
committed
fix: parse weird exprs correctly
1 parent afb6000 commit 39eaeb4

File tree

8 files changed

+86217
-77959
lines changed

8 files changed

+86217
-77959
lines changed

.gitattributes

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
/src/** linguist-vendored
21
/examples/* linguist-vendored
32

3+
src/tree_sitter/* linguist-generated
44
src/grammar.json linguist-generated
55
src/node-types.json linguist-generated
66
src/parser.c linguist-generated
7-
8-
src/grammar.json -diff
9-
src/node-types.json -diff
10-
src/parser.c -diff

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ build
55
package-lock.json
66
/examples
77
!examples/ast.rs
8+
!examples/weird-exprs.rs
89
/target/

examples/weird-exprs.rs

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
// run-pass
2+
3+
#![feature(generators)]
4+
5+
#![allow(non_camel_case_types)]
6+
#![allow(dead_code)]
7+
#![allow(redundant_semicolons)]
8+
#![allow(unreachable_code)]
9+
#![allow(unused_braces, unused_must_use, unused_parens)]
10+
#![allow(uncommon_codepoints, confusable_idents)]
11+
#![allow(unused_imports)]
12+
#![allow(unreachable_patterns)]
13+
14+
#![recursion_limit = "256"]
15+
16+
extern crate core;
17+
use std::cell::Cell;
18+
use std::mem::swap;
19+
use std::ops::Deref;
20+
21+
// Just a grab bag of stuff that you wouldn't want to actually write.
22+
23+
fn strange() -> bool { let _x: bool = return true; }
24+
25+
fn funny() {
26+
fn f(_x: ()) { }
27+
f(return);
28+
}
29+
30+
fn what() {
31+
fn the(x: &Cell<bool>) {
32+
return while !x.get() { x.set(true); };
33+
}
34+
let i = &Cell::new(false);
35+
let dont = {||the(i)};
36+
dont();
37+
assert!((i.get()));
38+
}
39+
40+
fn zombiejesus() {
41+
loop {
42+
while (return) {
43+
if (return) {
44+
match (return) {
45+
1 => {
46+
if (return) {
47+
return
48+
} else {
49+
return
50+
}
51+
}
52+
_ => { return }
53+
};
54+
} else if (return) {
55+
return;
56+
}
57+
}
58+
if (return) { break; }
59+
}
60+
}
61+
62+
fn notsure() {
63+
let mut _x: isize;
64+
let mut _y = (_x = 0) == (_x = 0);
65+
let mut _z = (_x = 0) < (_x = 0);
66+
let _a = (_x += 0) == (_x = 0);
67+
let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
68+
}
69+
70+
fn canttouchthis() -> usize {
71+
fn p() -> bool { true }
72+
let _a = (assert!((true)) == (assert!(p())));
73+
let _c = (assert!((p())) == ());
74+
let _b: bool = (println!("{}", 0) == (return 0));
75+
}
76+
77+
fn angrydome() {
78+
loop { if break { } }
79+
let mut i = 0;
80+
loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
81+
break; }
82+
}
83+
84+
fn evil_lincoln() { let _evil: () = println!("lincoln"); }
85+
86+
fn dots() {
87+
assert_eq!(String::from(".................................................."),
88+
format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
89+
.. .. .. .. .. .. .. .. .. .. .. ..));
90+
}
91+
92+
fn u8(u8: u8) {
93+
if u8 != 0u8 {
94+
assert_eq!(8u8, {
95+
macro_rules! u8 {
96+
(u8) => {
97+
mod u8 {
98+
pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
99+
"u8";
100+
u8
101+
}
102+
}
103+
};
104+
}
105+
106+
u8!(u8);
107+
let &u8: &u8 = u8::u8(&8u8);
108+
::u8(0u8);
109+
u8
110+
});
111+
}
112+
}
113+
114+
fn fishy() {
115+
assert_eq!(String::from("><>"),
116+
String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
117+
}
118+
119+
fn union() {
120+
union union<'union> { union: &'union union<'union>, }
121+
}
122+
123+
fn special_characters() {
124+
let val = !((|(..):(_,_),(|__@_|__)|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
125+
;
126+
assert!(!val);
127+
}
128+
129+
fn punch_card() -> impl std::fmt::Debug {
130+
..=..=.. .. .. .. .. .. .. .. .. .. .. ..=.. ..
131+
..=.. ..=.. .. .. .. .. .. .. .. .. ..=..=..=..
132+
..=.. ..=.. ..=.. ..=.. .. ..=..=.. .. ..=.. ..
133+
..=..=.. .. ..=.. ..=.. ..=.. .. .. .. ..=.. ..
134+
..=.. ..=.. ..=.. ..=.. .. ..=.. .. .. ..=.. ..
135+
..=.. ..=.. ..=.. ..=.. .. .. ..=.. .. ..=.. ..
136+
..=.. ..=.. .. ..=..=.. ..=..=.. .. .. ..=.. ..
137+
}
138+
139+
fn r#match() {
140+
let val: () = match match match match match () {
141+
() => ()
142+
} {
143+
() => ()
144+
} {
145+
() => ()
146+
} {
147+
() => ()
148+
} {
149+
() => ()
150+
};
151+
assert_eq!(val, ());
152+
}
153+
154+
fn i_yield() {
155+
static || {
156+
yield yield yield yield yield yield yield yield yield;
157+
};
158+
}
159+
160+
fn match_nested_if() {
161+
let val = match () {
162+
() if if if if true {true} else {false} {true} else {false} {true} else {false} => true,
163+
_ => false,
164+
};
165+
assert!(val);
166+
}
167+
168+
fn monkey_barrel() {
169+
let val: () = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=();
170+
assert_eq!(val, ());
171+
}
172+
173+
fn 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎() {
174+
type 𝚕𝚘𝚘𝚙 = i32;
175+
fn 𝚋𝚛𝚎𝚊𝚔() -> 𝚕𝚘𝚘𝚙 {
176+
let 𝚛𝚎𝚝𝚞𝚛𝚗 = 42;
177+
return 𝚛𝚎𝚝𝚞𝚛𝚗;
178+
}
179+
assert_eq!(loop {
180+
break 𝚋𝚛𝚎𝚊𝚔 ();
181+
}, 42);
182+
}
183+
184+
fn function() {
185+
struct foo;
186+
impl Deref for foo {
187+
type Target = fn() -> Self;
188+
fn deref(&self) -> &Self::Target {
189+
&((|| foo) as _)
190+
}
191+
}
192+
let foo = foo () ()() ()()() ()()()() ()()()()();
193+
}
194+
195+
fn bathroom_stall() {
196+
let mut i = 1;
197+
matches!(2, _|_|_|_|_|_ if (i+=1) != (i+=1));
198+
assert_eq!(i, 13);
199+
}
200+
201+
fn closure_matching() {
202+
let x = |_| Some(1);
203+
let (|x| x) = match x(..) {
204+
|_| Some(2) => |_| Some(3),
205+
|_| _ => unreachable!(),
206+
};
207+
assert!(matches!(x(..), |_| Some(4)));
208+
}
209+
210+
fn semisemisemisemisemi() {
211+
;;;;;;; ;;;;;;; ;;; ;;; ;;
212+
;; ;; ;;;; ;;;; ;;
213+
;;;;;;; ;;;;; ;; ;;;; ;; ;;
214+
;; ;; ;; ;; ;; ;;
215+
;;;;;;; ;;;;;;; ;; ;; ;;
216+
}
217+
218+
fn useful_syntax() {
219+
use {{std::{{collections::{{HashMap}}}}}};
220+
use ::{{{{core}, {std}}}};
221+
use {{::{{core as core2}}}};
222+
}
223+
224+
fn infcx() {
225+
pub mod cx {
226+
pub mod cx {
227+
pub use super::cx;
228+
pub struct Cx;
229+
}
230+
}
231+
let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx;
232+
}
233+
234+
pub fn main() {
235+
strange();
236+
funny();
237+
what();
238+
zombiejesus();
239+
notsure();
240+
canttouchthis();
241+
angrydome();
242+
evil_lincoln();
243+
dots();
244+
u8(8u8);
245+
fishy();
246+
union();
247+
special_characters();
248+
punch_card();
249+
r#match();
250+
i_yield();
251+
match_nested_if();
252+
monkey_barrel();
253+
𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎();
254+
function();
255+
bathroom_stall();
256+
closure_matching();
257+
semisemisemisemisemi();
258+
useful_syntax();
259+
infcx();
260+
}

grammar.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ module.exports = grammar({
778778
generic_type: $ => prec(1, seq(
779779
field('type', choice(
780780
$._type_identifier,
781+
$._reserved_identifier,
781782
$.scoped_type_identifier,
782783
)),
783784
field('type_arguments', $.type_arguments),
@@ -1173,15 +1174,15 @@ module.exports = grammar({
11731174
'}',
11741175
),
11751176

1176-
match_arm: $ => seq(
1177+
match_arm: $ => prec.right(seq(
11771178
repeat($.attribute_item),
11781179
field('pattern', $.match_pattern),
11791180
'=>',
11801181
choice(
11811182
seq(field('value', $._expression), ','),
11821183
field('value', prec(1, $._expression_ending_with_block)),
11831184
),
1184-
),
1185+
)),
11851186

11861187
last_match_arm: $ => seq(
11871188
repeat($.attribute_item),
@@ -1192,7 +1193,7 @@ module.exports = grammar({
11921193
),
11931194

11941195
match_pattern: $ => seq(
1195-
$._pattern,
1196+
choice($._pattern, alias($.closure_expression, $.closure_pattern)),
11961197
optional(seq('if', field('condition', $._condition))),
11971198
),
11981199

@@ -1224,14 +1225,15 @@ module.exports = grammar({
12241225
),
12251226

12261227
closure_expression: $ => prec(PREC.closure, seq(
1228+
optional('static'),
12271229
optional('move'),
12281230
field('parameters', $.closure_parameters),
12291231
choice(
12301232
seq(
12311233
optional(seq('->', field('return_type', $._type))),
12321234
field('body', $.block),
12331235
),
1234-
field('body', $._expression),
1236+
field('body', choice($._expression, '_')),
12351237
),
12361238
)),
12371239

@@ -1311,7 +1313,7 @@ module.exports = grammar({
13111313

13121314
tuple_pattern: $ => seq(
13131315
'(',
1314-
sepBy(',', $._pattern),
1316+
sepBy(',', choice($._pattern, $.closure_expression)),
13151317
optional(','),
13161318
')',
13171319
),

script/known_failures.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
examples/tokio/examples/connect.rs

0 commit comments

Comments
 (0)