mirror of https://github.com/rust-lang/rust.git
syntax: format: put static arrays in their own blocks to avoid needing a wrapper block.
This commit is contained in:
parent
22376be754
commit
17b3c1107a
|
@ -473,22 +473,27 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_static_array(ecx: &mut ExtCtxt,
|
fn static_array(ecx: &mut ExtCtxt,
|
||||||
name: ast::Ident,
|
name: &str,
|
||||||
piece_ty: P<ast::Ty>,
|
piece_ty: P<ast::Ty>,
|
||||||
pieces: Vec<P<ast::Expr>>)
|
pieces: Vec<P<ast::Expr>>)
|
||||||
-> P<ast::Stmt> {
|
-> P<ast::Expr> {
|
||||||
let fmtsp = piece_ty.span;
|
let fmtsp = piece_ty.span;
|
||||||
let fmt = ecx.expr_vec(fmtsp, pieces);
|
let ty = ecx.ty_rptr(fmtsp,
|
||||||
let fmt = ecx.expr_addr_of(fmtsp, fmt);
|
ecx.ty(fmtsp, ast::TyVec(piece_ty)),
|
||||||
let ty = ast::TyVec(piece_ty);
|
Some(ecx.lifetime(fmtsp, special_idents::static_lifetime.name)),
|
||||||
let ty = ast::TyRptr(Some(ecx.lifetime(fmtsp, special_idents::static_lifetime.name)),
|
ast::MutImmutable);
|
||||||
ast::MutTy{ mutbl: ast::MutImmutable, ty: ecx.ty(fmtsp, ty) });
|
let slice = ecx.expr_vec_slice(fmtsp, pieces);
|
||||||
let ty = ecx.ty(fmtsp, ty);
|
let st = ast::ItemStatic(ty, ast::MutImmutable, slice);
|
||||||
let st = ast::ItemStatic(ty, ast::MutImmutable, fmt);
|
|
||||||
|
let name = ecx.ident_of(name);
|
||||||
let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st);
|
let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st);
|
||||||
let decl = respan(fmtsp, ast::DeclItem(item));
|
let decl = respan(fmtsp, ast::DeclItem(item));
|
||||||
P(respan(fmtsp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID)))
|
|
||||||
|
// Wrap the declaration in a block so that it forms a single expression.
|
||||||
|
ecx.expr_block(ecx.block(fmtsp,
|
||||||
|
vec![P(respan(fmtsp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID)))],
|
||||||
|
Some(ecx.expr_ident(fmtsp, name))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actually builds the expression which the iformat! block will be expanded
|
/// Actually builds the expression which the iformat! block will be expanded
|
||||||
|
@ -501,33 +506,17 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
|
|
||||||
// First, build up the static array which will become our precompiled
|
// First, build up the static array which will become our precompiled
|
||||||
// format "string"
|
// format "string"
|
||||||
let static_str_name = self.ecx.ident_of("__STATIC_FMTSTR");
|
let static_lifetime = self.ecx.lifetime(self.fmtsp, special_idents::static_lifetime.name);
|
||||||
let static_lifetime = self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("'static").name);
|
|
||||||
let piece_ty = self.ecx.ty_rptr(
|
let piece_ty = self.ecx.ty_rptr(
|
||||||
self.fmtsp,
|
self.fmtsp,
|
||||||
self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
|
self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
|
||||||
Some(static_lifetime),
|
Some(static_lifetime),
|
||||||
ast::MutImmutable);
|
ast::MutImmutable);
|
||||||
let mut lets = vec![
|
let pieces = Context::static_array(self.ecx,
|
||||||
Context::item_static_array(self.ecx, static_str_name, piece_ty, self.str_pieces)
|
"__STATIC_FMTSTR",
|
||||||
];
|
|
||||||
|
|
||||||
// Then, build up the static array which will store our precompiled
|
|
||||||
// nonstandard placeholders, if there are any.
|
|
||||||
let static_args_name = self.ecx.ident_of("__STATIC_FMTARGS");
|
|
||||||
if !self.all_pieces_simple {
|
|
||||||
let piece_ty = self.ecx.ty_path(self.ecx.path_all(
|
|
||||||
self.fmtsp,
|
|
||||||
true, Context::rtpath(self.ecx, "Argument"),
|
|
||||||
vec![static_lifetime],
|
|
||||||
vec![],
|
|
||||||
vec![]
|
|
||||||
));
|
|
||||||
lets.push(Context::item_static_array(self.ecx,
|
|
||||||
static_args_name,
|
|
||||||
piece_ty,
|
piece_ty,
|
||||||
self.pieces));
|
self.str_pieces);
|
||||||
}
|
|
||||||
|
|
||||||
// Right now there is a bug such that for the expression:
|
// Right now there is a bug such that for the expression:
|
||||||
// foo(bar(&1))
|
// foo(bar(&1))
|
||||||
|
@ -571,13 +560,25 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
let args = locals.into_iter().chain(names.into_iter().map(|a| a.unwrap()));
|
let args = locals.into_iter().chain(names.into_iter().map(|a| a.unwrap()));
|
||||||
|
|
||||||
// Now create the fmt::Arguments struct with all our locals we created.
|
// Now create the fmt::Arguments struct with all our locals we created.
|
||||||
let pieces = self.ecx.expr_ident(self.fmtsp, static_str_name);
|
|
||||||
let args_slice = self.ecx.expr_vec_slice(self.fmtsp, args.collect());
|
let args_slice = self.ecx.expr_vec_slice(self.fmtsp, args.collect());
|
||||||
|
|
||||||
let (fn_name, fn_args) = if self.all_pieces_simple {
|
let (fn_name, fn_args) = if self.all_pieces_simple {
|
||||||
("new", vec![pieces, args_slice])
|
("new", vec![pieces, args_slice])
|
||||||
} else {
|
} else {
|
||||||
let fmt = self.ecx.expr_ident(self.fmtsp, static_args_name);
|
// Build up the static array which will store our precompiled
|
||||||
|
// nonstandard placeholders, if there are any.
|
||||||
|
let piece_ty = self.ecx.ty_path(self.ecx.path_all(
|
||||||
|
self.fmtsp,
|
||||||
|
true, Context::rtpath(self.ecx, "Argument"),
|
||||||
|
vec![static_lifetime],
|
||||||
|
vec![],
|
||||||
|
vec![]
|
||||||
|
));
|
||||||
|
let fmt = Context::static_array(self.ecx,
|
||||||
|
"__STATIC_FMTARGS",
|
||||||
|
piece_ty,
|
||||||
|
self.pieces);
|
||||||
|
|
||||||
("with_placeholders", vec![pieces, fmt, args_slice])
|
("with_placeholders", vec![pieces, fmt, args_slice])
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -587,7 +588,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
self.ecx.ident_of("Arguments"),
|
self.ecx.ident_of("Arguments"),
|
||||||
self.ecx.ident_of(fn_name)), fn_args);
|
self.ecx.ident_of(fn_name)), fn_args);
|
||||||
|
|
||||||
let result = match invocation {
|
let body = match invocation {
|
||||||
Call(e) => {
|
Call(e) => {
|
||||||
let span = e.span;
|
let span = e.span;
|
||||||
self.ecx.expr_call(span, e, vec![
|
self.ecx.expr_call(span, e, vec![
|
||||||
|
@ -601,8 +602,6 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
|
|
||||||
Some(result)));
|
|
||||||
|
|
||||||
// Constructs an AST equivalent to:
|
// Constructs an AST equivalent to:
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue