diff options
| author | Steven Fackler <sfackler@gmail.com> | 2014-03-02 13:38:44 -0800 |
|---|---|---|
| committer | Steven Fackler <sfackler@gmail.com> | 2014-03-02 14:12:02 -0800 |
| commit | a0e54c77612faa9008f95a136ed1674dfcf494ef (patch) | |
| tree | 9538bd363a1f57d13d755cf570ddeb6d55ed1513 /src/libsyntax/ext/base.rs | |
| parent | 25431774a933a3b0c5212ea45150660544dec1ec (diff) | |
| download | rust-a0e54c77612faa9008f95a136ed1674dfcf494ef.tar.gz rust-a0e54c77612faa9008f95a136ed1674dfcf494ef.zip | |
Expand string literals and exprs inside of macros
A couple of syntax extensions manually expanded expressions, but it wasn't done universally, most noticably inside of asm!(). There's also a bit of random cleanup.
Diffstat (limited to 'src/libsyntax/ext/base.rs')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index e9fe21eded6..5cb09ec8232 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -405,11 +405,13 @@ impl<'a> ExtCtxt<'a> { } } -/// Extract a string literal from `expr`, emitting `err_msg` if `expr` -/// is not a string literal. This does not stop compilation on error, -/// merely emits a non-fatal error and returns None. -pub fn expr_to_str(cx: &ExtCtxt, expr: @ast::Expr, err_msg: &str) +/// Extract a string literal from the macro expanded version of `expr`, +/// emitting `err_msg` if `expr` is not a string literal. This does not stop +/// compilation on error, merely emits a non-fatal error and returns None. +pub fn expr_to_str(cx: &mut ExtCtxt, expr: @ast::Expr, err_msg: &str) -> Option<(InternedString, ast::StrStyle)> { + // we want to be able to handle e.g. concat("foo", "bar") + let expr = cx.expand_expr(expr); match expr.node { ast::ExprLit(l) => match l.node { ast::LitStr(ref s, style) => return Some(((*s).clone(), style)), @@ -457,7 +459,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt, /// Extract comma-separated expressions from `tts`. If there is a /// parsing error, emit a non-fatal error and return None. -pub fn get_exprs_from_tts(cx: &ExtCtxt, +pub fn get_exprs_from_tts(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Option<Vec<@ast::Expr> > { let mut p = parse::new_parser_from_tts(cx.parse_sess(), @@ -471,7 +473,7 @@ pub fn get_exprs_from_tts(cx: &ExtCtxt, cx.span_err(sp, "expected token: `,`"); return None; } - es.push(p.parse_expr()); + es.push(cx.expand_expr(p.parse_expr())); } Some(es) } @@ -482,9 +484,6 @@ pub fn get_exprs_from_tts(cx: &ExtCtxt, // This environment maps Names to SyntaxExtensions. -// Actually, the following implementation is parameterized -// by both key and value types. - //impl question: how to implement it? Initially, the // env will contain only macros, so it might be painful // to add an empty frame for every context. Let's just @@ -500,14 +499,6 @@ struct MapChainFrame { map: HashMap<Name, SyntaxExtension>, } -#[unsafe_destructor] -impl Drop for MapChainFrame { - fn drop(&mut self) { - // make sure that syntax extension dtors run before we drop the libs - self.map.clear(); - } -} - // Only generic to make it easy to test pub struct SyntaxEnv { priv chain: Vec<MapChainFrame> , |
