]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_lexer/src/tests.rs
Rollup merge of #83438 - CDirkx:releases, r=Mark-Simulacrum
[rust.git] / compiler / rustc_lexer / src / tests.rs
1 use super::*;
2
3 use expect_test::{expect, Expect};
4
5 fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
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]
15 fn test_naked_raw_str() {
16     check_raw_str(r#""abc""#, 0, None);
17 }
18
19 #[test]
20 fn test_raw_no_start() {
21     check_raw_str(r##""abc"#"##, 0, None);
22 }
23
24 #[test]
25 fn 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]
31 fn 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]
55 fn test_invalid_start() {
56     check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
57 }
58
59 #[test]
60 fn 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
69 #[test]
70 fn test_valid_shebang() {
71     // https://github.com/rust-lang/rust/issues/70528
72     let input = "#!/usr/bin/rustrun\nlet x = 5;";
73     assert_eq!(strip_shebang(input), Some(18));
74 }
75
76 #[test]
77 fn test_invalid_shebang_valid_rust_syntax() {
78     // https://github.com/rust-lang/rust/issues/70528
79     let input = "#!    [bad_attribute]";
80     assert_eq!(strip_shebang(input), None);
81 }
82
83 #[test]
84 fn test_shebang_second_line() {
85     // Because shebangs are interpreted by the kernel, they must be on the first line
86     let input = "\n#!/bin/bash";
87     assert_eq!(strip_shebang(input), None);
88 }
89
90 #[test]
91 fn test_shebang_space() {
92     let input = "#!    /bin/bash";
93     assert_eq!(strip_shebang(input), Some(input.len()));
94 }
95
96 #[test]
97 fn test_shebang_empty_shebang() {
98     let input = "#!    \n[attribute(foo)]";
99     assert_eq!(strip_shebang(input), None);
100 }
101
102 #[test]
103 fn test_invalid_shebang_comment() {
104     let input = "#!//bin/ami/a/comment\n[";
105     assert_eq!(strip_shebang(input), None)
106 }
107
108 #[test]
109 fn test_invalid_shebang_another_comment() {
110     let input = "#!/*bin/ami/a/comment*/\n[attribute";
111     assert_eq!(strip_shebang(input), None)
112 }
113
114 #[test]
115 fn test_shebang_valid_rust_after() {
116     let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
117     assert_eq!(strip_shebang(input), Some(23))
118 }
119
120 #[test]
121 fn test_shebang_followed_by_attrib() {
122     let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
123     assert_eq!(strip_shebang(input), Some(19));
124 }
125
126 fn check_lexing(src: &str, expect: Expect) {
127     let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect();
128     expect.assert_eq(&actual)
129 }
130
131 #[test]
132 fn smoke_test() {
133     check_lexing(
134         "/* my source file */ fn main() { println!(\"zebra\"); }\n",
135         expect![[r#"
136             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 }
137             Token { kind: Whitespace, len: 1 }
138             Token { kind: Ident, len: 2 }
139             Token { kind: Whitespace, len: 1 }
140             Token { kind: Ident, len: 4 }
141             Token { kind: OpenParen, len: 1 }
142             Token { kind: CloseParen, len: 1 }
143             Token { kind: Whitespace, len: 1 }
144             Token { kind: OpenBrace, len: 1 }
145             Token { kind: Whitespace, len: 1 }
146             Token { kind: Ident, len: 7 }
147             Token { kind: Bang, len: 1 }
148             Token { kind: OpenParen, len: 1 }
149             Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 7 }, len: 7 }
150             Token { kind: CloseParen, len: 1 }
151             Token { kind: Semi, len: 1 }
152             Token { kind: Whitespace, len: 1 }
153             Token { kind: CloseBrace, len: 1 }
154             Token { kind: Whitespace, len: 1 }
155         "#]],
156     )
157 }
158
159 #[test]
160 fn comment_flavors() {
161     check_lexing(
162         r"
163 // line
164 //// line as well
165 /// outer doc line
166 //! inner doc line
167 /* block */
168 /**/
169 /*** also block */
170 /** outer doc block */
171 /*! inner doc block */
172 ",
173         expect![[r#"
174             Token { kind: Whitespace, len: 1 }
175             Token { kind: LineComment { doc_style: None }, len: 7 }
176             Token { kind: Whitespace, len: 1 }
177             Token { kind: LineComment { doc_style: None }, len: 17 }
178             Token { kind: Whitespace, len: 1 }
179             Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 }
180             Token { kind: Whitespace, len: 1 }
181             Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 }
182             Token { kind: Whitespace, len: 1 }
183             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
184             Token { kind: Whitespace, len: 1 }
185             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 }
186             Token { kind: Whitespace, len: 1 }
187             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 }
188             Token { kind: Whitespace, len: 1 }
189             Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 }
190             Token { kind: Whitespace, len: 1 }
191             Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 }
192             Token { kind: Whitespace, len: 1 }
193         "#]],
194     )
195 }
196
197 #[test]
198 fn nested_block_comments() {
199     check_lexing(
200         "/* /* */ */'a'",
201         expect![[r#"
202             Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
203             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
204         "#]],
205     )
206 }
207
208 #[test]
209 fn characters() {
210     check_lexing(
211         "'a' ' ' '\\n'",
212         expect![[r#"
213             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
214             Token { kind: Whitespace, len: 1 }
215             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
216             Token { kind: Whitespace, len: 1 }
217             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 }
218         "#]],
219     );
220 }
221
222 #[test]
223 fn lifetime() {
224     check_lexing(
225         "'abc",
226         expect![[r#"
227             Token { kind: Lifetime { starts_with_number: false }, len: 4 }
228         "#]],
229     );
230 }
231
232 #[test]
233 fn raw_string() {
234     check_lexing(
235         "r###\"\"#a\\b\x00c\"\"###",
236         expect![[r#"
237             Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 17 }, len: 17 }
238         "#]],
239     )
240 }
241
242 #[test]
243 fn literal_suffixes() {
244     check_lexing(
245         r####"
246 'a'
247 b'a'
248 "a"
249 b"a"
250 1234
251 0b101
252 0xABC
253 1.0
254 1.0e10
255 2us
256 r###"raw"###suffix
257 br###"raw"###suffix
258 "####,
259         expect![[r#"
260             Token { kind: Whitespace, len: 1 }
261             Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
262             Token { kind: Whitespace, len: 1 }
263             Token { kind: Literal { kind: Byte { terminated: true }, suffix_start: 4 }, len: 4 }
264             Token { kind: Whitespace, len: 1 }
265             Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 }
266             Token { kind: Whitespace, len: 1 }
267             Token { kind: Literal { kind: ByteStr { terminated: true }, suffix_start: 4 }, len: 4 }
268             Token { kind: Whitespace, len: 1 }
269             Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 4 }, len: 4 }
270             Token { kind: Whitespace, len: 1 }
271             Token { kind: Literal { kind: Int { base: Binary, empty_int: false }, suffix_start: 5 }, len: 5 }
272             Token { kind: Whitespace, len: 1 }
273             Token { kind: Literal { kind: Int { base: Hexadecimal, empty_int: false }, suffix_start: 5 }, len: 5 }
274             Token { kind: Whitespace, len: 1 }
275             Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 3 }, len: 3 }
276             Token { kind: Whitespace, len: 1 }
277             Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 6 }, len: 6 }
278             Token { kind: Whitespace, len: 1 }
279             Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 1 }, len: 3 }
280             Token { kind: Whitespace, len: 1 }
281             Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 12 }, len: 18 }
282             Token { kind: Whitespace, len: 1 }
283             Token { kind: Literal { kind: RawByteStr { n_hashes: 3, err: None }, suffix_start: 13 }, len: 19 }
284             Token { kind: Whitespace, len: 1 }
285         "#]],
286     )
287 }