]> git.lizzy.rs Git - rust.git/blob - src/test/ui-fulldeps/ast_stmt_expr_attr.rs
Simplify Cache wrapper to single type, impl Deref on it, fix all compilation errors...
[rust.git] / src / test / ui-fulldeps / ast_stmt_expr_attr.rs
1 // run-pass
2
3 #![allow(unused_imports)]
4 // ignore-cross-compile
5
6 #![feature(rustc_private)]
7
8 extern crate syntax;
9 extern crate syntax_expand;
10 extern crate rustc_parse;
11 extern crate rustc_errors;
12
13 use rustc_errors::PResult;
14 use rustc_parse::parser::attr::*;
15 use rustc_parse::new_parser_from_source_str;
16 use rustc_parse::parser::Parser;
17 use syntax::ast::*;
18 use syntax::attr::*;
19 use syntax::ast;
20 use syntax::sess::ParseSess;
21 use syntax::source_map::{FilePathMapping, FileName};
22 use syntax::ptr::P;
23 use syntax::print::pprust;
24 use syntax::token;
25 use std::fmt;
26
27 // Copied out of syntax::util::parser_testing
28
29 pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
30     new_parser_from_source_str(ps, FileName::Custom(source_str.clone()), source_str)
31 }
32
33 fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where
34     F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
35 {
36     let mut p = string_to_parser(&ps, s);
37     let x = f(&mut p);
38
39     if ps.span_diagnostic.has_errors() || p.token != token::Eof {
40         if let Err(mut e) = x {
41             e.cancel();
42         }
43         return Err(p.fatal("parse error"));
44     }
45
46     x
47 }
48
49 fn expr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P<ast::Expr>> {
50     with_error_checking_parse(s.to_string(), ps, |p| {
51         p.parse_expr()
52     })
53 }
54
55 fn stmt<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Stmt> {
56     with_error_checking_parse(s.to_string(), ps, |p| {
57         p.parse_stmt().map(|s| s.unwrap())
58     })
59 }
60
61 fn attr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Attribute> {
62     with_error_checking_parse(s.to_string(), ps, |p| {
63         p.parse_attribute(true)
64     })
65 }
66
67 fn str_compare<T, F: Fn(&T) -> String>(e: &str, expected: &[T], actual: &[T], f: F) {
68     let expected: Vec<_> = expected.iter().map(|e| f(e)).collect();
69     let actual: Vec<_> = actual.iter().map(|e| f(e)).collect();
70
71     if expected != actual {
72         panic!("parsed `{}` as {:?}, expected {:?}", e, actual, expected);
73     }
74 }
75
76 fn sess() -> ParseSess {
77     ParseSess::new(FilePathMapping::empty())
78 }
79
80 fn check_expr_attrs(es: &str, expected: &[&str]) {
81     let ps = sess();
82     let e = expr(es, &ps).expect("parse error");
83     let actual = &e.attrs;
84     str_compare(es,
85                 &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
86                 &actual,
87                 pprust::attribute_to_string);
88 }
89
90 fn check_stmt_attrs(es: &str, expected: &[&str]) {
91     let ps = sess();
92     let e = stmt(es, &ps).expect("parse error");
93     let actual = e.kind.attrs();
94     str_compare(es,
95                 &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
96                 actual,
97                 pprust::attribute_to_string);
98 }
99
100 fn reject_expr_parse(es: &str) {
101     let ps = sess();
102     match expr(es, &ps) {
103         Ok(_) => panic!("parser did not reject `{}`", es),
104         Err(mut e) => e.cancel(),
105     };
106 }
107
108 fn reject_stmt_parse(es: &str) {
109     let ps = sess();
110     match stmt(es, &ps) {
111         Ok(_) => panic!("parser did not reject `{}`", es),
112         Err(mut e) => e.cancel(),
113     };
114 }
115
116 fn main() {
117     syntax::with_default_globals(|| run());
118 }
119
120 fn run() {
121     let both = &["#[attr]", "#![attr]"];
122     let outer = &["#[attr]"];
123     let none = &[];
124
125     check_expr_attrs("#[attr] box 0", outer);
126     reject_expr_parse("box #![attr] 0");
127
128     check_expr_attrs("#[attr] [#![attr]]", both);
129     check_expr_attrs("#[attr] [#![attr] 0]", both);
130     check_expr_attrs("#[attr] [#![attr] 0; 0]", both);
131     check_expr_attrs("#[attr] [#![attr] 0, 0, 0]", both);
132     reject_expr_parse("[#[attr]]");
133
134     check_expr_attrs("#[attr] foo()", outer);
135     check_expr_attrs("#[attr] x.foo()", outer);
136     reject_expr_parse("foo#[attr]()");
137     reject_expr_parse("foo(#![attr])");
138     reject_expr_parse("x.foo(#![attr])");
139     reject_expr_parse("x.#[attr]foo()");
140     reject_expr_parse("x.#![attr]foo()");
141
142     check_expr_attrs("#[attr] (#![attr])", both);
143     check_expr_attrs("#[attr] (#![attr] #[attr] 0,)", both);
144     check_expr_attrs("#[attr] (#![attr] #[attr] 0, 0)", both);
145
146     check_expr_attrs("#[attr] 0 + #[attr] 0", none);
147     check_expr_attrs("#[attr] 0 / #[attr] 0", none);
148     check_expr_attrs("#[attr] 0 & #[attr] 0", none);
149     check_expr_attrs("#[attr] 0 % #[attr] 0", none);
150     check_expr_attrs("#[attr] (0 + 0)", outer);
151     reject_expr_parse("0 + #![attr] 0");
152
153     check_expr_attrs("#[attr] !0", outer);
154     check_expr_attrs("#[attr] -0", outer);
155     reject_expr_parse("!#![attr] 0");
156     reject_expr_parse("-#![attr] 0");
157
158     check_expr_attrs("#[attr] false", outer);
159     check_expr_attrs("#[attr] 0", outer);
160     check_expr_attrs("#[attr] 'c'", outer);
161
162     check_expr_attrs("#[attr] x as Y", none);
163     check_expr_attrs("#[attr] (x as Y)", outer);
164     reject_expr_parse("x #![attr] as Y");
165
166     reject_expr_parse("#[attr] if false {}");
167     reject_expr_parse("if false #[attr] {}");
168     reject_expr_parse("if false {#![attr]}");
169     reject_expr_parse("if false {} #[attr] else {}");
170     reject_expr_parse("if false {} else #[attr] {}");
171     reject_expr_parse("if false {} else {#![attr]}");
172     reject_expr_parse("if false {} else #[attr] if true {}");
173     reject_expr_parse("if false {} else if true #[attr] {}");
174     reject_expr_parse("if false {} else if true {#![attr]}");
175
176     reject_expr_parse("#[attr] if let Some(false) = false {}");
177     reject_expr_parse("if let Some(false) = false #[attr] {}");
178     reject_expr_parse("if let Some(false) = false {#![attr]}");
179     reject_expr_parse("if let Some(false) = false {} #[attr] else {}");
180     reject_expr_parse("if let Some(false) = false {} else #[attr] {}");
181     reject_expr_parse("if let Some(false) = false {} else {#![attr]}");
182     reject_expr_parse("if let Some(false) = false {} else #[attr] if let Some(false) = true {}");
183     reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true #[attr] {}");
184     reject_expr_parse("if let Some(false) = false {} else if let Some(false) = true {#![attr]}");
185
186     check_expr_attrs("#[attr] while true {#![attr]}", both);
187
188     check_expr_attrs("#[attr] while let Some(false) = true {#![attr]}", both);
189
190     check_expr_attrs("#[attr] for x in y {#![attr]}", both);
191
192     check_expr_attrs("#[attr] loop {#![attr]}", both);
193
194     check_expr_attrs("#[attr] match true {#![attr] #[attr] _ => false}", both);
195
196     check_expr_attrs("#[attr]      || #[attr] foo", outer);
197     check_expr_attrs("#[attr] move || #[attr] foo", outer);
198     check_expr_attrs("#[attr]      || #[attr] { #![attr] foo }", outer);
199     check_expr_attrs("#[attr] move || #[attr] { #![attr] foo }", outer);
200     check_expr_attrs("#[attr]      || { #![attr] foo }", outer);
201     check_expr_attrs("#[attr] move || { #![attr] foo }", outer);
202     reject_expr_parse("|| #![attr] foo");
203     reject_expr_parse("move || #![attr] foo");
204     reject_expr_parse("|| #![attr] {foo}");
205     reject_expr_parse("move || #![attr] {foo}");
206
207     check_expr_attrs("#[attr] { #![attr] }", both);
208     check_expr_attrs("#[attr] { #![attr] let _ = (); }", both);
209     check_expr_attrs("#[attr] { #![attr] let _ = (); foo }", both);
210
211     check_expr_attrs("#[attr] x = y", none);
212     check_expr_attrs("#[attr] (x = y)", outer);
213
214     check_expr_attrs("#[attr] x += y", none);
215     check_expr_attrs("#[attr] (x += y)", outer);
216
217     check_expr_attrs("#[attr] foo.bar", outer);
218     check_expr_attrs("(#[attr] foo).bar", none);
219
220     check_expr_attrs("#[attr] foo.0", outer);
221     check_expr_attrs("(#[attr] foo).0", none);
222
223     check_expr_attrs("#[attr] foo[bar]", outer);
224     check_expr_attrs("(#[attr] foo)[bar]", none);
225
226     check_expr_attrs("#[attr] 0..#[attr] 0", none);
227     check_expr_attrs("#[attr] 0..", none);
228     reject_expr_parse("#[attr] ..#[attr] 0");
229     reject_expr_parse("#[attr] ..");
230
231     check_expr_attrs("#[attr] (0..0)", outer);
232     check_expr_attrs("#[attr] (0..)", outer);
233     check_expr_attrs("#[attr] (..0)", outer);
234     check_expr_attrs("#[attr] (..)", outer);
235
236     check_expr_attrs("#[attr] foo::bar::baz", outer);
237
238     check_expr_attrs("#[attr] &0", outer);
239     check_expr_attrs("#[attr] &mut 0", outer);
240     check_expr_attrs("#[attr] & #[attr] 0", outer);
241     check_expr_attrs("#[attr] &mut #[attr] 0", outer);
242     reject_expr_parse("#[attr] &#![attr] 0");
243     reject_expr_parse("#[attr] &mut #![attr] 0");
244
245     check_expr_attrs("#[attr] break", outer);
246     check_expr_attrs("#[attr] continue", outer);
247     check_expr_attrs("#[attr] return", outer);
248
249     check_expr_attrs("#[attr] foo!()", outer);
250     check_expr_attrs("#[attr] foo!(#![attr])", outer);
251     check_expr_attrs("#[attr] foo![]", outer);
252     check_expr_attrs("#[attr] foo![#![attr]]", outer);
253     check_expr_attrs("#[attr] foo!{}", outer);
254     check_expr_attrs("#[attr] foo!{#![attr]}", outer);
255
256     check_expr_attrs("#[attr] Foo { #![attr] bar: baz }", both);
257     check_expr_attrs("#[attr] Foo { #![attr] ..foo }", both);
258     check_expr_attrs("#[attr] Foo { #![attr] bar: baz, ..foo }", both);
259
260     check_expr_attrs("#[attr] (#![attr] 0)", both);
261
262     // Look at statements in their natural habitat...
263     check_expr_attrs("{
264         #[attr] let _ = 0;
265         #[attr] 0;
266         #[attr] foo!();
267         #[attr] foo!{}
268         #[attr] foo![];
269     }", none);
270
271     check_stmt_attrs("#[attr] let _ = 0", outer);
272     check_stmt_attrs("#[attr] 0",         outer);
273     check_stmt_attrs("#[attr] {#![attr]}", both);
274     check_stmt_attrs("#[attr] foo!()",    outer);
275     check_stmt_attrs("#[attr] foo![]",    outer);
276     check_stmt_attrs("#[attr] foo!{}",    outer);
277
278     reject_stmt_parse("#[attr] #![attr] let _ = 0");
279     reject_stmt_parse("#[attr] #![attr] 0");
280     reject_stmt_parse("#[attr] #![attr] foo!()");
281     reject_stmt_parse("#[attr] #![attr] foo![]");
282     reject_stmt_parse("#[attr] #![attr] foo!{}");
283
284     // FIXME: Allow attributes in pattern constexprs?
285     // note: requires parens in patterns to allow disambiguation
286
287     reject_expr_parse("match 0 {
288         0..=#[attr] 10 => ()
289     }");
290     reject_expr_parse("match 0 {
291         0..=#[attr] -10 => ()
292     }");
293     reject_expr_parse("match 0 {
294         0..=-#[attr] 10 => ()
295     }");
296     reject_expr_parse("match 0 {
297         0..=#[attr] FOO => ()
298     }");
299
300     // make sure we don't catch this bug again...
301     reject_expr_parse("{
302         fn foo() {
303             #[attr];
304         }
305     }");
306     reject_expr_parse("{
307         fn foo() {
308             #[attr]
309         }
310     }");
311 }