about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2015-06-05 18:51:23 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2015-07-22 15:34:00 +0200
commit07afe91fda3df8e3b7bbb14006a64d136627f33c (patch)
treed09da26b0a98c9cf03ad223b0d1cdfca41802a53 /src/libsyntax/ext
parentcb5f0b4971481fd8985c78c7a24e422f45ea6560 (diff)
downloadrust-07afe91fda3df8e3b7bbb14006a64d136627f33c.tar.gz
rust-07afe91fda3df8e3b7bbb14006a64d136627f33c.zip
Allow unstable code to be injected by placement-`in` expansion.
(Over time the stability checking has gotten more finicky; in
particular one must attach the (whole) span of the original `in PLACE
BLOCK` expression to the injected references to unstable paths, as
noted in the comments.)

call `push_compiler_expansion` during the placement-`in` expansion.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/expand.rs26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 93e744287ba..faa1e5b2f51 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -50,12 +50,23 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             callee: NameAndSpan {
                 name: expansion_desc.to_string(),
                 format: CompilerExpansion,
+
+                // This does *not* mean code generated after
+                // `push_compiler_expansion` is automatically exempt
+                // from stability lints; must also tag such code with
+                // an appropriate span from `fld.cx.backtrace()`.
                 allow_internal_unstable: true,
+
                 span: None,
             },
         });
     }
 
+    // Sets the expn_id so that we can use unstable methods.
+    fn allow_unstable(fld: &mut MacroExpander, span: Span) -> Span {
+        Span { expn_id: fld.cx.backtrace(), ..span }
+    }
+
     let expr_span = e.span;
     return e.and_then(|ast::Expr {id, node, span}| match node {
 
@@ -101,6 +112,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                 &fld.cx.parse_sess.span_diagnostic,
                 expr_span);
 
+            push_compiler_expansion(fld, expr_span, "placement-in expansion");
+
             let value_span = value_expr.span;
             let placer_span = placer.span;
 
@@ -121,9 +134,14 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             let inplace_finalize = ["ops", "InPlace", "finalize"];
 
             let make_call = |fld: &mut MacroExpander, p, args| {
-                let path = mk_core_path(fld, placer_span, p);
+                // We feed in the `expr_span` because codemap's span_allows_unstable
+                // allows the call_site span to inherit the `allow_internal_unstable`
+                // setting.
+                let span_unstable = allow_unstable(fld, expr_span);
+                let path = mk_core_path(fld, span_unstable, p);
                 let path = fld.cx.expr_path(path);
-                fld.cx.expr_call(span, path, args)
+                let expr_span_unstable = allow_unstable(fld, span);
+                fld.cx.expr_call(expr_span_unstable, path, args)
             };
 
             let stmt_let = |fld: &mut MacroExpander, bind, expr| {
@@ -166,7 +184,9 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             };
 
             let block = fld.cx.block_all(span, vec![s1, s2, s3], expr);
-            fld.cx.expr_block(block)
+            let result = fld.cx.expr_block(block);
+            fld.cx.bt_pop();
+            result
         }
 
         // Issue #22181: