diff options
| author | Douglas Young <rcxdude@gmail.com> | 2014-02-18 16:14:12 +0000 |
|---|---|---|
| committer | Douglas Young <rcxdude@gmail.com> | 2014-02-18 16:17:51 +0000 |
| commit | 0bdfd0f4c76fa29a4be774937bc72165390b06d6 (patch) | |
| tree | e595de26e0a25bd8b8258a82ef653553c499d42e /src/libsyntax/ext | |
| parent | 517e38997db9f60612676c9f83dab6ed35c1b5df (diff) | |
| download | rust-0bdfd0f4c76fa29a4be774937bc72165390b06d6.tar.gz rust-0bdfd0f4c76fa29a4be774937bc72165390b06d6.zip | |
Avoid returning original macro if expansion fails.
Closes #11692. Instead of returning the original expression, a dummy expression (with identical span) is returned. This prevents infinite loops of failed expansions as well as odd double error messages in certain situations.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/asm.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/bytes.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/concat.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/concat_idents.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/env.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/trace_macros.rs | 2 |
10 files changed, 34 insertions, 28 deletions
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 1a3ebf3ce5d..1bf82573c49 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -64,7 +64,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) "inline assembly must be a string literal.") { Some((s, st)) => (s, st), // let compilation continue - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), }; asm = s; asm_str_style = Some(style); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 3dac82ae3b7..e6fffe8b53f 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -101,6 +101,7 @@ pub trait AnyMacro { fn make_stmt(&self) -> @ast::Stmt; } + pub enum MacResult { MRExpr(@ast::Expr), MRItem(@ast::Item), @@ -112,10 +113,15 @@ impl MacResult { /// type signatures after emitting a non-fatal error (which stop /// compilation well before the validity (or otherwise)) of the /// expression are checked. - pub fn dummy_expr() -> MacResult { - MRExpr(@ast::Expr { - id: ast::DUMMY_NODE_ID, node: ast::ExprLogLevel, span: codemap::DUMMY_SP - }) + pub fn raw_dummy_expr(sp: codemap::Span) -> @ast::Expr { + @ast::Expr { + id: ast::DUMMY_NODE_ID, + node: ast::ExprLogLevel, + span: sp + } + } + pub fn dummy_expr(sp: codemap::Span) -> MacResult { + MRExpr(MacResult::raw_dummy_expr(sp)) } } diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs index 39bb870b969..68aa757c524 100644 --- a/src/libsyntax/ext/bytes.rs +++ b/src/libsyntax/ext/bytes.rs @@ -21,7 +21,7 @@ use std::char; pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult { // Gather all argument expressions let exprs = match get_exprs_from_tts(cx, sp, tts) { - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), Some(e) => e, }; let mut bytes = ~[]; diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index c13f9bf92af..5316b8f7212 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -21,7 +21,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, tts: &[ast::TokenTree]) -> base::MacResult { let es = match base::get_exprs_from_tts(cx, sp, tts) { Some(e) => e, - None => return base::MacResult::dummy_expr() + None => return base::MacResult::dummy_expr(sp) }; let mut accumulator = ~""; for e in es.move_iter() { diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 15e9d31daa0..85cfd4f61e4 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -25,7 +25,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) ast::TTTok(_, token::COMMA) => (), _ => { cx.span_err(sp, "concat_idents! expecting comma."); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } } } else { @@ -35,7 +35,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } _ => { cx.span_err(sp, "concat_idents! requires ident args."); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } } } diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index c23a1ce1e28..fec1e70af07 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -26,7 +26,7 @@ use std::os; pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult { let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") { - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), Some(v) => v }; @@ -42,14 +42,14 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let exprs = match get_exprs_from_tts(cx, sp, tts) { Some([]) => { cx.span_err(sp, "env! takes 1 or 2 arguments"); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), Some(exprs) => exprs }; let var = match expr_to_str(cx, exprs[0], "expected string literal") { - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), Some((v, _style)) => v }; let msg = match exprs.len() { @@ -60,13 +60,13 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } 2 => { match expr_to_str(cx, exprs[1], "expected string literal") { - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), Some((s, _style)) => s } } _ => { cx.span_err(sp, "env! takes 1 or 2 arguments"); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } }; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 97766e1a14b..4b81713f7d0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -51,7 +51,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { format!("expected macro name without module \ separators")); // let compilation continue - return e; + return MacResult::raw_dummy_expr(e.span); } let extname = pth.segments[0].identifier; let extnamestr = token::get_ident(extname); @@ -64,7 +64,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { extnamestr.get())); // let compilation continue - return e; + return MacResult::raw_dummy_expr(e.span); } Some(&NormalTT(ref expandfun, exp_span)) => { fld.cx.bt_push(ExpnInfo { @@ -98,7 +98,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { extnamestr.get() ) ); - return e; + return MacResult::raw_dummy_expr(e.span); } }; @@ -111,7 +111,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { format!("'{}' is not a tt-style macro", extnamestr.get()) ); - return e; + return MacResult::raw_dummy_expr(e.span); } }; diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 01d348595b8..13b1afb4c00 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -811,7 +811,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, expr, "format argument must be a string literal.") { Some((fmt, _)) => fmt, - None => return efmt + None => return MacResult::raw_dummy_expr(sp) }; let mut parser = parse::Parser::new(fmt.get()); @@ -829,7 +829,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, match parser.errors.shift() { Some(error) => { cx.ecx.span_err(efmt.span, "invalid format string: " + error); - return efmt; + return MacResult::raw_dummy_expr(sp); } None => {} } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 150f054b2af..c81ee55c237 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -83,7 +83,7 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult { let file = match get_single_str_from_tts(cx, sp, tts, "include!") { Some(f) => f, - None => return MacResult::dummy_expr(), + None => return MacResult::dummy_expr(sp), }; // The file will be added to the code map by the parser let mut p = @@ -101,13 +101,13 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult { let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") { Some(f) => f, - None => return MacResult::dummy_expr() + None => return MacResult::dummy_expr(sp) }; let file = res_rel_file(cx, sp, &Path::new(file)); let bytes = match File::open(&file).read_to_end() { Err(e) => { cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } Ok(bytes) => bytes, }; @@ -123,7 +123,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } None => { cx.span_err(sp, format!("{} wasn't a utf-8 file", file.display())); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } } } @@ -133,13 +133,13 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) { let file = match get_single_str_from_tts(cx, sp, tts, "include_bin!") { Some(f) => f, - None => return MacResult::dummy_expr() + None => return MacResult::dummy_expr(sp) }; let file = res_rel_file(cx, sp, &Path::new(file)); match File::open(&file).read_to_end() { Err(e) => { cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - return MacResult::dummy_expr(); + return MacResult::dummy_expr(sp); } Ok(bytes) => { base::MRExpr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes)))) diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index 4189ea6a967..db2c9dcddb6 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -33,7 +33,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, cx.set_trace_macros(false); } else { cx.span_err(sp, "trace_macros! only accepts `true` or `false`"); - return base::MacResult::dummy_expr(); + return base::MacResult::dummy_expr(sp); } rust_parser.bump(); |
