3 #![allow(unused_imports)]
4 // ignore-cross-compile
6 #![feature(rustc_private)]
9 extern crate syntax_expand;
10 extern crate rustc_parse;
11 extern crate rustc_errors;
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;
20 use syntax::sess::ParseSess;
21 use syntax::source_map::{FilePathMapping, FileName};
23 use syntax::print::pprust;
27 // Copied out of syntax::util::parser_testing
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)
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>,
36 let mut p = string_to_parser(&ps, s);
39 if ps.span_diagnostic.has_errors() || p.token != token::Eof {
40 if let Err(mut e) = x {
43 return Err(p.fatal("parse error"));
49 fn expr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P<ast::Expr>> {
50 with_error_checking_parse(s.to_string(), ps, |p| {
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())
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)
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();
71 if expected != actual {
72 panic!("parsed `{}` as {:?}, expected {:?}", e, actual, expected);
76 fn sess() -> ParseSess {
77 ParseSess::new(FilePathMapping::empty())
80 fn check_expr_attrs(es: &str, expected: &[&str]) {
82 let e = expr(es, &ps).expect("parse error");
83 let actual = &e.attrs;
85 &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
87 pprust::attribute_to_string);
90 fn check_stmt_attrs(es: &str, expected: &[&str]) {
92 let e = stmt(es, &ps).expect("parse error");
93 let actual = e.kind.attrs();
95 &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
97 pprust::attribute_to_string);
100 fn reject_expr_parse(es: &str) {
102 match expr(es, &ps) {
103 Ok(_) => panic!("parser did not reject `{}`", es),
104 Err(mut e) => e.cancel(),
108 fn reject_stmt_parse(es: &str) {
110 match stmt(es, &ps) {
111 Ok(_) => panic!("parser did not reject `{}`", es),
112 Err(mut e) => e.cancel(),
117 syntax::with_default_globals(|| run());
121 let both = &["#[attr]", "#![attr]"];
122 let outer = &["#[attr]"];
125 check_expr_attrs("#[attr] box 0", outer);
126 reject_expr_parse("box #![attr] 0");
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]]");
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()");
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);
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");
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");
158 check_expr_attrs("#[attr] false", outer);
159 check_expr_attrs("#[attr] 0", outer);
160 check_expr_attrs("#[attr] 'c'", outer);
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");
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]}");
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]}");
186 check_expr_attrs("#[attr] while true {#![attr]}", both);
188 check_expr_attrs("#[attr] while let Some(false) = true {#![attr]}", both);
190 check_expr_attrs("#[attr] for x in y {#![attr]}", both);
192 check_expr_attrs("#[attr] loop {#![attr]}", both);
194 check_expr_attrs("#[attr] match true {#![attr] #[attr] _ => false}", both);
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}");
207 check_expr_attrs("#[attr] { #![attr] }", both);
208 check_expr_attrs("#[attr] { #![attr] let _ = (); }", both);
209 check_expr_attrs("#[attr] { #![attr] let _ = (); foo }", both);
211 check_expr_attrs("#[attr] x = y", none);
212 check_expr_attrs("#[attr] (x = y)", outer);
214 check_expr_attrs("#[attr] x += y", none);
215 check_expr_attrs("#[attr] (x += y)", outer);
217 check_expr_attrs("#[attr] foo.bar", outer);
218 check_expr_attrs("(#[attr] foo).bar", none);
220 check_expr_attrs("#[attr] foo.0", outer);
221 check_expr_attrs("(#[attr] foo).0", none);
223 check_expr_attrs("#[attr] foo[bar]", outer);
224 check_expr_attrs("(#[attr] foo)[bar]", none);
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] ..");
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);
236 check_expr_attrs("#[attr] foo::bar::baz", outer);
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");
245 check_expr_attrs("#[attr] break", outer);
246 check_expr_attrs("#[attr] continue", outer);
247 check_expr_attrs("#[attr] return", outer);
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);
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);
260 check_expr_attrs("#[attr] (#![attr] 0)", both);
262 // Look at statements in their natural habitat...
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);
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!{}");
284 // FIXME: Allow attributes in pattern constexprs?
285 // note: requires parens in patterns to allow disambiguation
287 reject_expr_parse("match 0 {
290 reject_expr_parse("match 0 {
291 0..=#[attr] -10 => ()
293 reject_expr_parse("match 0 {
294 0..=-#[attr] 10 => ()
296 reject_expr_parse("match 0 {
297 0..=#[attr] FOO => ()
300 // make sure we don't catch this bug again...