Skip to content

Commit 7f469ba

Browse files
committed
Move placement in desugaring to lowering
1 parent bc364b4 commit 7f469ba

File tree

2 files changed

+106
-157
lines changed

2 files changed

+106
-157
lines changed

src/librustc_front/lowering.rs

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,83 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
752752
ExprBox(ref e) => {
753753
hir::ExprBox(lower_expr(lctx, e))
754754
}
755+
756+
// Desugar ExprBox: `in (PLACE) EXPR`
757+
ExprInPlace(Some(ref placer), ref value_expr) => {
758+
// to:
759+
//
760+
// let p = PLACE;
761+
// let mut place = Placer::make_place(p);
762+
// let raw_place = Place::pointer(&mut place);
763+
// push_unsafe!({
764+
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
765+
// InPlace::finalize(place)
766+
// })
767+
768+
// TODO
769+
println!("{}", lctx.foo);
770+
771+
let placer_expr = lower_expr(lctx, placer);
772+
let value_expr = lower_expr(lctx, value_expr);
773+
774+
let placer_ident = token::gensym_ident("placer");
775+
let agent_ident = token::gensym_ident("place");
776+
let p_ptr_ident = token::gensym_ident("p_ptr");
777+
778+
let make_place = ["ops", "Placer", "make_place"];
779+
let place_pointer = ["ops", "Place", "pointer"];
780+
let move_val_init = ["intrinsics", "move_val_init"];
781+
let inplace_finalize = ["ops", "InPlace", "finalize"];
782+
783+
let make_call = |lctx, p, args| {
784+
let path = core_path(lctx, e.span, p);
785+
let path = expr_path(lctx, path);
786+
expr_call(lctx, e.span, path, args)
787+
};
788+
789+
let mk_stmt_let = |lctx, bind, expr| {
790+
stmt_let(lctx, e.span, false, bind, expr)
791+
};
792+
let mk_stmt_let_mut = |lctx, bind, expr| {
793+
stmt_let(lctx, e.span, true, bind, expr)
794+
};
795+
796+
// let placer = <placer_expr> ;
797+
let s1 = mk_stmt_let(lctx, placer_ident, placer_expr);
798+
799+
// let mut place = Placer::make_place(placer);
800+
let s2 = {
801+
let call = make_call(lctx, &make_place, vec![expr_ident(lctx, e.span, placer_ident)]);
802+
mk_stmt_let_mut(lctx, agent_ident, call)
803+
};
804+
805+
// let p_ptr = Place::pointer(&mut place);
806+
let s3 = {
807+
let args = vec![expr_mut_addr_of(lctx, e.span, expr_ident(lctx, e.span, agent_ident))];
808+
let call = make_call(lctx, &place_pointer, args);
809+
mk_stmt_let(lctx, p_ptr_ident, call)
810+
};
811+
812+
// pop_unsafe!(EXPR));
813+
let pop_unsafe_expr = pop_unsafe_expr(lctx, value_expr, e.span);
814+
815+
// push_unsafe!({
816+
// ptr::write(p_ptr, pop_unsafe!(<value_expr>));
817+
// InPlace::finalize(place)
818+
// })
819+
let expr = {
820+
let call_move_val_init = hir::StmtSemi(make_call(
821+
lctx, &move_val_init, vec![expr_ident(lctx, e.span, p_ptr_ident), pop_unsafe_expr]), lctx.next_id());
822+
let call_move_val_init = respan(e.span, call_move_val_init);
823+
824+
let call = make_call(lctx, &inplace_finalize, vec![expr_ident(lctx, e.span, agent_ident)]);
825+
Some(push_unsafe_expr(lctx, vec![P(call_move_val_init)], call, e.span))
826+
};
827+
828+
let block = block_all(lctx, e.span, vec![s1, s2, s3], expr);
829+
return expr_block(lctx, block);
830+
}
831+
755832
ExprVec(ref exprs) => {
756833
hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect())
757834
}
@@ -895,9 +972,6 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
895972
ExprParen(ref ex) => {
896973
return lower_expr(lctx, ex);
897974
}
898-
ExprInPlace(..) => {
899-
panic!("todo");
900-
}
901975

902976
// Desugar ExprIfLet
903977
// From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
@@ -1393,3 +1467,29 @@ fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec<Ident> {
13931467
v.extend(components.iter().map(|s| str_to_ident(s)));
13941468
return v
13951469
}
1470+
1471+
// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
1472+
// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
1473+
fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path {
1474+
let idents = std_path(lctx, components);
1475+
path_global(span, idents)
1476+
}
1477+
1478+
fn push_unsafe_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>,
1479+
expr: P<hir::Expr>, span: Span)
1480+
-> P<hir::Expr> {
1481+
let rules = hir::PushUnsafeBlock(hir::CompilerGenerated);
1482+
expr_block(lctx, P(hir::Block {
1483+
rules: rules, span: span, id: lctx.next_id(),
1484+
stmts: stmts, expr: Some(expr),
1485+
}))
1486+
}
1487+
1488+
fn pop_unsafe_expr(lctx: &LoweringContext, expr: P<hir::Expr>, span: Span)
1489+
-> P<hir::Expr> {
1490+
let rules = hir::PopUnsafeBlock(hir::CompilerGenerated);
1491+
expr_block(lctx, P(hir::Block {
1492+
rules: rules, span: span, id: lctx.next_id(),
1493+
stmts: vec![], expr: Some(expr),
1494+
}))
1495+
}

src/libsyntax/ext/expand.rs

Lines changed: 3 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,20 @@ use attr;
2020
use attr::AttrMetaMethods;
2121
use codemap;
2222
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
23-
use codemap::{CompilerExpansion, CompilerExpansionFormat};
2423
use ext::base::*;
2524
use feature_gate::{self, Features, GatedCfg};
2625
use fold;
2726
use fold::*;
2827
use parse;
2928
use parse::token::{fresh_mark, fresh_name, intern};
30-
use parse::token;
3129
use ptr::P;
3230
use util::small_vector::SmallVector;
3331
use visit;
3432
use visit::Visitor;
3533
use std_inject;
3634

37-
// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
38-
// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
39-
fn mk_core_path(fld: &mut MacroExpander,
40-
span: Span,
41-
suffix: &[&'static str]) -> ast::Path {
42-
let idents = fld.cx.std_path(suffix);
43-
fld.cx.path_global(span, idents)
44-
}
4535

4636
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
47-
fn push_compiler_expansion(fld: &mut MacroExpander, span: Span,
48-
expansion_type: CompilerExpansionFormat) {
49-
fld.cx.bt_push(ExpnInfo {
50-
call_site: span,
51-
callee: NameAndSpan {
52-
format: CompilerExpansion(expansion_type),
53-
54-
// This does *not* mean code generated after
55-
// `push_compiler_expansion` is automatically exempt
56-
// from stability lints; must also tag such code with
57-
// an appropriate span from `fld.cx.backtrace()`.
58-
allow_internal_unstable: true,
59-
60-
span: None,
61-
},
62-
});
63-
}
64-
65-
// Sets the expn_id so that we can use unstable methods.
66-
fn allow_unstable(fld: &mut MacroExpander, span: Span) -> Span {
67-
Span { expn_id: fld.cx.backtrace(), ..span }
68-
}
69-
7037
let expr_span = e.span;
7138
return e.and_then(|ast::Expr {id, node, span}| match node {
7239

@@ -94,118 +61,18 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
9461
})
9562
}
9663

97-
// Desugar ExprInPlace: `in PLACE { EXPR }`
9864
ast::ExprInPlace(placer, value_expr) => {
99-
// to:
100-
//
101-
// let p = PLACE;
102-
// let mut place = Placer::make_place(p);
103-
// let raw_place = Place::pointer(&mut place);
104-
// push_unsafe!({
105-
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
106-
// InPlace::finalize(place)
107-
// })
108-
10965
// Ensure feature-gate is enabled
11066
feature_gate::check_for_placement_in(
11167
fld.cx.ecfg.features,
11268
&fld.cx.parse_sess.span_diagnostic,
11369
expr_span);
11470

115-
push_compiler_expansion(fld, expr_span, CompilerExpansionFormat::PlacementIn);
116-
117-
let value_span = value_expr.span;
118-
let placer_span = placer.span;
119-
120-
let placer_expr = fld.fold_expr(placer);
71+
let placer = fld.fold_expr(placer);
12172
let value_expr = fld.fold_expr(value_expr);
122-
123-
let placer_ident = token::gensym_ident("placer");
124-
let agent_ident = token::gensym_ident("place");
125-
let p_ptr_ident = token::gensym_ident("p_ptr");
126-
127-
let placer = fld.cx.expr_ident(span, placer_ident);
128-
let agent = fld.cx.expr_ident(span, agent_ident);
129-
let p_ptr = fld.cx.expr_ident(span, p_ptr_ident);
130-
131-
let make_place = ["ops", "Placer", "make_place"];
132-
let place_pointer = ["ops", "Place", "pointer"];
133-
let move_val_init = ["intrinsics", "move_val_init"];
134-
let inplace_finalize = ["ops", "InPlace", "finalize"];
135-
136-
let make_call = |fld: &mut MacroExpander, p, args| {
137-
// We feed in the `expr_span` because codemap's span_allows_unstable
138-
// allows the call_site span to inherit the `allow_internal_unstable`
139-
// setting.
140-
let span_unstable = allow_unstable(fld, expr_span);
141-
let path = mk_core_path(fld, span_unstable, p);
142-
let path = fld.cx.expr_path(path);
143-
let expr_span_unstable = allow_unstable(fld, span);
144-
fld.cx.expr_call(expr_span_unstable, path, args)
145-
};
146-
147-
let stmt_let = |fld: &mut MacroExpander, bind, expr| {
148-
fld.cx.stmt_let(placer_span, false, bind, expr)
149-
};
150-
let stmt_let_mut = |fld: &mut MacroExpander, bind, expr| {
151-
fld.cx.stmt_let(placer_span, true, bind, expr)
152-
};
153-
154-
// let placer = <placer_expr> ;
155-
let s1 = stmt_let(fld, placer_ident, placer_expr);
156-
157-
// let mut place = Placer::make_place(placer);
158-
let s2 = {
159-
let call = make_call(fld, &make_place, vec![placer]);
160-
stmt_let_mut(fld, agent_ident, call)
161-
};
162-
163-
// let p_ptr = Place::pointer(&mut place);
164-
let s3 = {
165-
let args = vec![fld.cx.expr_mut_addr_of(placer_span, agent.clone())];
166-
let call = make_call(fld, &place_pointer, args);
167-
stmt_let(fld, p_ptr_ident, call)
168-
};
169-
170-
// pop_unsafe!(EXPR));
171-
let pop_unsafe_expr = pop_unsafe_expr(fld.cx, value_expr, value_span);
172-
173-
// push_unsafe!({
174-
// ptr::write(p_ptr, pop_unsafe!(<value_expr>));
175-
// InPlace::finalize(place)
176-
// })
177-
let expr = {
178-
let call_move_val_init = StmtSemi(make_call(
179-
fld, &move_val_init, vec![p_ptr, pop_unsafe_expr]), ast::DUMMY_NODE_ID);
180-
let call_move_val_init = codemap::respan(value_span, call_move_val_init);
181-
182-
let call = make_call(fld, &inplace_finalize, vec![agent]);
183-
Some(push_unsafe_expr(fld.cx, vec![P(call_move_val_init)], call, span))
184-
};
185-
186-
let block = fld.cx.block_all(span, vec![s1, s2, s3], expr);
187-
let result = fld.cx.expr_block(block);
188-
fld.cx.bt_pop();
189-
result
73+
fld.cx.expr(span, ast::ExprBox(Some(placer), value_expr))
19074
}
19175

192-
// Issue #22181:
193-
// Eventually a desugaring for `box EXPR`
194-
// (similar to the desugaring above for `in PLACE BLOCK`)
195-
// should go here, desugaring
196-
//
197-
// to:
198-
//
199-
// let mut place = BoxPlace::make_place();
200-
// let raw_place = Place::pointer(&mut place);
201-
// let value = $value;
202-
// unsafe {
203-
// ::std::ptr::write(raw_place, value);
204-
// Boxed::finalize(place)
205-
// }
206-
//
207-
// But for now there are type-inference issues doing that.
208-
20976
ast::ExprWhile(cond, body, opt_ident) => {
21077
let cond = fld.fold_expr(cond);
21178
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> {
22592
}
22693

22794
ast::ExprForLoop(pat, head, body, opt_ident) => {
95+
let pat = fld.fold_pat(pat);
22896
let head = fld.fold_expr(head);
22997
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
23098
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> {
247115
}, fld))
248116
}
249117
});
250-
251-
fn push_unsafe_expr(cx: &mut ExtCtxt, stmts: Vec<P<ast::Stmt>>,
252-
expr: P<ast::Expr>, span: Span)
253-
-> P<ast::Expr> {
254-
let rules = ast::PushUnsafeBlock(ast::CompilerGenerated);
255-
cx.expr_block(P(ast::Block {
256-
rules: rules, span: span, id: ast::DUMMY_NODE_ID,
257-
stmts: stmts, expr: Some(expr),
258-
}))
259-
}
260-
261-
fn pop_unsafe_expr(cx: &mut ExtCtxt, expr: P<ast::Expr>, span: Span)
262-
-> P<ast::Expr> {
263-
let rules = ast::PopUnsafeBlock(ast::CompilerGenerated);
264-
cx.expr_block(P(ast::Block {
265-
rules: rules, span: span, id: ast::DUMMY_NODE_ID,
266-
stmts: vec![], expr: Some(expr),
267-
}))
268-
}
269118
}
270119

271120
/// Expand a (not-ident-style) macro invocation. Returns the result

0 commit comments

Comments
 (0)