]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
Rollup merge of #40254 - nagisa:compiler-builtin-no-panic, r=alexcrichton
[rust.git] / src / test / run-pass-fulldeps / auxiliary / procedural_mbe_matching.rs
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 // force-host
12
13 #![crate_type="dylib"]
14 #![feature(plugin_registrar, quote, rustc_private)]
15
16 extern crate syntax;
17 extern crate syntax_pos;
18 extern crate rustc;
19 extern crate rustc_plugin;
20
21 use syntax::parse::token::{NtExpr, NtPat};
22 use syntax::ast::{Ident, Pat};
23 use syntax::tokenstream::{TokenTree};
24 use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
25 use syntax::ext::build::AstBuilder;
26 use syntax::ext::tt::quoted;
27 use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
28 use syntax::ext::tt::macro_parser::{Success, Failure, Error};
29 use syntax::ext::tt::macro_parser::parse_failure_msg;
30 use syntax::ptr::P;
31 use syntax_pos::Span;
32 use rustc_plugin::Registry;
33
34 fn expand_mbe_matches(cx: &mut ExtCtxt, _: Span, args: &[TokenTree])
35         -> Box<MacResult + 'static> {
36
37     let mbe_matcher = quote_tokens!(cx, $$matched:expr, $$($$pat:pat)|+);
38     let mbe_matcher = quoted::parse(mbe_matcher.into_iter().collect(), true, cx.parse_sess);
39     let map = match TokenTree::parse(cx, &mbe_matcher, args.iter().cloned().collect()) {
40         Success(map) => map,
41         Failure(_, tok) => {
42             panic!("expected Success, but got Failure: {}", parse_failure_msg(tok));
43         }
44         Error(_, s) => {
45             panic!("expected Success, but got Error: {}", s);
46         }
47     };
48
49     let matched_nt = match *map[&Ident::from_str("matched")] {
50         MatchedNonterminal(ref nt) => nt.clone(),
51         _ => unreachable!(),
52     };
53
54     let mac_expr = match (&*matched_nt, &*map[&Ident::from_str("pat")]) {
55         (&NtExpr(ref matched_expr), &MatchedSeq(ref pats, seq_sp)) => {
56             let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt| {
57                 match **pat_nt {
58                     MatchedNonterminal(ref nt) => match **nt {
59                         NtPat(ref pat) => pat.clone(),
60                         _ => unreachable!(),
61                     },
62                     _ => unreachable!(),
63                 }
64             }).collect();
65             let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true));
66
67             quote_expr!(cx,
68                 match $matched_expr {
69                     $arm
70                     _ => false
71                 }
72             )
73         }
74         _ => unreachable!()
75     };
76
77     MacEager::expr(mac_expr)
78 }
79
80 #[plugin_registrar]
81 pub fn plugin_registrar(reg: &mut Registry) {
82     reg.register_macro("matches", expand_mbe_matches);
83 }