about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-09-29 13:17:46 +1300
committerNick Cameron <ncameron@mozilla.com>2015-10-09 11:53:41 +1300
commit7f469ba6c5b0167949540d6c2afe51a0454767f5 (patch)
tree78d9173f74811c35171f87550b43482da389b0e4
parentbc364b4a0d678b29cba92ce948d948aee9d76b25 (diff)
downloadrust-7f469ba6c5b0167949540d6c2afe51a0454767f5.tar.gz
rust-7f469ba6c5b0167949540d6c2afe51a0454767f5.zip
Move placement in desugaring to lowering
-rw-r--r--src/librustc_front/lowering.rs106
-rw-r--r--src/libsyntax/ext/expand.rs157
2 files changed, 106 insertions, 157 deletions
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
index d9b834fe9fc..8a8620cbcca 100644
--- a/src/librustc_front/lowering.rs
+++ b/src/librustc_front/lowering.rs
@@ -752,6 +752,83 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                 ExprBox(ref e) => {
                     hir::ExprBox(lower_expr(lctx, e))
                 }
+
+                // Desugar ExprBox: `in (PLACE) EXPR`
+                ExprInPlace(Some(ref placer), ref value_expr) => {
+                    // to:
+                    //
+                    // let p = PLACE;
+                    // let mut place = Placer::make_place(p);
+                    // let raw_place = Place::pointer(&mut place);
+                    // push_unsafe!({
+                    //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
+                    //     InPlace::finalize(place)
+                    // })
+
+                    // TODO
+                    println!("{}", lctx.foo);
+
+                    let placer_expr = lower_expr(lctx, placer);
+                    let value_expr = lower_expr(lctx, value_expr);
+
+                    let placer_ident = token::gensym_ident("placer");
+                    let agent_ident = token::gensym_ident("place");
+                    let p_ptr_ident = token::gensym_ident("p_ptr");
+
+                    let make_place = ["ops", "Placer", "make_place"];
+                    let place_pointer = ["ops", "Place", "pointer"];
+                    let move_val_init = ["intrinsics", "move_val_init"];
+                    let inplace_finalize = ["ops", "InPlace", "finalize"];
+
+                    let make_call = |lctx, p, args| {
+                        let path = core_path(lctx, e.span, p);
+                        let path = expr_path(lctx, path);
+                        expr_call(lctx, e.span, path, args)
+                    };
+
+                    let mk_stmt_let = |lctx, bind, expr| {
+                        stmt_let(lctx, e.span, false, bind, expr)
+                    };
+                    let mk_stmt_let_mut = |lctx, bind, expr| {
+                        stmt_let(lctx, e.span, true, bind, expr)
+                    };
+
+                    // let placer = <placer_expr> ;
+                    let s1 = mk_stmt_let(lctx, placer_ident, placer_expr);
+
+                    // let mut place = Placer::make_place(placer);
+                    let s2 = {
+                        let call = make_call(lctx, &make_place, vec![expr_ident(lctx, e.span, placer_ident)]);
+                        mk_stmt_let_mut(lctx, agent_ident, call)
+                    };
+
+                    // let p_ptr = Place::pointer(&mut place);
+                    let s3 = {
+                        let args = vec![expr_mut_addr_of(lctx, e.span, expr_ident(lctx, e.span, agent_ident))];
+                        let call = make_call(lctx, &place_pointer, args);
+                        mk_stmt_let(lctx, p_ptr_ident, call)
+                    };
+
+                    // pop_unsafe!(EXPR));
+                    let pop_unsafe_expr = pop_unsafe_expr(lctx, value_expr, e.span);
+
+                    // push_unsafe!({
+                    //     ptr::write(p_ptr, pop_unsafe!(<value_expr>));
+                    //     InPlace::finalize(place)
+                    // })
+                    let expr = {
+                        let call_move_val_init = hir::StmtSemi(make_call(
+                            lctx, &move_val_init, vec![expr_ident(lctx, e.span, p_ptr_ident), pop_unsafe_expr]), lctx.next_id());
+                        let call_move_val_init = respan(e.span, call_move_val_init);
+
+                        let call = make_call(lctx, &inplace_finalize, vec![expr_ident(lctx, e.span, agent_ident)]);
+                        Some(push_unsafe_expr(lctx, vec![P(call_move_val_init)], call, e.span))
+                    };
+
+                    let block = block_all(lctx, e.span, vec![s1, s2, s3], expr);
+                    return expr_block(lctx, block);
+                }
+                
                 ExprVec(ref exprs) => {
                     hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect())
                 }
@@ -895,9 +972,6 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                 ExprParen(ref ex) => {
                     return lower_expr(lctx, ex);
                 }
-                ExprInPlace(..) => {
-                    panic!("todo");
-                }
 
                 // Desugar ExprIfLet
                 // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
@@ -1393,3 +1467,29 @@ fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec<Ident> {
     v.extend(components.iter().map(|s| str_to_ident(s)));
     return v
 }
+
+// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
+// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
+fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path {
+    let idents = std_path(lctx, components);
+    path_global(span, idents)
+}
+
+fn push_unsafe_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>,
+                    expr: P<hir::Expr>, span: Span)
+                    -> P<hir::Expr> {
+    let rules = hir::PushUnsafeBlock(hir::CompilerGenerated);
+    expr_block(lctx, P(hir::Block {
+        rules: rules, span: span, id: lctx.next_id(),
+        stmts: stmts, expr: Some(expr),
+    }))
+}
+
+fn pop_unsafe_expr(lctx: &LoweringContext, expr: P<hir::Expr>, span: Span)
+                   -> P<hir::Expr> {
+    let rules = hir::PopUnsafeBlock(hir::CompilerGenerated);
+    expr_block(lctx, P(hir::Block {
+        rules: rules, span: span, id: lctx.next_id(),
+        stmts: vec![], expr: Some(expr),
+    }))
+}
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index f6767bc4e47..abda406dcc8 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -20,53 +20,20 @@ use attr;
 use attr::AttrMetaMethods;
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
-use codemap::{CompilerExpansion, CompilerExpansionFormat};
 use ext::base::*;
 use feature_gate::{self, Features, GatedCfg};
 use fold;
 use fold::*;
 use parse;
 use parse::token::{fresh_mark, fresh_name, intern};
-use parse::token;
 use ptr::P;
 use util::small_vector::SmallVector;
 use visit;
 use visit::Visitor;
 use std_inject;
 
-// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
-// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
-fn mk_core_path(fld: &mut MacroExpander,
-                span: Span,
-                suffix: &[&'static str]) -> ast::Path {
-    let idents = fld.cx.std_path(suffix);
-    fld.cx.path_global(span, idents)
-}
 
 pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
-    fn push_compiler_expansion(fld: &mut MacroExpander, span: Span,
-                               expansion_type: CompilerExpansionFormat) {
-        fld.cx.bt_push(ExpnInfo {
-            call_site: span,
-            callee: NameAndSpan {
-                format: CompilerExpansion(expansion_type),
-
-                // 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 {
 
@@ -94,118 +61,18 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             })
         }
 
-        // Desugar ExprInPlace: `in PLACE { EXPR }`
         ast::ExprInPlace(placer, value_expr) => {
-            // to:
-            //
-            // let p = PLACE;
-            // let mut place = Placer::make_place(p);
-            // let raw_place = Place::pointer(&mut place);
-            // push_unsafe!({
-            //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
-            //     InPlace::finalize(place)
-            // })
-
             // Ensure feature-gate is enabled
             feature_gate::check_for_placement_in(
                 fld.cx.ecfg.features,
                 &fld.cx.parse_sess.span_diagnostic,
                 expr_span);
 
-            push_compiler_expansion(fld, expr_span, CompilerExpansionFormat::PlacementIn);
-
-            let value_span = value_expr.span;
-            let placer_span = placer.span;
-
-            let placer_expr = fld.fold_expr(placer);
+            let placer = fld.fold_expr(placer);
             let value_expr = fld.fold_expr(value_expr);
-
-            let placer_ident = token::gensym_ident("placer");
-            let agent_ident = token::gensym_ident("place");
-            let p_ptr_ident = token::gensym_ident("p_ptr");
-
-            let placer = fld.cx.expr_ident(span, placer_ident);
-            let agent = fld.cx.expr_ident(span, agent_ident);
-            let p_ptr = fld.cx.expr_ident(span, p_ptr_ident);
-
-            let make_place = ["ops", "Placer", "make_place"];
-            let place_pointer = ["ops", "Place", "pointer"];
-            let move_val_init = ["intrinsics", "move_val_init"];
-            let inplace_finalize = ["ops", "InPlace", "finalize"];
-
-            let make_call = |fld: &mut MacroExpander, p, args| {
-                // 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);
-                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| {
-                fld.cx.stmt_let(placer_span, false, bind, expr)
-            };
-            let stmt_let_mut = |fld: &mut MacroExpander, bind, expr| {
-                fld.cx.stmt_let(placer_span, true, bind, expr)
-            };
-
-            // let placer = <placer_expr> ;
-            let s1 = stmt_let(fld, placer_ident, placer_expr);
-
-            // let mut place = Placer::make_place(placer);
-            let s2 = {
-                let call = make_call(fld, &make_place, vec![placer]);
-                stmt_let_mut(fld, agent_ident, call)
-            };
-
-            // let p_ptr = Place::pointer(&mut place);
-            let s3 = {
-                let args = vec![fld.cx.expr_mut_addr_of(placer_span, agent.clone())];
-                let call = make_call(fld, &place_pointer, args);
-                stmt_let(fld, p_ptr_ident, call)
-            };
-
-            // pop_unsafe!(EXPR));
-            let pop_unsafe_expr = pop_unsafe_expr(fld.cx, value_expr, value_span);
-
-            // push_unsafe!({
-            //     ptr::write(p_ptr, pop_unsafe!(<value_expr>));
-            //     InPlace::finalize(place)
-            // })
-            let expr = {
-                let call_move_val_init = StmtSemi(make_call(
-                    fld, &move_val_init, vec![p_ptr, pop_unsafe_expr]), ast::DUMMY_NODE_ID);
-                let call_move_val_init = codemap::respan(value_span, call_move_val_init);
-
-                let call = make_call(fld, &inplace_finalize, vec![agent]);
-                Some(push_unsafe_expr(fld.cx, vec![P(call_move_val_init)], call, span))
-            };
-
-            let block = fld.cx.block_all(span, vec![s1, s2, s3], expr);
-            let result = fld.cx.expr_block(block);
-            fld.cx.bt_pop();
-            result
+            fld.cx.expr(span, ast::ExprBox(Some(placer), value_expr))
         }
 
-        // Issue #22181:
-        // Eventually a desugaring for `box EXPR`
-        // (similar to the desugaring above for `in PLACE BLOCK`)
-        // should go here, desugaring
-        //
-        // to:
-        //
-        // let mut place = BoxPlace::make_place();
-        // let raw_place = Place::pointer(&mut place);
-        // let value = $value;
-        // unsafe {
-        //     ::std::ptr::write(raw_place, value);
-        //     Boxed::finalize(place)
-        // }
-        //
-        // But for now there are type-inference issues doing that.
-
         ast::ExprWhile(cond, body, opt_ident) => {
             let cond = fld.fold_expr(cond);
             let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
@@ -225,6 +92,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
         }
 
         ast::ExprForLoop(pat, head, body, opt_ident) => {
+            let pat = fld.fold_pat(pat);
             let head = fld.fold_expr(head);
             let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
             fld.cx.expr(span, ast::ExprForLoop(pat, head, body, opt_ident))
@@ -247,25 +115,6 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             }, fld))
         }
     });
-
-    fn push_unsafe_expr(cx: &mut ExtCtxt, stmts: Vec<P<ast::Stmt>>,
-                        expr: P<ast::Expr>, span: Span)
-                        -> P<ast::Expr> {
-        let rules = ast::PushUnsafeBlock(ast::CompilerGenerated);
-        cx.expr_block(P(ast::Block {
-            rules: rules, span: span, id: ast::DUMMY_NODE_ID,
-            stmts: stmts, expr: Some(expr),
-        }))
-    }
-
-    fn pop_unsafe_expr(cx: &mut ExtCtxt, expr: P<ast::Expr>, span: Span)
-                       -> P<ast::Expr> {
-        let rules = ast::PopUnsafeBlock(ast::CompilerGenerated);
-        cx.expr_block(P(ast::Block {
-            rules: rules, span: span, id: ast::DUMMY_NODE_ID,
-            stmts: vec![], expr: Some(expr),
-        }))
-    }
 }
 
 /// Expand a (not-ident-style) macro invocation. Returns the result