Skip to content

Commit 684d387

Browse files
committed
add larger test for proc_macro FromStr implementations
1 parent e5efc33 commit 684d387

File tree

5 files changed

+383
-0
lines changed

5 files changed

+383
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use proc_macro::*;
2+
use std::panic::catch_unwind;
3+
use std::str::FromStr;
4+
5+
fn stream(s: &str) {
6+
println!("{:?}", TokenStream::from_str(s));
7+
}
8+
9+
fn lit(s: &str) {
10+
println!("{:?}", Literal::from_str(s));
11+
}
12+
13+
fn stream_catch_unwind(s: &str) {
14+
if catch_unwind(|| println!("{:?}", TokenStream::from_str(s))).is_ok() {
15+
eprintln!("{s} did not panic");
16+
}
17+
}
18+
19+
fn lit_catch_unwind(s: &str) {
20+
if catch_unwind(|| println!("{:?}", Literal::from_str(s))).is_ok() {
21+
eprintln!("{s} did not panic");
22+
}
23+
}
24+
25+
pub fn run() {
26+
// returns Ok(valid instance)
27+
lit("123");
28+
lit("\"ab\"");
29+
lit("\'b\'");
30+
lit("'b'");
31+
lit("b\"b\"");
32+
lit("c\"b\"");
33+
lit("cr\"b\"");
34+
lit("b'b'");
35+
lit("256u8");
36+
lit("-256u8");
37+
stream("-256u8");
38+
lit("0b11111000000001111i16");
39+
lit("0xf32");
40+
lit("0b0f32");
41+
lit("2E4");
42+
lit("2.2E-4f64");
43+
lit("18u8E");
44+
lit("18.0u8E");
45+
lit("cr#\"// /* // \n */\"#");
46+
lit("'\\''");
47+
lit("'\\\''");
48+
lit(&format!("r{0}\"a\"{0}", "#".repeat(255)));
49+
stream("fn main() { println!(\"Hello, world!\") }");
50+
stream("18.u8E");
51+
stream("18.0f32");
52+
stream("18.0f34");
53+
stream("18.bu8");
54+
stream("3//\n4");
55+
stream(
56+
"\'c\'/*\n
57+
*/",
58+
);
59+
stream("/*a*/ //");
60+
61+
println!("### ERRORS");
62+
63+
// returns Err(LexError)
64+
lit("\'c\'/**/");
65+
lit(" 0");
66+
lit("0 ");
67+
lit("0//");
68+
lit("3//\n4");
69+
lit("18.u8E");
70+
lit("/*a*/ //");
71+
// FIXME: all of the cases below should return an Err and emit no diagnostics, but don't yet.
72+
73+
// emits diagnostics and returns LexError
74+
lit("r'r'");
75+
lit("c'r'");
76+
77+
// emits diagnostic and returns a seemingly valid tokenstream
78+
stream("r'r'");
79+
stream("c'r'");
80+
81+
for (parse, parse_catch_unwind) in [
82+
(stream as fn(&str), stream_catch_unwind as fn(&str)),
83+
(lit, lit_catch_unwind),
84+
] {
85+
// emits diagnostic(s), then panics
86+
parse_catch_unwind("1 ) 2");
87+
parse_catch_unwind("( x [ ) ]");
88+
parse_catch_unwind("r#");
89+
90+
// emits diagnostic(s), then returns Ok(Literal { kind: ErrWithGuar, .. })
91+
parse("0b2");
92+
parse("0bf32");
93+
parse("0b0.0f32");
94+
parse("'\''");
95+
parse(
96+
"'
97+
'",
98+
);
99+
parse_catch_unwind(&format!("r{0}\"a\"{0}", "#".repeat(256)));
100+
101+
// emits diagnostic, then, when parsing as a lit, returns LexError, otherwise ErrWithGuar
102+
parse("/*a*/ 0b2 //");
103+
}
104+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
extern crate proc_macro;
2+
use proc_macro::*;
3+
4+
#[path = "nonfatal-parsing-body.rs"]
5+
mod body;
6+
7+
#[proc_macro]
8+
pub fn run(_: TokenStream) -> TokenStream {
9+
body::run();
10+
TokenStream::new()
11+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ proc-macro: nonfatal-parsing.rs
2+
//@ needs-unwind
3+
//@ edition:2024
4+
//@ dont-require-annotations: ERROR
5+
// FIXME: should be a check-pass test
6+
7+
extern crate proc_macro;
8+
extern crate nonfatal_parsing;
9+
10+
#[path = "auxiliary/nonfatal-parsing-body.rs"]
11+
mod body;
12+
13+
fn main() {
14+
nonfatal_parsing::run!();
15+
// FIXME: enable this once the standalone backend exists
16+
// body::run();
17+
}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
error: prefix `r` is unknown
2+
--> <proc-macro source code>:1:1
3+
|
4+
LL | r'r'
5+
| ^ unknown prefix
6+
|
7+
= note: prefixed identifiers and literals are reserved since Rust 2021
8+
help: consider inserting whitespace here
9+
|
10+
LL | r 'r'
11+
| +
12+
13+
error: prefix `c` is unknown
14+
--> <proc-macro source code>:1:1
15+
|
16+
LL | c'r'
17+
| ^ unknown prefix
18+
|
19+
= note: prefixed identifiers and literals are reserved since Rust 2021
20+
help: consider inserting whitespace here
21+
|
22+
LL | c 'r'
23+
| +
24+
25+
error: unexpected closing delimiter: `)`
26+
--> $DIR/nonfatal-parsing.rs:14:5
27+
|
28+
LL | nonfatal_parsing::run!();
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected closing delimiter
30+
|
31+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
32+
33+
error: unexpected closing delimiter: `]`
34+
--> $DIR/nonfatal-parsing.rs:14:5
35+
|
36+
LL | nonfatal_parsing::run!();
37+
| -^^^^^^^^^^^^^^^^^^^^^^^
38+
| |
39+
| the nearest open delimiter
40+
| missing open `(` for this delimiter
41+
| unexpected closing delimiter
42+
|
43+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
44+
45+
error: found invalid character; only `#` is allowed in raw string delimitation: \u{0}
46+
--> $DIR/nonfatal-parsing.rs:14:5
47+
|
48+
LL | nonfatal_parsing::run!();
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^
50+
|
51+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
52+
53+
error: invalid digit for a base 2 literal
54+
--> $DIR/nonfatal-parsing.rs:14:5
55+
|
56+
LL | nonfatal_parsing::run!();
57+
| ^^^^^^^^^^^^^^^^^^^^^^^^
58+
|
59+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
60+
61+
error[E0768]: no valid digits found for number
62+
--> $DIR/nonfatal-parsing.rs:14:5
63+
|
64+
LL | nonfatal_parsing::run!();
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^
66+
|
67+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
68+
69+
error: binary float literal is not supported
70+
--> $DIR/nonfatal-parsing.rs:14:5
71+
|
72+
LL | nonfatal_parsing::run!();
73+
| ^^^^^^^^^^^^^^^^^^^^^^^^
74+
|
75+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
76+
77+
error: character constant must be escaped: `'`
78+
--> $DIR/nonfatal-parsing.rs:14:5
79+
|
80+
LL | nonfatal_parsing::run!();
81+
| ^^^^^^^^^^^^^^^^^^^^^^^^
82+
|
83+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
84+
help: escape the character
85+
|
86+
LL - nonfatal_parsing::run!();
87+
LL + nonfatal_parsing::run!(\';
88+
|
89+
90+
error: character constant must be escaped: `\n`
91+
--> $DIR/nonfatal-parsing.rs:14:5
92+
|
93+
LL | nonfatal_parsing::run!();
94+
| ^^^^^^^^^^^^^^^^^^^^^^^^
95+
|
96+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
97+
help: escape the character
98+
|
99+
LL - nonfatal_parsing::run!();
100+
LL + nonfatal_parsing::run!(\n;
101+
|
102+
103+
error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
104+
--> $DIR/nonfatal-parsing.rs:14:5
105+
|
106+
LL | nonfatal_parsing::run!();
107+
| ^^^^^^^^^^^^^^^^^^^^^^^^
108+
|
109+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
110+
111+
error: invalid digit for a base 2 literal
112+
--> $DIR/nonfatal-parsing.rs:14:5
113+
|
114+
LL | nonfatal_parsing::run!();
115+
| ^^^^^^^^^^^^^^^^^^^^^^^^
116+
|
117+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
118+
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
119+
120+
error: unexpected closing delimiter: `)`
121+
--> <proc-macro source code>:1:3
122+
|
123+
LL | 1 ) 2
124+
| ^ unexpected closing delimiter
125+
126+
error: unexpected closing delimiter: `]`
127+
--> <proc-macro source code>:1:10
128+
|
129+
LL | ( x [ ) ]
130+
| - - ^ unexpected closing delimiter
131+
| | |
132+
| | missing open `(` for this delimiter
133+
| the nearest open delimiter
134+
135+
error: found invalid character; only `#` is allowed in raw string delimitation: \u{0}
136+
--> <proc-macro source code>:1:1
137+
|
138+
LL | r#
139+
| ^^
140+
141+
error: invalid digit for a base 2 literal
142+
--> <proc-macro source code>:1:3
143+
|
144+
LL | 0b2
145+
| ^
146+
147+
error[E0768]: no valid digits found for number
148+
--> <proc-macro source code>:1:1
149+
|
150+
LL | 0bf32
151+
| ^^
152+
153+
error: binary float literal is not supported
154+
--> <proc-macro source code>:1:1
155+
|
156+
LL | 0b0.0f32
157+
| ^^^^^
158+
159+
error: character constant must be escaped: `'`
160+
--> <proc-macro source code>:1:2
161+
|
162+
LL | '''
163+
| ^
164+
|
165+
help: escape the character
166+
|
167+
LL | '\''
168+
| +
169+
170+
error: character constant must be escaped: `\n`
171+
--> <proc-macro source code>:1:2
172+
|
173+
LL | '
174+
| __^
175+
LL | | '
176+
| |_^
177+
|
178+
help: escape the character
179+
|
180+
LL | '\n'
181+
| ++
182+
183+
error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
184+
--> <proc-macro source code>:1:1
185+
|
186+
LL | r#######################################...##################################################
187+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
188+
189+
error: invalid digit for a base 2 literal
190+
--> <proc-macro source code>:1:9
191+
|
192+
LL | /*a*/ 0b2 //
193+
| ^
194+
195+
error: aborting due to 22 previous errors
196+
197+
For more information about this error, try `rustc --explain E0768`.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: #25 bytes(276..300) })
2+
Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: #25 bytes(276..300) })
3+
Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #25 bytes(276..300) })
4+
Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #25 bytes(276..300) })
5+
Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: #25 bytes(276..300) })
6+
Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: #25 bytes(276..300) })
7+
Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: #25 bytes(276..300) })
8+
Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: #25 bytes(276..300) })
9+
Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #25 bytes(276..300) })
10+
Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: #25 bytes(276..300) })
11+
Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: #25 bytes(276..300) }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #25 bytes(276..300) }])
12+
Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: #25 bytes(276..300) })
13+
Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: #25 bytes(276..300) })
14+
Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: #25 bytes(276..300) })
15+
Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: #25 bytes(276..300) })
16+
Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: #25 bytes(276..300) })
17+
Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: #25 bytes(276..300) })
18+
Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: #25 bytes(276..300) })
19+
Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: #25 bytes(276..300) })
20+
Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #25 bytes(276..300) })
21+
Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #25 bytes(276..300) })
22+
Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: #25 bytes(276..300) })
23+
Ok(TokenStream [Ident { ident: "fn", span: #25 bytes(276..300) }, Ident { ident: "main", span: #25 bytes(276..300) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #25 bytes(276..300) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: #25 bytes(276..300) }, Punct { ch: '!', spacing: Alone, span: #25 bytes(276..300) }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: #25 bytes(276..300) }], span: #25 bytes(276..300) }], span: #25 bytes(276..300) }])
24+
Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #25 bytes(276..300) }, Punct { ch: '.', spacing: Alone, span: #25 bytes(276..300) }, Ident { ident: "u8E", span: #25 bytes(276..300) }])
25+
Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: #25 bytes(276..300) }])
26+
Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: #25 bytes(276..300) }])
27+
Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #25 bytes(276..300) }, Punct { ch: '.', spacing: Alone, span: #25 bytes(276..300) }, Ident { ident: "bu8", span: #25 bytes(276..300) }])
28+
Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: #25 bytes(276..300) }, Literal { kind: Integer, symbol: "4", suffix: None, span: #25 bytes(276..300) }])
29+
Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #25 bytes(276..300) }])
30+
Ok(TokenStream [])
31+
### ERRORS
32+
Err(LexError)
33+
Err(LexError)
34+
Err(LexError)
35+
Err(LexError)
36+
Err(LexError)
37+
Err(LexError)
38+
Err(LexError)
39+
Err(LexError)
40+
Err(LexError)
41+
Ok(TokenStream [Ident { ident: "r", span: #25 bytes(276..300) }, Literal { kind: Char, symbol: "r", suffix: None, span: #25 bytes(276..300) }])
42+
Ok(TokenStream [Ident { ident: "c", span: #25 bytes(276..300) }, Literal { kind: Char, symbol: "r", suffix: None, span: #25 bytes(276..300) }])
43+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #25 bytes(276..300) }])
44+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #25 bytes(276..300) }])
45+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #25 bytes(276..300) }])
46+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #25 bytes(276..300) }])
47+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #25 bytes(276..300) }])
48+
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #25 bytes(276..300) }])
49+
Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #25 bytes(276..300) })
50+
Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #25 bytes(276..300) })
51+
Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #25 bytes(276..300) })
52+
Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #25 bytes(276..300) })
53+
Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #25 bytes(276..300) })
54+
Err(LexError)

0 commit comments

Comments
 (0)