Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 58d8da1

Browse files
committed
Use compile_errors! to report parse errors
Unfortunately, we will lose the span for these errors. (See rust-lang/rust#44535)
1 parent afb61e9 commit 58d8da1

File tree

2 files changed

+107
-82
lines changed

2 files changed

+107
-82
lines changed

src/macros/mod.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,51 +30,6 @@ macro_rules! item {
3030
($it: item) => { $it }
3131
}
3232

33-
34-
#[doc(hidden)]
35-
#[macro_export]
36-
macro_rules! assert_struct {
37-
(true, {
38-
type: class,
39-
rust_name: $rust_name:ident,
40-
ruby_name: $ruby_name:tt,
41-
meta: $meta:tt,
42-
struct: { $($struct:tt)+ },
43-
methods: $methods:tt
44-
}) => {};
45-
46-
(false, {
47-
type: class,
48-
rust_name: $rust_name:ident,
49-
ruby_name: $ruby_name:tt,
50-
meta: $meta:tt,
51-
struct: (),
52-
methods: $methods:tt
53-
}) => {};
54-
}
55-
56-
#[doc(hidden)]
57-
#[macro_export]
58-
macro_rules! assert_valid_self_arg {
59-
(self) => {}
60-
}
61-
62-
#[doc(hidden)]
63-
#[macro_export]
64-
macro_rules! assert_valid_arg {
65-
($arg:ident) => {};
66-
(_) => {};
67-
}
68-
69-
#[doc(hidden)]
70-
#[macro_export]
71-
macro_rules! assert_no_explict_return_for_initializer {
72-
(instance_method, $($rest:tt)*) => {};
73-
(class_method, $($rest:tt)*) => {};
74-
(initializer, ) => {};
75-
}
76-
77-
7833
#[macro_export]
7934
macro_rules! throw {
8035
($msg:expr) => {

src/macros/parser.rs

Lines changed: 107 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ macro_rules! parse {
8989
state: parse_class,
9090
buffer: $buffer,
9191
stack: {
92-
ruby_name: {},
92+
ruby_name: uninitialized,
9393
pub: false,
9494
reopen: false,
9595
$($stack)*
@@ -103,7 +103,7 @@ macro_rules! parse {
103103
state: parse_class,
104104
buffer: { #[ruby_name = $ruby_name:tt] $($rest:tt)* },
105105
stack: {
106-
ruby_name: {},
106+
ruby_name: uninitialized,
107107
pub: false,
108108
reopen: false,
109109
$($stack:tt)*
@@ -169,7 +169,7 @@ macro_rules! parse {
169169
state: parse_class,
170170
buffer: { class $name:tt $($rest:tt)* },
171171
stack: {
172-
ruby_name: {},
172+
ruby_name: uninitialized,
173173
$($stack:tt)*
174174
}
175175
} => {
@@ -195,15 +195,15 @@ macro_rules! parse {
195195
}
196196
} => {
197197
parse! {
198-
state: parse_class_body,
198+
state: parse_struct,
199199
buffer: { $($body)* },
200200
stack: {
201201
class: {
202202
type: class,
203203
rust_name: $name,
204204
ruby_name: $ruby_name,
205205
meta: { pub: $pub, reopen: $reopen },
206-
struct: uninitialized,
206+
struct: (),
207207
methods: []
208208
},
209209
program: { $($rest)* },
@@ -212,23 +212,25 @@ macro_rules! parse {
212212
}
213213
};
214214

215-
// STATE: parse_class_body
215+
// STATE: parse_struct
216216

217217
{
218-
state: parse_class_body,
218+
state: parse_struct,
219219
buffer: { struct { $($struct:tt)* } $($rest:tt)* },
220220
stack: {
221221
class: {
222222
type: class,
223-
rust_name: $rust_name:ident,
223+
rust_name: $rust_name:tt,
224224
ruby_name: $ruby_name:tt,
225-
meta: $meta:tt,
226-
struct: uninitialized,
227-
methods : []
225+
meta: { pub: $pub:tt, reopen: $reopen:tt },
226+
struct: (),
227+
methods: []
228228
},
229229
$($stack:tt)*
230230
}
231231
} => {
232+
assert_not_reopen!({ reopen: $reopen }, "Cannot define a struct in `reopen class`");
233+
232234
parse! {
233235
state: parse_methods,
234236
buffer: { $($rest)* },
@@ -237,7 +239,7 @@ macro_rules! parse {
237239
type: class,
238240
rust_name: $rust_name,
239241
ruby_name: $ruby_name,
240-
meta: $meta,
242+
meta: { pub: $pub, reopen: $reopen },
241243
struct: { $($struct)* },
242244
methods: []
243245
},
@@ -247,34 +249,14 @@ macro_rules! parse {
247249
};
248250

249251
{
250-
state: parse_class_body,
252+
state: parse_struct,
251253
buffer: $buffer:tt,
252-
stack: {
253-
class: {
254-
type: class,
255-
rust_name: $rust_name:ident,
256-
ruby_name: $ruby_name:tt,
257-
meta: $meta:tt,
258-
struct: uninitialized,
259-
methods : []
260-
},
261-
$($stack:tt)*
262-
}
254+
stack: $stack:tt
263255
} => {
264256
parse! {
265257
state: parse_methods,
266258
buffer: $buffer,
267-
stack: {
268-
class: {
269-
type: class,
270-
rust_name: $rust_name,
271-
ruby_name: $ruby_name,
272-
meta: $meta,
273-
struct: (),
274-
methods: []
275-
},
276-
$($stack)*
277-
}
259+
stack: $stack
278260
}
279261
};
280262

@@ -342,7 +324,8 @@ macro_rules! parse {
342324
$($stack:tt)*
343325
}
344326
} => {
345-
assert_struct!(true, $class);
327+
assert_not_reopen!($class, "Cannot define `initialize` in `reopen class`");
328+
assert_has_struct!($class, "Cannot define `initialize` without a `struct`");
346329

347330
parse! {
348331
state: parse_arguments_helix,
@@ -578,7 +561,7 @@ macro_rules! parse {
578561
$($stack:tt)*
579562
}
580563
} => {
581-
assert_no_explict_return_for_initializer!($type, ->);
564+
assert_no_explict_return_for_initializer!({ type: $type }, "`def initialize` cannot have an explicit return type");
582565

583566
parse! {
584567
state: finish_method,
@@ -716,4 +699,91 @@ macro_rules! parse {
716699
}
717700
}
718701
};
702+
703+
// Catch all
704+
705+
{ $($state:tt)* } => {
706+
parse_error!(
707+
"Unknonw parser state. ",
708+
"This is possibly a bug in Helix itself, please file an issue ",
709+
"with the following debug information:\n\n",
710+
format_parser_state!($($state)*)
711+
);
712+
};
713+
}
714+
715+
#[doc(hidden)]
716+
#[macro_export]
717+
macro_rules! parse_error {
718+
($($message:expr),*) => { compile_error!(concat!("Parse Error! ", $($message),*)); };
719+
}
720+
721+
#[doc(hidden)]
722+
#[macro_export]
723+
macro_rules! format_parser_state {
724+
{
725+
state: $state:tt,
726+
buffer: $buffer:tt,
727+
stack: $stack:tt
728+
} => {
729+
concat!("{\n",
730+
" state: ", stringify!($state), ",\n",
731+
" buffer: ", stringify!($buffer), ",\n",
732+
" stack: ", stringify!($stack), ",\n",
733+
"}")
734+
};
735+
736+
{ $($state:tt)* } => { concat!("(CORRUPTED)\n", stringify!($($state)*)) };
737+
}
738+
739+
#[doc(hidden)]
740+
#[macro_export]
741+
macro_rules! assert_not_reopen {
742+
{
743+
{
744+
type: class,
745+
rust_name: $rust_name:tt,
746+
ruby_name: $ruby_name:tt,
747+
meta: { pub: $pub:tt, reopen: $reopen:tt },
748+
struct: $struct:tt,
749+
methods: $methods:tt
750+
},
751+
$($message:expr),*
752+
} => { assert_not_reopen!({ reopen: $reopen }, $($message),*); };
753+
754+
{ { reopen: true }, $($message:expr),* } => { parse_error!($($message),*); };
755+
{ { reopen: false }, $($message:expr),* } => {};
756+
}
757+
758+
#[doc(hidden)]
759+
#[macro_export]
760+
macro_rules! assert_has_struct {
761+
{
762+
{
763+
type: class,
764+
rust_name: $rust_name:tt,
765+
ruby_name: $ruby_name:tt,
766+
meta: $meta:tt,
767+
struct: $struct:tt,
768+
methods: $methods:tt
769+
},
770+
$($message:expr),*
771+
} => { assert_has_struct!({ struct: $struct }, $($message),*); };
772+
773+
{ { struct: () }, $($message:expr),* } => { parse_error!($($message),*); };
774+
{ { struct: $struct:tt }, $($message:expr),* } => {};
775+
}
776+
777+
#[doc(hidden)]
778+
#[macro_export]
779+
macro_rules! assert_valid_self_arg {
780+
(self) => {};
781+
}
782+
783+
#[doc(hidden)]
784+
#[macro_export]
785+
macro_rules! assert_no_explict_return_for_initializer {
786+
({ type: instance_method }, $($message:expr),*) => {};
787+
({ type: class_method }, $($message:expr),*) => {};
788+
({ type: initializer }, $($message:expr),*) => { parse_error!($($message),*); };
719789
}

0 commit comments

Comments
 (0)