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