about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-05-13 12:07:11 +0000
committerbors <bors@rust-lang.org>2015-05-13 12:07:11 +0000
commiteb4cb6d16d142a4e810d1f1df0bab26542caa155 (patch)
treec310e5f476897641866e47c3cfa3ee629be3bd8d /src/libsyntax
parent67433c1a309d3c9457e49f15e80a2d927d165996 (diff)
parentedb2ee510b08b0fadedd3cb56b188cf69ecf2a6a (diff)
downloadrust-eb4cb6d16d142a4e810d1f1df0bab26542caa155.tar.gz
rust-eb4cb6d16d142a4e810d1f1df0bab26542caa155.zip
Auto merge of #25318 - nrc:for-expn, r=sfackler
r? @sfackler 
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/codemap.rs4
-rw-r--r--src/libsyntax/diagnostic.rs11
-rw-r--r--src/libsyntax/ext/expand.rs51
3 files changed, 52 insertions, 14 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 348bf6f51bb..c692babfacc 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -235,7 +235,9 @@ pub enum MacroFormat {
     /// e.g. #[derive(...)] <item>
     MacroAttribute,
     /// e.g. `format!()`
-    MacroBang
+    MacroBang,
+    /// Expansion performed by the compiler (libsyntax::expand).
+    CompilerExpansion,
 }
 
 #[derive(Clone, Hash, Debug)]
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index aa649b4d99a..66ddd73101e 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -770,12 +770,15 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
                                                |span| cm.span_to_string(span));
                 let (pre, post) = match ei.callee.format {
                     codemap::MacroAttribute => ("#[", "]"),
-                    codemap::MacroBang => ("", "!")
+                    codemap::MacroBang => ("", "!"),
+                    codemap::CompilerExpansion => ("", ""),
                 };
                 try!(print_diagnostic(w, &ss, Note,
-                                      &format!("in expansion of {}{}{}", pre,
-                                              ei.callee.name,
-                                              post), None));
+                                      &format!("in expansion of {}{}{}",
+                                               pre,
+                                               ei.callee.name,
+                                               post),
+                                      None));
                 let ss = cm.span_to_string(ei.call_site);
                 try!(print_diagnostic(w, &ss, Note, "expansion site", None));
                 Ok(Some(ei.call_site))
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d71557bd737..fae0b56ce3d 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -19,7 +19,7 @@ use ext::build::AstBuilder;
 use attr;
 use attr::AttrMetaMethods;
 use codemap;
-use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, CompilerExpansion};
 use ext::base::*;
 use feature_gate::{self, Features};
 use fold;
@@ -34,6 +34,18 @@ use visit::Visitor;
 use std_inject;
 
 pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
+    fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc: &str) {
+        fld.cx.bt_push(ExpnInfo {
+            call_site: span,
+            callee: NameAndSpan {
+                name: expansion_desc.to_string(),
+                format: CompilerExpansion,
+                allow_internal_unstable: true,
+                span: None,
+            },
+        });
+    }
+
     e.and_then(|ast::Expr {id, node, span}| match node {
         // expr_mac should really be expr_ext or something; it's the
         // entry-point for all syntax extensions.
@@ -77,6 +89,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             //     }
             //   }
 
+            push_compiler_expansion(fld, span, "while let expansion");
+
             // `<pat> => <body>`
             let pat_arm = {
                 let body_expr = fld.cx.expr_block(body);
@@ -98,7 +112,9 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             // `[opt_ident]: loop { ... }`
             let loop_block = fld.cx.block_expr(match_expr);
             let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
-            fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident))
+            let result = fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident));
+            fld.cx.bt_pop();
+            result
         }
 
         // Desugar ExprIfLet
@@ -112,6 +128,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             //     _ => [<elseopt> | ()]
             //   }
 
+            push_compiler_expansion(fld, span, "if let expansion");
+
             // `<pat> => <body>`
             let pat_arm = {
                 let body_expr = fld.cx.expr_block(body);
@@ -173,13 +191,16 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                                                 ast::MatchSource::IfLetDesugar {
                                                     contains_else_clause: contains_else_clause,
                                                 }));
-            fld.fold_expr(match_expr)
+            let result = fld.fold_expr(match_expr);
+            fld.cx.bt_pop();
+            result
         }
 
         // Desugar support for ExprIfLet in the ExprIf else position
         ast::ExprIf(cond, blk, elseopt) => {
             let elseopt = elseopt.map(|els| els.and_then(|els| match els.node {
                 ast::ExprIfLet(..) => {
+                    push_compiler_expansion(fld, span, "if let expansion");
                     // wrap the if-let expr in a block
                     let span = els.span;
                     let blk = P(ast::Block {
@@ -189,7 +210,9 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                         rules: ast::DefaultBlock,
                         span: span
                     });
-                    fld.cx.expr_block(blk)
+                    let result = fld.cx.expr_block(blk);
+                    fld.cx.bt_pop();
+                    result
                 }
                 _ => P(els)
             }));
@@ -221,6 +244,10 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             //     result
             //   }
 
+            push_compiler_expansion(fld, span, "for loop expansion");
+
+            let span = fld.new_span(span);
+
             // expand <head>
             let head = fld.fold_expr(head);
 
@@ -235,10 +262,11 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                 rename_fld.fold_ident(ident)
             };
 
-            let pat_span = pat.span;
-            // `:;std::option::Option::Some(<pat>) => <body>`
+            let pat_span = fld.new_span(pat.span);
+            // `::std::option::Option::Some(<pat>) => <body>`
             let pat_arm = {
                 let body_expr = fld.cx.expr_block(body);
+                let pat = noop_fold_pat(pat, fld);
                 let some_pat = fld.cx.pat_some(pat_span, pat);
 
                 fld.cx.arm(pat_span, vec![some_pat], body_expr)
@@ -304,20 +332,25 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
 
             // `{ let result = ...; result }`
             let result_ident = token::gensym_ident("result");
-            fld.cx.expr_block(
+            let result = fld.cx.expr_block(
                 fld.cx.block_all(
                     span,
                     vec![fld.cx.stmt_let(span, false, result_ident, match_expr)],
-                    Some(fld.cx.expr_ident(span, result_ident))))
+                    Some(fld.cx.expr_ident(span, result_ident))));
+            fld.cx.bt_pop();
+            result
         }
 
         ast::ExprClosure(capture_clause, fn_decl, block) => {
+            push_compiler_expansion(fld, span, "closure expansion");
             let (rewritten_fn_decl, rewritten_block)
                 = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
             let new_node = ast::ExprClosure(capture_clause,
                                             rewritten_fn_decl,
                                             rewritten_block);
-            P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
+            let result = P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)});
+            fld.cx.bt_pop();
+            result
         }
 
         _ => {