diff options
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/asm.rs | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 072be571221..e5c6a17c78b 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -19,8 +19,8 @@ use syntax::codemap::Span; use syntax::ext::base; use syntax::ext::base::*; use syntax::feature_gate; -use syntax::parse::token::{intern, InternedString}; -use syntax::parse::token; +use syntax::parse::token::intern; +use syntax::parse::{self, token}; use syntax::ptr::P; use syntax::ast::AsmDialect; @@ -58,8 +58,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) return DummyResult::expr(sp); } - let mut p = cx.new_parser_from_tts(tts); - let mut asm = InternedString::new(""); + // Split the tts before the first colon, to avoid `asm!("x": y)` being + // parsed as `asm!(z)` with `z = "x": y` which is type ascription. + let first_colon = tts.iter().position(|tt| { + match *tt { + ast::TokenTree::Token(_, token::Colon) | + ast::TokenTree::Token(_, token::ModSep) => true, + _ => false + } + }).unwrap_or(tts.len()); + let mut p = cx.new_parser_from_tts(&tts[first_colon..]); + let mut asm = token::InternedString::new(""); let mut asm_str_style = None; let mut outputs = Vec::new(); let mut inputs = Vec::new(); @@ -79,12 +88,22 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) cx.span_err(sp, "malformed inline assembly"); return DummyResult::expr(sp); } - let (s, style) = match expr_to_string(cx, panictry!(p.parse_expr()), + // Nested parser, stop before the first colon (see above). + let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]); + let (s, style) = match expr_to_string(cx, panictry!(p2.parse_expr()), "inline assembly must be a string literal") { Some((s, st)) => (s, st), // let compilation continue None => return DummyResult::expr(sp), }; + + // This is most likely malformed. + if p2.token != token::Eof { + let mut extra_tts = panictry!(p2.parse_all_token_trees()); + extra_tts.extend(tts[first_colon..].iter().cloned()); + p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg()); + } + asm = s; asm_str_style = Some(style); } |
