]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_lexer/src/tests.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / compiler / rustc_lexer / src / tests.rs
CommitLineData
1b1a35ee
XL
1use super::*;
2
3use expect_test::{expect, Expect};
4
5e7ed085 5fn check_raw_str(s: &str, expected_hashes: u8, expected_err: Option<RawStrError>) {
1b1a35ee
XL
6 let s = &format!("r{}", s);
7 let mut cursor = Cursor::new(s);
8 cursor.bump();
9 let (n_hashes, err) = cursor.raw_double_quoted_string(0);
10 assert_eq!(n_hashes, expected_hashes);
11 assert_eq!(err, expected_err);
12}
13
14#[test]
15fn test_naked_raw_str() {
16 check_raw_str(r#""abc""#, 0, None);
17}
18
19#[test]
20fn test_raw_no_start() {
21 check_raw_str(r##""abc"#"##, 0, None);
22}
23
24#[test]
25fn test_too_many_terminators() {
26 // this error is handled in the parser later
27 check_raw_str(r###"#"abc"##"###, 1, None);
28}
29
30#[test]
31fn test_unterminated() {
32 check_raw_str(
33 r#"#"abc"#,
34 1,
35 Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }),
36 );
37 check_raw_str(
38 r###"##"abc"#"###,
39 2,
40 Some(RawStrError::NoTerminator {
41 expected: 2,
42 found: 1,
43 possible_terminator_offset: Some(7),
44 }),
45 );
46 // We're looking for "# not just any #
47 check_raw_str(
48 r###"##"abc#"###,
49 2,
50 Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }),
51 )
52}
53
54#[test]
55fn test_invalid_start() {
56 check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
57}
58
59#[test]
60fn test_unterminated_no_pound() {
61 // https://github.com/rust-lang/rust/issues/70677
62 check_raw_str(
63 r#"""#,
64 0,
65 Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }),
66 );
67}
68
5e7ed085
FG
69#[test]
70fn test_too_many_hashes() {
71 let max_count = u8::MAX;
72 let mut hashes: String = "#".repeat(max_count.into());
73
74 // Valid number of hashes (255 = 2^8 - 1 = u8::MAX), but invalid string.
75 check_raw_str(&hashes, max_count, Some(RawStrError::InvalidStarter { bad_char: '\u{0}' }));
76
77 // One more hash sign (256 = 2^8) becomes too many.
78 hashes.push('#');
79 check_raw_str(
80 &hashes,
81 0,
82 Some(RawStrError::TooManyDelimiters { found: usize::from(max_count) + 1 }),
83 );
84}
85
1b1a35ee
XL
86#[test]
87fn test_valid_shebang() {
88 // https://github.com/rust-lang/rust/issues/70528
89 let input = "#!/usr/bin/rustrun\nlet x = 5;";
90 assert_eq!(strip_shebang(input), Some(18));
91}
92
93#[test]
94fn test_invalid_shebang_valid_rust_syntax() {
95 // https://github.com/rust-lang/rust/issues/70528
96 let input = "#! [bad_attribute]";
97 assert_eq!(strip_shebang(input), None);
98}
99
100#[test]
101fn test_shebang_second_line() {
102 // Because shebangs are interpreted by the kernel, they must be on the first line
103 let input = "\n#!/bin/bash";
104 assert_eq!(strip_shebang(input), None);
105}
106
107#[test]
108fn test_shebang_space() {
109 let input = "#! /bin/bash";
110 assert_eq!(strip_shebang(input), Some(input.len()));
111}
112
113#[test]
114fn test_shebang_empty_shebang() {
115 let input = "#! \n[attribute(foo)]";
116 assert_eq!(strip_shebang(input), None);
117}
118
119#[test]
120fn test_invalid_shebang_comment() {
121 let input = "#!//bin/ami/a/comment\n[";
122 assert_eq!(strip_shebang(input), None)
123}
124
125#[test]
126fn test_invalid_shebang_another_comment() {
127 let input = "#!/*bin/ami/a/comment*/\n[attribute";
128 assert_eq!(strip_shebang(input), None)
129}
130
131#[test]
132fn test_shebang_valid_rust_after() {
133 let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
134 assert_eq!(strip_shebang(input), Some(23))
135}
136
137#[test]
138fn test_shebang_followed_by_attrib() {
139 let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
140 assert_eq!(strip_shebang(input), Some(19));
141}
142
143fn check_lexing(src: &str, expect: Expect) {
144 let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect();
145 expect.assert_eq(&actual)
146}
147
148#[test]
149fn smoke_test() {
150 check_lexing(
151 "/* my source file */ fn main() { println!(\"zebra\"); }\n",
152 expect![[r#"
153 Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 }
154 Token { kind: Whitespace, len: 1 }
155 Token { kind: Ident, len: 2 }
156 Token { kind: Whitespace, len: 1 }
157 Token { kind: Ident, len: 4 }
158 Token { kind: OpenParen, len: 1 }
159 Token { kind: CloseParen, len: 1 }
160 Token { kind: Whitespace, len: 1 }
161 Token { kind: OpenBrace, len: 1 }
162 Token { kind: Whitespace, len: 1 }
163 Token { kind: Ident, len: 7 }
164 Token { kind: Bang, len: 1 }
165 Token { kind: OpenParen, len: 1 }
166 Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 7 }, len: 7 }
167 Token { kind: CloseParen, len: 1 }
168 Token { kind: Semi, len: 1 }
169 Token { kind: Whitespace, len: 1 }
170 Token { kind: CloseBrace, len: 1 }
171 Token { kind: Whitespace, len: 1 }
172 "#]],
173 )
174}
175
176#[test]
177fn comment_flavors() {
178 check_lexing(
179 r"
180// line
181//// line as well
182/// outer doc line
183//! inner doc line
184/* block */
185/**/
186/*** also block */
187/** outer doc block */
188/*! inner doc block */
189",
190 expect![[r#"
191 Token { kind: Whitespace, len: 1 }
192 Token { kind: LineComment { doc_style: None }, len: 7 }
193 Token { kind: Whitespace, len: 1 }
194 Token { kind: LineComment { doc_style: None }, len: 17 }
195 Token { kind: Whitespace, len: 1 }
196 Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 }
197 Token { kind: Whitespace, len: 1 }
198 Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 }
199 Token { kind: Whitespace, len: 1 }
200 Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
201 Token { kind: Whitespace, len: 1 }
202 Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 }
203 Token { kind: Whitespace, len: 1 }
204 Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 }
205 Token { kind: Whitespace, len: 1 }
206 Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 }
207 Token { kind: Whitespace, len: 1 }
208 Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 }
209 Token { kind: Whitespace, len: 1 }
210 "#]],
211 )
212}
213
214#[test]
215fn nested_block_comments() {
216 check_lexing(
217 "/* /* */ */'a'",
218 expect![[r#"
219 Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
220 Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
221 "#]],
222 )
223}
224
225#[test]
226fn characters() {
227 check_lexing(
228 "'a' ' ' '\\n'",
229 expect![[r#"
230 Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
231 Token { kind: Whitespace, len: 1 }
232 Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
233 Token { kind: Whitespace, len: 1 }
234 Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 }
235 "#]],
236 );
237}
238
239#[test]
240fn lifetime() {
241 check_lexing(
242 "'abc",
243 expect![[r#"
244 Token { kind: Lifetime { starts_with_number: false }, len: 4 }
245 "#]],
246 );
247}
248
249#[test]
250fn raw_string() {
251 check_lexing(
252 "r###\"\"#a\\b\x00c\"\"###",
253 expect![[r#"
254 Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 17 }, len: 17 }
255 "#]],
256 )
257}
258
259#[test]
260fn literal_suffixes() {
261 check_lexing(
262 r####"
263'a'
264b'a'
265"a"
266b"a"
2671234
2680b101
2690xABC
2701.0
2711.0e10
2722us
273r###"raw"###suffix
274br###"raw"###suffix
275"####,
276 expect![[r#"
277 Token { kind: Whitespace, len: 1 }
278 Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
279 Token { kind: Whitespace, len: 1 }
280 Token { kind: Literal { kind: Byte { terminated: true }, suffix_start: 4 }, len: 4 }
281 Token { kind: Whitespace, len: 1 }
282 Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 }
283 Token { kind: Whitespace, len: 1 }
284 Token { kind: Literal { kind: ByteStr { terminated: true }, suffix_start: 4 }, len: 4 }
285 Token { kind: Whitespace, len: 1 }
286 Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 4 }, len: 4 }
287 Token { kind: Whitespace, len: 1 }
288 Token { kind: Literal { kind: Int { base: Binary, empty_int: false }, suffix_start: 5 }, len: 5 }
289 Token { kind: Whitespace, len: 1 }
290 Token { kind: Literal { kind: Int { base: Hexadecimal, empty_int: false }, suffix_start: 5 }, len: 5 }
291 Token { kind: Whitespace, len: 1 }
292 Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 3 }, len: 3 }
293 Token { kind: Whitespace, len: 1 }
294 Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 6 }, len: 6 }
295 Token { kind: Whitespace, len: 1 }
296 Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 1 }, len: 3 }
297 Token { kind: Whitespace, len: 1 }
298 Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 12 }, len: 18 }
299 Token { kind: Whitespace, len: 1 }
300 Token { kind: Literal { kind: RawByteStr { n_hashes: 3, err: None }, suffix_start: 13 }, len: 19 }
301 Token { kind: Whitespace, len: 1 }
302 "#]],
303 )
304}