Auto merge of #21988 - kmcallister:no-std, r=sfackler

Fixes #21833.

[breaking-change]

r? @alexcrichton 

The tests in #21912 will also need `#[feature(no_std)]`. If you're okay with both PRs, I can merge and test them.
This commit is contained in:
bors
2015-02-08 00:24:03 +00:00
74 changed files with 489 additions and 171 deletions

View File

@@ -544,6 +544,7 @@ pub struct ExtCtxt<'a> {
pub cfg: ast::CrateConfig,
pub backtrace: ExpnId,
pub ecfg: expand::ExpansionConfig,
pub use_std: bool,
pub mod_path: Vec<ast::Ident> ,
pub trace_mac: bool,
@@ -563,6 +564,7 @@ impl<'a> ExtCtxt<'a> {
backtrace: NO_EXPANSION,
mod_path: Vec::new(),
ecfg: ecfg,
use_std: true,
trace_mac: false,
exported_macros: Vec::new(),
syntax_env: env,
@@ -737,6 +739,9 @@ impl<'a> ExtCtxt<'a> {
pub fn ident_of(&self, st: &str) -> ast::Ident {
str_to_ident(st)
}
pub fn ident_of_std(&self, st: &str) -> ast::Ident {
self.ident_of(if self.use_std { "std" } else { st })
}
pub fn name_of(&self, st: &str) -> ast::Name {
token::intern(st)
}

View File

@@ -386,7 +386,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.path_all(DUMMY_SP,
true,
vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("option"),
self.ident_of("Option")
),
@@ -656,7 +656,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
self.expr_call_global(sp,
vec!(self.ident_of("std"),
vec!(self.ident_of_std("collections"),
self.ident_of("vec"),
self.ident_of("Vec"),
self.ident_of("new")),
@@ -676,7 +676,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
let some = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("option"),
self.ident_of("Option"),
self.ident_of("Some"));
@@ -685,7 +685,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_none(&self, sp: Span) -> P<ast::Expr> {
let none = self.path_global(sp, vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("option"),
self.ident_of("Option"),
self.ident_of("None")));
@@ -712,7 +712,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(
span,
vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("rt"),
self.ident_of("begin_unwind")),
vec!(
@@ -728,7 +728,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
let ok = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Ok"));
@@ -737,7 +737,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
let err = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Err"));
@@ -745,10 +745,20 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
let ok = self.ident_of("Ok");
let ok_path = self.path_ident(sp, ok);
let err = self.ident_of("Err");
let err_path = self.path_ident(sp, err);
let ok = vec![
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Ok")
];
let ok_path = self.path_global(sp, ok);
let err = vec![
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Err")
];
let err_path = self.path_global(sp, err);
let binding_variable = self.ident_of("__try_var");
let binding_pat = self.pat_ident(sp, binding_variable);
@@ -758,8 +768,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
let ok_pat = self.pat_enum(sp, ok_path, vec!(binding_pat.clone()));
// Err(__try_var) (pattern and expression resp.)
let err_pat = self.pat_enum(sp, err_path, vec!(binding_pat));
let err_inner_expr = self.expr_call_ident(sp, err, vec!(binding_expr.clone()));
let err_pat = self.pat_enum(sp, err_path.clone(), vec!(binding_pat));
let err_inner_expr = self.expr_call(sp, self.expr_path(err_path),
vec!(binding_expr.clone()));
// return Err(__try_var)
let err_expr = self.expr(sp, ast::ExprRet(Some(err_inner_expr)));
@@ -808,7 +819,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("option"),
self.ident_of("Option"),
self.ident_of("Some"));
@@ -818,7 +829,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn pat_none(&self, span: Span) -> P<ast::Pat> {
let some = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("option"),
self.ident_of("Option"),
self.ident_of("None"));
@@ -828,7 +839,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Ok"));
@@ -838,7 +849,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = vec!(
self.ident_of("std"),
self.ident_of_std("core"),
self.ident_of("result"),
self.ident_of("Result"),
self.ident_of("Err"));

View File

@@ -45,10 +45,16 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
}
};
let path = Path::new(vec![
if cx.use_std { "std" } else { "core" },
"marker",
name
]);
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "marker", name)),
path: path,
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: Vec::new(),

View File

@@ -29,7 +29,7 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "clone", "Clone")),
path: path_std!(cx, core::clone::Clone),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@@ -58,7 +58,7 @@ fn cs_clone(
let ctor_path;
let all_fields;
let fn_path = vec![
cx.ident_of("std"),
cx.ident_of_std("core"),
cx.ident_of("clone"),
cx.ident_of("Clone"),
cx.ident_of("clone"),

View File

@@ -70,7 +70,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
ret_ty: Literal(path!(bool)),
attributes: attrs,
combine_substructure: combine_substructure(box |a, b, c| {
$f(a, b, c)
@@ -82,7 +82,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "cmp", "PartialEq")),
path: path_std!(cx, core::cmp::PartialEq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(

View File

@@ -36,7 +36,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
ret_ty: Literal(path!(bool)),
attributes: attrs,
combine_substructure: combine_substructure(box |cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
@@ -45,8 +45,8 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
} }
}
let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
let ordering_ty = Literal(path_std!(cx, core::cmp::Ordering));
let ret_ty = Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec![box ordering_ty],
true));
@@ -69,7 +69,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: vec![],
path: Path::new(vec!["std", "cmp", "PartialOrd"]),
path: path_std!(cx, core::cmp::PartialOrd),
additional_bounds: vec![],
generics: LifetimeBounds::empty(),
methods: vec![
@@ -107,7 +107,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__test");
let ordering = cx.path_global(span,
vec!(cx.ident_of("std"),
vec!(cx.ident_of_std("core"),
cx.ident_of("cmp"),
cx.ident_of("Ordering"),
cx.ident_of("Equal")));
@@ -115,7 +115,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
let equals_expr = cx.expr_some(span, ordering);
let partial_cmp_path = vec![
cx.ident_of("std"),
cx.ident_of_std("core"),
cx.ident_of("cmp"),
cx.ident_of("PartialOrd"),
cx.ident_of("partial_cmp"),

View File

@@ -46,7 +46,7 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "cmp", "Eq")),
path: path_std!(cx, core::cmp::Eq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(

View File

@@ -30,7 +30,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "cmp", "Ord")),
path: path_std!(cx, core::cmp::Ord),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@@ -39,7 +39,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
attributes: attrs,
combine_substructure: combine_substructure(box |a, b, c| {
cs_cmp(a, b, c)
@@ -65,13 +65,13 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__test");
let equals_path = cx.path_global(span,
vec!(cx.ident_of("std"),
vec!(cx.ident_of_std("core"),
cx.ident_of("cmp"),
cx.ident_of("Ordering"),
cx.ident_of("Equal")));
let cmp_path = vec![
cx.ident_of("std"),
cx.ident_of_std("core"),
cx.ident_of("cmp"),
cx.ident_of("Ord"),
cx.ident_of("cmp"),

View File

@@ -49,6 +49,12 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
krate: &'static str) where
F: FnOnce(P<Item>),
{
if !cx.use_std {
// FIXME(#21880): lift this requirement.
cx.span_err(span, "this trait cannot be derived with #![no_std]");
return;
}
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
@@ -68,7 +74,7 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
args: vec!(Ptr(box Literal(Path::new_local("__D")),
Borrowed(None, MutMutable))),
ret_ty: Literal(Path::new_(
vec!("std", "result", "Result"),
pathvec_std!(cx, core::result::Result),
None,
vec!(box Self, box Literal(Path::new_(
vec!["__D", "Error"], None, vec![], false

View File

@@ -29,7 +29,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "default", "Default")),
path: path_std!(cx, core::default::Default),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@@ -52,7 +52,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
let default_ident = vec!(
cx.ident_of("std"),
cx.ident_of_std("core"),
cx.ident_of("default"),
cx.ident_of("Default"),
cx.ident_of("default")

View File

@@ -125,6 +125,12 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
krate: &'static str) where
F: FnOnce(P<Item>),
{
if !cx.use_std {
// FIXME(#21880): lift this requirement.
cx.span_err(span, "this trait cannot be derived with #![no_std]");
return;
}
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
@@ -144,7 +150,7 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
args: vec!(Ptr(box Literal(Path::new_local("__S")),
Borrowed(None, MutMutable))),
ret_ty: Literal(Path::new_(
vec!("std", "result", "Result"),
pathvec_std!(cx, core::result::Result),
None,
vec!(box Tuple(Vec::new()), box Literal(Path::new_(
vec!["__S", "Error"], None, vec![], false

View File

@@ -25,13 +25,13 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
F: FnOnce(P<Item>),
{
let path = Path::new_(vec!("std", "hash", "Hash"), None,
let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
vec!(box Literal(Path::new_local("__S"))), true);
let generics = LifetimeBounds {
lifetimes: Vec::new(),
bounds: vec!(("__S",
vec!(Path::new(vec!("std", "hash", "Writer")),
Path::new(vec!("std", "hash", "Hasher"))))),
vec!(path_std!(cx, core::hash::Writer),
path_std!(cx, core::hash::Hasher)))),
};
let args = Path::new_local("__S");
let inline = cx.meta_word(span, InternedString::new("inline"));
@@ -69,7 +69,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
let call_hash = |span, thing_expr| {
let hash_path = {
let strs = vec![
cx.ident_of("std"),
cx.ident_of_std("core"),
cx.ident_of("hash"),
cx.ident_of("Hash"),
cx.ident_of("hash"),

View File

@@ -18,6 +18,34 @@ use ext::base::ExtCtxt;
use codemap::Span;
use ptr::P;
macro_rules! pathvec {
($($x:ident)::+) => (
vec![ $( stringify!($x) ),+ ]
)
}
macro_rules! path {
($($x:tt)*) => (
::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
)
}
macro_rules! pathvec_std {
($cx:expr, $first:ident :: $($rest:ident)::+) => (
if $cx.use_std {
pathvec!(std :: $($rest)::+)
} else {
pathvec!($first :: $($rest)::+)
}
)
}
macro_rules! path_std {
($($x:tt)*) => (
::ext::deriving::generic::ty::Path::new( pathvec_std!( $($x)* ) )
)
}
pub mod bounds;
pub mod clone;
pub mod encodable;

View File

@@ -30,7 +30,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "num", "FromPrimitive")),
path: path_std!(cx, core::num::FromPrimitive),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@@ -38,9 +38,8 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
name: "from_i64",
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(
Literal(Path::new(vec!("i64")))),
ret_ty: Literal(Path::new_(vec!("std", "option", "Option"),
args: vec!(Literal(path!(i64))),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(box Self),
true)),
@@ -54,9 +53,8 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
name: "from_u64",
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(
Literal(Path::new(vec!("u64")))),
ret_ty: Literal(Path::new_(vec!("std", "option", "Option"),
args: vec!(Literal(path!(u64))),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(box Self),
true)),

View File

@@ -28,10 +28,16 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
"`#[derive(Rand)]` is deprecated in favour of `#[derive_Rand]` from \
`rand_macros` on crates.io");
if !cx.use_std {
// FIXME(#21880): lift this requirement.
cx.span_err(span, "this trait cannot be derived with #![no_std]");
return;
}
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!("std", "rand", "Rand")),
path: path!(std::rand::Rand),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@@ -40,7 +46,7 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds {
lifetimes: Vec::new(),
bounds: vec!(("R",
vec!( Path::new(vec!("std", "rand", "Rng")) )))
vec!( path!(std::rand::Rng) ))),
},
explicit_self: None,
args: vec!(

View File

@@ -29,13 +29,13 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
F: FnOnce(P<Item>),
{
// &mut ::std::fmt::Formatter
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
let fmtr = Ptr(box Literal(path_std!(cx, core::fmt::Formatter)),
Borrowed(None, ast::MutMutable));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: Path::new(vec!["std", "fmt", "Debug"]),
path: path_std!(cx, core::fmt::Debug),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec![
@@ -44,7 +44,7 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec!(fmtr),
ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
ret_ty: Literal(path_std!(cx, core::fmt::Result)),
attributes: Vec::new(),
combine_substructure: combine_substructure(box |a, b, c| {
show_substructure(a, b, c)

View File

@@ -34,7 +34,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
Err(..) => {
cx.expr_path(cx.path_all(sp,
true,
vec!(cx.ident_of("std"),
vec!(cx.ident_of_std("core"),
cx.ident_of("option"),
cx.ident_of("Option"),
cx.ident_of("None")),
@@ -50,7 +50,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
}
Ok(s) => {
cx.expr_call_global(sp,
vec!(cx.ident_of("std"),
vec!(cx.ident_of_std("core"),
cx.ident_of("option"),
cx.ident_of("Option"),
cx.ident_of("Some")),

View File

@@ -31,6 +31,7 @@ use ptr::P;
use util::small_vector::SmallVector;
use visit;
use visit::Visitor;
use std_inject;
pub fn expand_type(t: P<ast::Ty>,
fld: &mut MacroExpander,
@@ -278,7 +279,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
let match_expr = {
let next_path = {
let strs = vec![
fld.cx.ident_of("std"),
fld.cx.ident_of_std("core"),
fld.cx.ident_of("iter"),
fld.cx.ident_of("Iterator"),
fld.cx.ident_of("next"),
@@ -311,7 +312,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
let into_iter_expr = {
let into_iter_path = {
let strs = vec![
fld.cx.ident_of("std"),
fld.cx.ident_of_std("core"),
fld.cx.ident_of("iter"),
fld.cx.ident_of("IntoIterator"),
fld.cx.ident_of("into_iter"),
@@ -1429,6 +1430,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
user_exts: Vec<NamedSyntaxExtension>,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
cx.use_std = std_inject::use_std(&c);
let mut expander = MacroExpander::new(&mut cx);
for def in imported_macros {

View File

@@ -302,7 +302,7 @@ impl<'a, 'b> Context<'a, 'b> {
}
fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec<ast::Ident> {
vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"),
vec![ecx.ident_of_std("core"), ecx.ident_of("fmt"), ecx.ident_of("rt"),
ecx.ident_of("v1"), ecx.ident_of(s)]
}
@@ -576,7 +576,7 @@ impl<'a, 'b> Context<'a, 'b> {
};
self.ecx.expr_call_global(self.fmtsp, vec!(
self.ecx.ident_of("std"),
self.ecx.ident_of_std("core"),
self.ecx.ident_of("fmt"),
self.ecx.ident_of("Arguments"),
self.ecx.ident_of(fn_name)), fn_args)
@@ -607,7 +607,7 @@ impl<'a, 'b> Context<'a, 'b> {
}
Unsigned => {
return ecx.expr_call_global(sp, vec![
ecx.ident_of("std"),
ecx.ident_of_std("core"),
ecx.ident_of("fmt"),
ecx.ident_of("ArgumentV1"),
ecx.ident_of("from_uint")], vec![arg])
@@ -615,12 +615,12 @@ impl<'a, 'b> Context<'a, 'b> {
};
let format_fn = ecx.path_global(sp, vec![
ecx.ident_of("std"),
ecx.ident_of_std("core"),
ecx.ident_of("fmt"),
ecx.ident_of(trait_),
ecx.ident_of("fmt")]);
ecx.expr_call_global(sp, vec![
ecx.ident_of("std"),
ecx.ident_of_std("core"),
ecx.ident_of("fmt"),
ecx.ident_of("ArgumentV1"),
ecx.ident_of("new")], vec![arg, ecx.expr_path(format_fn)])