Skip to content

Commit 17b3c11

Browse files
committed
syntax: format: put static arrays in their own blocks to avoid needing a wrapper block.
1 parent 22376be commit 17b3c11

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

src/libsyntax/ext/format.rs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -473,22 +473,27 @@ impl<'a, 'b> Context<'a, 'b> {
473473
}
474474
}
475475

476-
fn item_static_array(ecx: &mut ExtCtxt,
477-
name: ast::Ident,
478-
piece_ty: P<ast::Ty>,
479-
pieces: Vec<P<ast::Expr>>)
480-
-> P<ast::Stmt> {
476+
fn static_array(ecx: &mut ExtCtxt,
477+
name: &str,
478+
piece_ty: P<ast::Ty>,
479+
pieces: Vec<P<ast::Expr>>)
480+
-> P<ast::Expr> {
481481
let fmtsp = piece_ty.span;
482-
let fmt = ecx.expr_vec(fmtsp, pieces);
483-
let fmt = ecx.expr_addr_of(fmtsp, fmt);
484-
let ty = ast::TyVec(piece_ty);
485-
let ty = ast::TyRptr(Some(ecx.lifetime(fmtsp, special_idents::static_lifetime.name)),
486-
ast::MutTy{ mutbl: ast::MutImmutable, ty: ecx.ty(fmtsp, ty) });
487-
let ty = ecx.ty(fmtsp, ty);
488-
let st = ast::ItemStatic(ty, ast::MutImmutable, fmt);
482+
let ty = ecx.ty_rptr(fmtsp,
483+
ecx.ty(fmtsp, ast::TyVec(piece_ty)),
484+
Some(ecx.lifetime(fmtsp, special_idents::static_lifetime.name)),
485+
ast::MutImmutable);
486+
let slice = ecx.expr_vec_slice(fmtsp, pieces);
487+
let st = ast::ItemStatic(ty, ast::MutImmutable, slice);
488+
489+
let name = ecx.ident_of(name);
489490
let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st);
490491
let decl = respan(fmtsp, ast::DeclItem(item));
491-
P(respan(fmtsp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID)))
492+
493+
// Wrap the declaration in a block so that it forms a single expression.
494+
ecx.expr_block(ecx.block(fmtsp,
495+
vec![P(respan(fmtsp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID)))],
496+
Some(ecx.expr_ident(fmtsp, name))))
492497
}
493498

494499
/// Actually builds the expression which the iformat! block will be expanded
@@ -501,33 +506,17 @@ impl<'a, 'b> Context<'a, 'b> {
501506

502507
// First, build up the static array which will become our precompiled
503508
// format "string"
504-
let static_str_name = self.ecx.ident_of("__STATIC_FMTSTR");
505-
let static_lifetime = self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("'static").name);
509+
let static_lifetime = self.ecx.lifetime(self.fmtsp, special_idents::static_lifetime.name);
506510
let piece_ty = self.ecx.ty_rptr(
507511
self.fmtsp,
508512
self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
509513
Some(static_lifetime),
510514
ast::MutImmutable);
511-
let mut lets = vec![
512-
Context::item_static_array(self.ecx, static_str_name, piece_ty, self.str_pieces)
513-
];
514-
515-
// Then, build up the static array which will store our precompiled
516-
// nonstandard placeholders, if there are any.
517-
let static_args_name = self.ecx.ident_of("__STATIC_FMTARGS");
518-
if !self.all_pieces_simple {
519-
let piece_ty = self.ecx.ty_path(self.ecx.path_all(
520-
self.fmtsp,
521-
true, Context::rtpath(self.ecx, "Argument"),
522-
vec![static_lifetime],
523-
vec![],
524-
vec![]
525-
));
526-
lets.push(Context::item_static_array(self.ecx,
527-
static_args_name,
528-
piece_ty,
529-
self.pieces));
530-
}
515+
let pieces = Context::static_array(self.ecx,
516+
"__STATIC_FMTSTR",
517+
piece_ty,
518+
self.str_pieces);
519+
531520

532521
// Right now there is a bug such that for the expression:
533522
// foo(bar(&1))
@@ -571,13 +560,25 @@ impl<'a, 'b> Context<'a, 'b> {
571560
let args = locals.into_iter().chain(names.into_iter().map(|a| a.unwrap()));
572561

573562
// Now create the fmt::Arguments struct with all our locals we created.
574-
let pieces = self.ecx.expr_ident(self.fmtsp, static_str_name);
575563
let args_slice = self.ecx.expr_vec_slice(self.fmtsp, args.collect());
576564

577565
let (fn_name, fn_args) = if self.all_pieces_simple {
578566
("new", vec![pieces, args_slice])
579567
} else {
580-
let fmt = self.ecx.expr_ident(self.fmtsp, static_args_name);
568+
// Build up the static array which will store our precompiled
569+
// nonstandard placeholders, if there are any.
570+
let piece_ty = self.ecx.ty_path(self.ecx.path_all(
571+
self.fmtsp,
572+
true, Context::rtpath(self.ecx, "Argument"),
573+
vec![static_lifetime],
574+
vec![],
575+
vec![]
576+
));
577+
let fmt = Context::static_array(self.ecx,
578+
"__STATIC_FMTARGS",
579+
piece_ty,
580+
self.pieces);
581+
581582
("with_placeholders", vec![pieces, fmt, args_slice])
582583
};
583584

@@ -587,7 +588,7 @@ impl<'a, 'b> Context<'a, 'b> {
587588
self.ecx.ident_of("Arguments"),
588589
self.ecx.ident_of(fn_name)), fn_args);
589590

590-
let result = match invocation {
591+
let body = match invocation {
591592
Call(e) => {
592593
let span = e.span;
593594
self.ecx.expr_call(span, e, vec![
@@ -601,8 +602,6 @@ impl<'a, 'b> Context<'a, 'b> {
601602
])
602603
}
603604
};
604-
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
605-
Some(result)));
606605

607606
// Constructs an AST equivalent to:
608607
//

0 commit comments

Comments
 (0)