]> git.lizzy.rs Git - rust.git/blob - src/libsyntax_ext/assert.rs
Refactor mod/check (part vii)
[rust.git] / src / libsyntax_ext / assert.rs
1 // Copyright 2018 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 use syntax::ast::*;
12 use syntax::codemap::Spanned;
13 use syntax::ext::base::*;
14 use syntax::ext::build::AstBuilder;
15 use syntax::parse::token;
16 use syntax::print::pprust;
17 use syntax::symbol::Symbol;
18 use syntax::tokenstream::{TokenStream, TokenTree};
19 use syntax_pos::{Span, DUMMY_SP};
20
21 pub fn expand_assert<'cx>(
22     cx: &'cx mut ExtCtxt,
23     sp: Span,
24     tts: &[TokenTree],
25 ) -> Box<dyn MacResult + 'cx> {
26     let mut parser = cx.new_parser_from_tts(tts);
27     let cond_expr = panictry!(parser.parse_expr());
28     let custom_msg_args = if parser.eat(&token::Comma) {
29         let ts = parser.parse_tokens();
30         if !ts.is_empty() {
31             Some(ts)
32         } else {
33             None
34         }
35     } else {
36         None
37     };
38
39     let sp = sp.apply_mark(cx.current_expansion.mark);
40     let panic_call = Mac_ {
41         path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)),
42         tts: if let Some(ts) = custom_msg_args {
43             ts.into()
44         } else {
45             TokenStream::from(TokenTree::Token(
46                 DUMMY_SP,
47                 token::Literal(
48                     token::Lit::Str_(Name::intern(&format!(
49                         "assertion failed: {}",
50                         pprust::expr_to_string(&cond_expr).escape_debug()
51                     ))),
52                     None,
53                 ),
54             )).into()
55         },
56         delim: MacDelimiter::Parenthesis,
57     };
58     let if_expr = cx.expr_if(
59         sp,
60         cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)),
61         cx.expr(
62             sp,
63             ExprKind::Mac(Spanned {
64                 span: sp,
65                 node: panic_call,
66             }),
67         ),
68         None,
69     );
70     MacEager::expr(if_expr)
71 }