mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-21 04:03:11 +00:00
auto merge of #12066 : huonw/rust/show2, r=alexcrichton
- Convert the formatting traits to `&self` rather than `_: &Self` - Rejig `syntax::ext::{format,deriving}` a little in preparation - Implement `#[deriving(Show)]`
This commit is contained in:
commit
dde2e0b386
@ -1969,13 +1969,14 @@ impl<T: Eq> Eq for Foo<T> {
|
||||
Supported traits for `deriving` are:
|
||||
|
||||
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
|
||||
* Serialization: `Encodable`, `Decodable`. These require `extra`.
|
||||
* Serialization: `Encodable`, `Decodable`. These require `serialize`.
|
||||
* `Clone` and `DeepClone`, to perform (deep) copies.
|
||||
* `IterBytes`, to iterate over the bytes in a data type.
|
||||
* `Rand`, to create a random instance of a data type.
|
||||
* `Default`, to create an empty instance of a data type.
|
||||
* `Zero`, to create an zero instance of a numeric data type.
|
||||
* `FromPrimitive`, to create an instance from a numeric primitve.
|
||||
* `FromPrimitive`, to create an instance from a numeric primitive.
|
||||
* `Show`, to format a value using the `{}` formatter.
|
||||
|
||||
### Stability
|
||||
One can indicate the stability of an API using the following attributes:
|
||||
|
@ -2523,7 +2523,7 @@ enum ABC { A, B, C }
|
||||
|
||||
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
|
||||
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
|
||||
`IterBytes`, `Rand`, `Default`, `Zero`, and `ToStr`.
|
||||
`IterBytes`, `Rand`, `Default`, `Zero`, `FromPrimitive` and `Show`.
|
||||
|
||||
# Crates and the module system
|
||||
|
||||
|
@ -118,7 +118,8 @@ traits = {
|
||||
for (trait, supers, errs) in [('Rand', [], 1),
|
||||
('Clone', [], 1), ('DeepClone', ['Clone'], 1),
|
||||
('Eq', [], 2), ('Ord', [], 8),
|
||||
('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1)]:
|
||||
('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1),
|
||||
('Show', [], 1)]:
|
||||
traits[trait] = (ALL, supers, errs)
|
||||
|
||||
for (trait, (types, super_traits, error_count)) in traits.items():
|
||||
|
@ -20,10 +20,10 @@ use std::fmt;
|
||||
pub struct Escape<'a>(&'a str);
|
||||
|
||||
impl<'a> fmt::Show for Escape<'a> {
|
||||
fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Because the internet is always right, turns out there's not that many
|
||||
// characters to escape: http://stackoverflow.com/questions/7381974
|
||||
let Escape(s) = *s;
|
||||
let Escape(s) = *self;
|
||||
let pile_o_bits = s.as_slice();
|
||||
let mut last = 0;
|
||||
for (i, ch) in s.bytes().enumerate() {
|
||||
|
@ -48,23 +48,23 @@ impl PuritySpace {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Generics {
|
||||
fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) }
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
||||
if_ok!(f.buf.write("<".as_bytes()));
|
||||
|
||||
for (i, life) in g.lifetimes.iter().enumerate() {
|
||||
for (i, life) in self.lifetimes.iter().enumerate() {
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *life));
|
||||
}
|
||||
|
||||
if g.type_params.len() > 0 {
|
||||
if g.lifetimes.len() > 0 {
|
||||
if self.type_params.len() > 0 {
|
||||
if self.lifetimes.len() > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
|
||||
for (i, tp) in g.type_params.iter().enumerate() {
|
||||
for (i, tp) in self.type_params.iter().enumerate() {
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()))
|
||||
}
|
||||
@ -87,16 +87,16 @@ impl fmt::Show for clean::Generics {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Lifetime {
|
||||
fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(f.buf.write("'".as_bytes()));
|
||||
if_ok!(f.buf.write(l.get_ref().as_bytes()));
|
||||
if_ok!(f.buf.write(self.get_ref().as_bytes()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::TyParamBound {
|
||||
fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *bound {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::RegionBound => {
|
||||
f.buf.write("'static".as_bytes())
|
||||
}
|
||||
@ -108,11 +108,11 @@ impl fmt::Show for clean::TyParamBound {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Path {
|
||||
fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if path.global {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.global {
|
||||
if_ok!(f.buf.write("::".as_bytes()))
|
||||
}
|
||||
for (i, seg) in path.segments.iter().enumerate() {
|
||||
for (i, seg) in self.segments.iter().enumerate() {
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write("::".as_bytes()))
|
||||
}
|
||||
@ -297,8 +297,8 @@ fn typarams(w: &mut io::Writer,
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Type {
|
||||
fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *g {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::TyParamBinder(id) | clean::Generic(id) => {
|
||||
local_data::get(cache_key, |cache| {
|
||||
let m = cache.unwrap().get();
|
||||
@ -405,18 +405,18 @@ impl fmt::Show for clean::Type {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::FnDecl {
|
||||
fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
args = d.inputs,
|
||||
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = d.output)
|
||||
args = self.inputs,
|
||||
arrow = match self.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = self.output)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for ~[clean::Argument] {
|
||||
fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut args = ~"";
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
for (i, input) in self.iter().enumerate() {
|
||||
if i > 0 { args.push_str(", "); }
|
||||
if input.name.len() > 0 {
|
||||
args.push_str(format!("{}: ", input.name));
|
||||
@ -428,8 +428,8 @@ impl fmt::Show for ~[clean::Argument] {
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Method<'a> {
|
||||
fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *m;
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *self;
|
||||
let mut args = ~"";
|
||||
match *selfty {
|
||||
clean::SelfStatic => {},
|
||||
@ -463,8 +463,8 @@ impl<'a> fmt::Show for Method<'a> {
|
||||
}
|
||||
|
||||
impl fmt::Show for VisSpace {
|
||||
fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.get() {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.get() {
|
||||
Some(ast::Public) => write!(f.buf, "pub "),
|
||||
Some(ast::Private) => write!(f.buf, "priv "),
|
||||
Some(ast::Inherited) | None => Ok(())
|
||||
@ -473,8 +473,8 @@ impl fmt::Show for VisSpace {
|
||||
}
|
||||
|
||||
impl fmt::Show for PuritySpace {
|
||||
fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match p.get() {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.get() {
|
||||
ast::UnsafeFn => write!(f.buf, "unsafe "),
|
||||
ast::ExternFn => write!(f.buf, "extern "),
|
||||
ast::ImpureFn => Ok(())
|
||||
@ -483,8 +483,8 @@ impl fmt::Show for PuritySpace {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ViewPath {
|
||||
fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *v {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::SimpleImport(ref name, ref src) => {
|
||||
if *name == src.path.segments.last().unwrap().name {
|
||||
write!(f.buf, "use {};", *src)
|
||||
@ -510,14 +510,14 @@ impl fmt::Show for clean::ViewPath {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ImportSource {
|
||||
fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.did {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.did {
|
||||
// FIXME: shouldn't be restricted to just local imports
|
||||
Some(did) if ast_util::is_local(did) => {
|
||||
resolved_path(f.buf, did.node, &v.path, true)
|
||||
resolved_path(f.buf, did.node, &self.path, true)
|
||||
}
|
||||
_ => {
|
||||
for (i, seg) in v.path.segments.iter().enumerate() {
|
||||
for (i, seg) in self.path.segments.iter().enumerate() {
|
||||
if i > 0 {
|
||||
if_ok!(write!(f.buf, "::"))
|
||||
}
|
||||
@ -530,21 +530,21 @@ impl fmt::Show for clean::ImportSource {
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ViewListIdent {
|
||||
fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.source {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.source {
|
||||
// FIXME: shouldn't be limited to just local imports
|
||||
Some(did) if ast_util::is_local(did) => {
|
||||
let path = clean::Path {
|
||||
global: false,
|
||||
segments: ~[clean::PathSegment {
|
||||
name: v.name.clone(),
|
||||
name: self.name.clone(),
|
||||
lifetimes: ~[],
|
||||
types: ~[],
|
||||
}]
|
||||
};
|
||||
resolved_path(f.buf, did.node, &path, false)
|
||||
}
|
||||
_ => write!(f.buf, "{}", v.name),
|
||||
_ => write!(f.buf, "{}", self.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,8 +211,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Markdown<'a> {
|
||||
fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Markdown(md) = *md;
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Markdown(md) = *self;
|
||||
// This is actually common enough to special-case
|
||||
if md.len() == 0 { return Ok(()) }
|
||||
render(fmt.buf, md.as_slice())
|
||||
|
@ -801,8 +801,8 @@ impl<'a> Item<'a> {
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Item<'a> {
|
||||
fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match attr::find_stability(it.item.attrs.iter()) {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match attr::find_stability(self.item.attrs.iter()) {
|
||||
Some(ref stability) => {
|
||||
if_ok!(write!(fmt.buf,
|
||||
"<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
|
||||
@ -815,29 +815,29 @@ impl<'a> fmt::Show for Item<'a> {
|
||||
None => {}
|
||||
}
|
||||
|
||||
if it.cx.include_sources {
|
||||
if self.cx.include_sources {
|
||||
let mut path = ~[];
|
||||
clean_srcpath(it.item.source.filename.as_bytes(), |component| {
|
||||
clean_srcpath(self.item.source.filename.as_bytes(), |component| {
|
||||
path.push(component.to_owned());
|
||||
});
|
||||
let href = if it.item.source.loline == it.item.source.hiline {
|
||||
format!("{}", it.item.source.loline)
|
||||
let href = if self.item.source.loline == self.item.source.hiline {
|
||||
format!("{}", self.item.source.loline)
|
||||
} else {
|
||||
format!("{}-{}", it.item.source.loline, it.item.source.hiline)
|
||||
format!("{}-{}", self.item.source.loline, self.item.source.hiline)
|
||||
};
|
||||
if_ok!(write!(fmt.buf,
|
||||
"<a class='source'
|
||||
href='{root}src/{crate}/{path}.html\\#{href}'>\
|
||||
[src]</a>",
|
||||
root = it.cx.root_path,
|
||||
crate = it.cx.layout.crate,
|
||||
root = self.cx.root_path,
|
||||
crate = self.cx.layout.crate,
|
||||
path = path.connect("/"),
|
||||
href = href));
|
||||
}
|
||||
|
||||
// Write the breadcrumb trail header for the top
|
||||
if_ok!(write!(fmt.buf, "<h1 class='fqn'>"));
|
||||
match it.item.inner {
|
||||
match self.item.inner {
|
||||
clean::ModuleItem(..) => if_ok!(write!(fmt.buf, "Module ")),
|
||||
clean::FunctionItem(..) => if_ok!(write!(fmt.buf, "Function ")),
|
||||
clean::TraitItem(..) => if_ok!(write!(fmt.buf, "Trait ")),
|
||||
@ -845,8 +845,8 @@ impl<'a> fmt::Show for Item<'a> {
|
||||
clean::EnumItem(..) => if_ok!(write!(fmt.buf, "Enum ")),
|
||||
_ => {}
|
||||
}
|
||||
let cur = it.cx.current.as_slice();
|
||||
let amt = if it.ismodule() { cur.len() - 1 } else { cur.len() };
|
||||
let cur = self.cx.current.as_slice();
|
||||
let amt = if self.ismodule() { cur.len() - 1 } else { cur.len() };
|
||||
for (i, component) in cur.iter().enumerate().take(amt) {
|
||||
let mut trail = ~"";
|
||||
for _ in range(0, cur.len() - i - 1) {
|
||||
@ -856,17 +856,17 @@ impl<'a> fmt::Show for Item<'a> {
|
||||
trail, component.as_slice()));
|
||||
}
|
||||
if_ok!(write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>",
|
||||
shortty(it.item), it.item.name.get_ref().as_slice()));
|
||||
shortty(self.item), self.item.name.get_ref().as_slice()));
|
||||
|
||||
match it.item.inner {
|
||||
clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
|
||||
it.item, m.items),
|
||||
match self.item.inner {
|
||||
clean::ModuleItem(ref m) => item_module(fmt.buf, self.cx,
|
||||
self.item, m.items),
|
||||
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
|
||||
item_function(fmt.buf, it.item, f),
|
||||
clean::TraitItem(ref t) => item_trait(fmt.buf, it.item, t),
|
||||
clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
|
||||
clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
|
||||
clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t),
|
||||
item_function(fmt.buf, self.item, f),
|
||||
clean::TraitItem(ref t) => item_trait(fmt.buf, self.item, t),
|
||||
clean::StructItem(ref s) => item_struct(fmt.buf, self.item, s),
|
||||
clean::EnumItem(ref e) => item_enum(fmt.buf, self.item, e),
|
||||
clean::TypedefItem(ref t) => item_typedef(fmt.buf, self.item, t),
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
@ -992,9 +992,8 @@ fn item_module(w: &mut Writer, cx: &Context,
|
||||
clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
|
||||
struct Initializer<'a>(&'a str);
|
||||
impl<'a> fmt::Show for Initializer<'a> {
|
||||
fn fmt(s: &Initializer<'a>,
|
||||
f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Initializer(s) = *s;
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Initializer(s) = *self;
|
||||
if s.len() == 0 { return Ok(()); }
|
||||
if_ok!(write!(f.buf, "<code> = </code>"));
|
||||
let tag = if s.contains("\n") { "pre" } else { "code" };
|
||||
@ -1518,9 +1517,9 @@ fn item_typedef(w: &mut Writer, it: &clean::Item,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Sidebar<'a> {
|
||||
fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let cx = s.cx;
|
||||
let it = s.item;
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let cx = self.cx;
|
||||
let it = self.item;
|
||||
if_ok!(write!(fmt.buf, "<p class='location'>"));
|
||||
let len = cx.current.len() - if it.is_mod() {1} else {0};
|
||||
for (i, name) in cx.current.iter().take(len).enumerate() {
|
||||
@ -1588,8 +1587,8 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> {
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Source<'a> {
|
||||
fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Source(s) = *s;
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Source(s) = *self;
|
||||
let lines = s.lines().len();
|
||||
let mut cols = 0;
|
||||
let mut tmp = lines;
|
||||
|
@ -36,6 +36,7 @@
|
||||
use std::char;
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::fmt::Show;
|
||||
use std::option::{Option, Some, None};
|
||||
use std::to_str::ToStr;
|
||||
|
||||
@ -62,10 +63,10 @@ impl cmp::Ord for Identifier {
|
||||
|
||||
impl fmt::Show for Identifier {
|
||||
#[inline]
|
||||
fn fmt(version: &Identifier, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *version {
|
||||
Numeric(ref n) => fmt::Show::fmt(n, f),
|
||||
AlphaNumeric(ref s) => fmt::Show::fmt(s, f)
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Numeric(ref n) => n.fmt(f),
|
||||
AlphaNumeric(ref s) => s.fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,20 +98,20 @@ pub struct Version {
|
||||
|
||||
impl fmt::Show for Version {
|
||||
#[inline]
|
||||
fn fmt(version: &Version, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(write!(f.buf, "{}.{}.{}", version.major, version.minor, version.patch))
|
||||
if !version.pre.is_empty() {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(write!(f.buf, "{}.{}.{}", self.major, self.minor, self.patch))
|
||||
if !self.pre.is_empty() {
|
||||
if_ok!(write!(f.buf, "-"));
|
||||
for (i, x) in version.pre.iter().enumerate() {
|
||||
for (i, x) in self.pre.iter().enumerate() {
|
||||
if i != 0 { if_ok!(write!(f.buf, ".")) };
|
||||
if_ok!(fmt::Show::fmt(x, f));
|
||||
if_ok!(x.fmt(f));
|
||||
}
|
||||
}
|
||||
if !version.build.is_empty() {
|
||||
if !self.build.is_empty() {
|
||||
if_ok!(write!(f.buf, "+"));
|
||||
for (i, x) in version.build.iter().enumerate() {
|
||||
for (i, x) in self.build.iter().enumerate() {
|
||||
if i != 0 { if_ok!(write!(f.buf, ".")) };
|
||||
if_ok!(fmt::Show::fmt(x, f));
|
||||
if_ok!(x.fmt(f));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -166,11 +166,11 @@ method of the signature:
|
||||
# mod fmt { pub type Result = (); }
|
||||
# struct T;
|
||||
# trait SomeName<T> {
|
||||
fn fmt(value: &T, f: &mut std::fmt::Formatter) -> fmt::Result;
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result;
|
||||
# }
|
||||
```
|
||||
|
||||
Your type will be passed by-reference in `value`, and then the function should
|
||||
Your type will be passed as `self` by-reference, and then the function should
|
||||
emit output into the `f.buf` stream. It is up to each format trait
|
||||
implementation to correctly adhere to the requested formatting parameters. The
|
||||
values of these parameters will be listed in the fields of the `Formatter`
|
||||
@ -195,19 +195,19 @@ struct Vector2D {
|
||||
}
|
||||
|
||||
impl fmt::Show for Vector2D {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// The `f.buf` value is of the type `&mut io::Writer`, which is what th
|
||||
// write! macro is expecting. Note that this formatting ignores the
|
||||
// various flags provided to format strings.
|
||||
write!(f.buf, "({}, {})", obj.x, obj.y)
|
||||
write!(f.buf, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
// Different traits allow different forms of output of a type. The meaning of
|
||||
// this format is to print the magnitude of a vector.
|
||||
impl fmt::Binary for Vector2D {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64;
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let magnitude = (self.x * self.x + self.y * self.y) as f64;
|
||||
let magnitude = magnitude.sqrt();
|
||||
|
||||
// Respect the formatting flags by using the helper method
|
||||
@ -558,50 +558,50 @@ pub struct Arguments<'a> {
|
||||
/// to this trait. There is not an explicit way of selecting this trait to be
|
||||
/// used for formatting, it is only if no other format is specified.
|
||||
#[allow(missing_doc)]
|
||||
pub trait Show { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Show { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
|
||||
/// Format trait for the `b` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Bool { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Bool { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `c` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Char { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Char { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `i` and `d` characters
|
||||
#[allow(missing_doc)]
|
||||
pub trait Signed { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Signed { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `u` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Unsigned { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Unsigned { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `o` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Octal { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Octal { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `b` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Binary { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Binary { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `x` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait LowerHex { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait LowerHex { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `X` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait UpperHex { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait UpperHex { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `s` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait String { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait String { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `?` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Poly { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Poly { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `p` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Pointer { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Pointer { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `f` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Float { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait Float { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `e` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait LowerExp { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait LowerExp { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `E` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait UpperExp { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
pub trait UpperExp { fn fmt(&self, &mut Formatter) -> Result; }
|
||||
|
||||
// FIXME #11938 - UFCS would make us able call the above methods
|
||||
// directly Show::show(x, fmt).
|
||||
@ -615,7 +615,7 @@ macro_rules! uniform_fn_call_workaround {
|
||||
$(
|
||||
#[doc(hidden)]
|
||||
pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
|
||||
$trait_::fmt(x, fmt)
|
||||
x.fmt(fmt)
|
||||
}
|
||||
)*
|
||||
}
|
||||
@ -1042,44 +1042,44 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
|
||||
/// (such as for select), then it invokes this method.
|
||||
#[doc(hidden)] #[inline]
|
||||
pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
|
||||
argument(String::fmt, s)
|
||||
argument(secret_string, s)
|
||||
}
|
||||
|
||||
/// When the compiler determines that the type of an argument *must* be a uint
|
||||
/// (such as for plural), then it invokes this method.
|
||||
#[doc(hidden)] #[inline]
|
||||
pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
|
||||
argument(Unsigned::fmt, s)
|
||||
argument(secret_unsigned, s)
|
||||
}
|
||||
|
||||
// Implementations of the core formatting traits
|
||||
|
||||
impl Bool for bool {
|
||||
fn fmt(b: &bool, f: &mut Formatter) -> Result {
|
||||
String::fmt(&(if *b {"true"} else {"false"}), f)
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
secret_string(&(if *self {"true"} else {"false"}), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: str::Str> String for T {
|
||||
fn fmt(s: &T, f: &mut Formatter) -> Result {
|
||||
f.pad(s.as_slice())
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.pad(self.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl Char for char {
|
||||
fn fmt(c: &char, f: &mut Formatter) -> Result {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
let mut utf8 = [0u8, ..4];
|
||||
let amt = c.encode_utf8(utf8);
|
||||
let amt = self.encode_utf8(utf8);
|
||||
let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) };
|
||||
String::fmt(&s, f)
|
||||
secret_string(&s, f)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
|
||||
$name:ident, $prefix:expr) => {
|
||||
impl $name for $ty {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*c as $into, $base, |buf| {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*self as $into, $base, |buf| {
|
||||
f.pad_integral(buf, $prefix, true)
|
||||
})
|
||||
}
|
||||
@ -1087,8 +1087,8 @@ macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
|
||||
})
|
||||
macro_rules! upper_hex(($ty:ident, $into:ident) => {
|
||||
impl UpperHex for $ty {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*c as $into, 16, |buf| {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*self as $into, 16, |buf| {
|
||||
upperhex(buf, f)
|
||||
})
|
||||
}
|
||||
@ -1112,9 +1112,9 @@ macro_rules! integer(($signed:ident, $unsigned:ident) => {
|
||||
// Signed is special because it actuall emits the negative sign,
|
||||
// nothing else should do that, however.
|
||||
impl Signed for $signed {
|
||||
fn fmt(c: &$signed, f: &mut Formatter) -> Result {
|
||||
::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
|
||||
f.pad_integral(buf, "", *c >= 0)
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
::$unsigned::to_str_bytes(self.abs() as $unsigned, 10, |buf| {
|
||||
f.pad_integral(buf, "", *self >= 0)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1138,35 +1138,35 @@ integer!(i64, u64)
|
||||
|
||||
macro_rules! floating(($ty:ident) => {
|
||||
impl Float for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exact(f.abs(), i),
|
||||
None => ::$ty::to_str_digits(f.abs(), 6)
|
||||
Some(i) => ::$ty::to_str_exact(self.abs(), i),
|
||||
None => ::$ty::to_str_digits(self.abs(), 6)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
fmt.pad_integral(s.as_bytes(), "", *self >= 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl LowerExp for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false),
|
||||
None => ::$ty::to_str_exp_digits(f.abs(), 6, false)
|
||||
Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, false),
|
||||
None => ::$ty::to_str_exp_digits(self.abs(), 6, false)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
fmt.pad_integral(s.as_bytes(), "", *self >= 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl UpperExp for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true),
|
||||
None => ::$ty::to_str_exp_digits(f.abs(), 6, true)
|
||||
Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true),
|
||||
None => ::$ty::to_str_exp_digits(self.abs(), 6, true)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
fmt.pad_integral(s.as_bytes(), "", *self >= 0.0)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1174,16 +1174,16 @@ floating!(f32)
|
||||
floating!(f64)
|
||||
|
||||
impl<T> Poly for T {
|
||||
fn fmt(t: &T, f: &mut Formatter) -> Result {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
match (f.width, f.precision) {
|
||||
(None, None) => {
|
||||
repr::write_repr(f.buf, t)
|
||||
repr::write_repr(f.buf, self)
|
||||
}
|
||||
|
||||
// If we have a specified width for formatting, then we have to make
|
||||
// this allocation of a new string
|
||||
_ => {
|
||||
let s = repr::repr_to_str(t);
|
||||
let s = repr::repr_to_str(self);
|
||||
f.pad(s)
|
||||
}
|
||||
}
|
||||
@ -1191,16 +1191,16 @@ impl<T> Poly for T {
|
||||
}
|
||||
|
||||
impl<T> Pointer for *T {
|
||||
fn fmt(t: &*T, f: &mut Formatter) -> Result {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.flags |= 1 << (parse::FlagAlternate as uint);
|
||||
::uint::to_str_bytes(*t as uint, 16, |buf| {
|
||||
::uint::to_str_bytes(*self as uint, 16, |buf| {
|
||||
f.pad_integral(buf, "0x", true)
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<T> Pointer for *mut T {
|
||||
fn fmt(t: &*mut T, f: &mut Formatter) -> Result {
|
||||
Pointer::fmt(&(*t as *T), f)
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
secret_pointer(&(*self as *T), f)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1208,33 +1208,33 @@ impl<T> Pointer for *mut T {
|
||||
|
||||
macro_rules! delegate(($ty:ty to $other:ident) => {
|
||||
impl<'a> Show for $ty {
|
||||
fn fmt(me: &$ty, f: &mut Formatter) -> Result {
|
||||
$other::fmt(me, f)
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
(concat_idents!(secret_, $other)(self, f))
|
||||
}
|
||||
}
|
||||
})
|
||||
delegate!(int to Signed)
|
||||
delegate!( i8 to Signed)
|
||||
delegate!(i16 to Signed)
|
||||
delegate!(i32 to Signed)
|
||||
delegate!(i64 to Signed)
|
||||
delegate!(uint to Unsigned)
|
||||
delegate!( u8 to Unsigned)
|
||||
delegate!( u16 to Unsigned)
|
||||
delegate!( u32 to Unsigned)
|
||||
delegate!( u64 to Unsigned)
|
||||
delegate!(~str to String)
|
||||
delegate!(&'a str to String)
|
||||
delegate!(bool to Bool)
|
||||
delegate!(char to Char)
|
||||
delegate!(f32 to Float)
|
||||
delegate!(f64 to Float)
|
||||
delegate!(int to signed)
|
||||
delegate!( i8 to signed)
|
||||
delegate!(i16 to signed)
|
||||
delegate!(i32 to signed)
|
||||
delegate!(i64 to signed)
|
||||
delegate!(uint to unsigned)
|
||||
delegate!( u8 to unsigned)
|
||||
delegate!( u16 to unsigned)
|
||||
delegate!( u32 to unsigned)
|
||||
delegate!( u64 to unsigned)
|
||||
delegate!(~str to string)
|
||||
delegate!(&'a str to string)
|
||||
delegate!(bool to bool)
|
||||
delegate!(char to char)
|
||||
delegate!(f32 to float)
|
||||
delegate!(f64 to float)
|
||||
|
||||
impl<T> Show for *T {
|
||||
fn fmt(me: &*T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
|
||||
}
|
||||
impl<T> Show for *mut T {
|
||||
fn fmt(me: &*mut T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
|
||||
}
|
||||
|
||||
// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
|
||||
|
@ -364,9 +364,9 @@ pub struct IoError {
|
||||
}
|
||||
|
||||
impl fmt::Show for IoError {
|
||||
fn fmt(err: &IoError, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(fmt.buf.write_str(err.desc));
|
||||
match err.detail {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(fmt.buf.write_str(self.desc));
|
||||
match self.detail {
|
||||
Some(ref s) => write!(fmt.buf, " ({})", *s),
|
||||
None => Ok(())
|
||||
}
|
||||
|
@ -93,8 +93,8 @@ pub enum ProcessExit {
|
||||
|
||||
impl fmt::Show for ProcessExit {
|
||||
/// Format a ProcessExit enum, to nicely present the information.
|
||||
fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *obj {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ExitStatus(code) => write!(f.buf, "exit code: {}", code),
|
||||
ExitSignal(code) => write!(f.buf, "signal: {}", code),
|
||||
}
|
||||
|
@ -382,8 +382,8 @@ impl<T: Default> Option<T> {
|
||||
|
||||
impl<T: fmt::Show> fmt::Show for Option<T> {
|
||||
#[inline]
|
||||
fn fmt(s: &Option<T>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *s {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Some(ref t) => write!(f.buf, "Some({})", *t),
|
||||
None => write!(f.buf, "None")
|
||||
}
|
||||
|
@ -942,8 +942,8 @@ pub enum MapError {
|
||||
}
|
||||
|
||||
impl fmt::Show for MapError {
|
||||
fn fmt(val: &MapError, out: &mut fmt::Formatter) -> fmt::Result {
|
||||
let str = match *val {
|
||||
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
|
||||
let str = match *self {
|
||||
ErrFdNotAvail => "fd not available for reading or writing",
|
||||
ErrInvalidFd => "Invalid fd",
|
||||
ErrUnaligned => {
|
||||
|
@ -494,8 +494,8 @@ pub struct Display<'a, P> {
|
||||
}
|
||||
|
||||
impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
|
||||
fn fmt(d: &Display<P>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
d.with_str(|s| f.pad(s))
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.with_str(|s| f.pad(s))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,8 +208,8 @@ impl<T, E> Result<T, E> {
|
||||
|
||||
impl<T: fmt::Show, E: fmt::Show> fmt::Show for Result<T, E> {
|
||||
#[inline]
|
||||
fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *s {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Ok(ref t) => write!(f.buf, "Ok({})", *t),
|
||||
Err(ref e) => write!(f.buf, "Err({})", *e)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ pub struct MacroDef {
|
||||
}
|
||||
|
||||
pub type ItemDecorator =
|
||||
fn(&ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item];
|
||||
fn(&mut ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item];
|
||||
|
||||
pub struct BasicMacroExpander {
|
||||
expander: MacroExpanderFn,
|
||||
|
@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_clone(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -42,7 +42,7 @@ pub fn expand_deriving_clone(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
pub fn expand_deriving_deep_clone(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_deep_clone(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -74,7 +74,7 @@ pub fn expand_deriving_deep_clone(cx: &ExtCtxt,
|
||||
|
||||
fn cs_clone(
|
||||
name: &str,
|
||||
cx: &ExtCtxt, trait_span: Span,
|
||||
cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
let clone_ident = substr.method_ident;
|
||||
let ctor_ident;
|
||||
|
@ -14,17 +14,17 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_eq(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
// structures are equal if all fields are equal, and non equal, if
|
||||
// any fields are not equal or if the enum variants are different
|
||||
fn cs_eq(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
cs_and(|cx, span, _, _| cx.expr_bool(span, false),
|
||||
cx, span, substr)
|
||||
}
|
||||
fn cs_ne(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
cs_or(|cx, span, _, _| cx.expr_bool(span, true),
|
||||
cx, span, substr)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_ord(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_ord(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -51,7 +51,7 @@ pub fn expand_deriving_ord(cx: &ExtCtxt,
|
||||
}
|
||||
|
||||
/// Strict inequality.
|
||||
fn cs_op(less: bool, equal: bool, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
let op = if less {ast::BiLt} else {ast::BiGt};
|
||||
cs_fold(
|
||||
false, // need foldr,
|
||||
|
@ -14,11 +14,11 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_totaleq(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
fn cs_equals(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
fn cs_equals(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
cs_and(|cx, span, _, _| cx.expr_bool(span, false),
|
||||
cx, span, substr)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
use std::cmp::{Ordering, Equal, Less, Greater};
|
||||
|
||||
pub fn expand_deriving_totalord(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -44,7 +44,7 @@ pub fn expand_deriving_totalord(cx: &ExtCtxt,
|
||||
}
|
||||
|
||||
|
||||
pub fn ordering_const(cx: &ExtCtxt, span: Span, cnst: Ordering) -> ast::Path {
|
||||
pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path {
|
||||
let cnst = match cnst {
|
||||
Less => "Less",
|
||||
Equal => "Equal",
|
||||
@ -56,7 +56,7 @@ pub fn ordering_const(cx: &ExtCtxt, span: Span, cnst: Ordering) -> ast::Path {
|
||||
cx.ident_of(cnst)])
|
||||
}
|
||||
|
||||
pub fn cs_cmp(cx: &ExtCtxt, span: Span,
|
||||
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
let test_id = cx.ident_of("__test");
|
||||
let equals_path = ordering_const(cx, span, Equal);
|
||||
@ -106,8 +106,10 @@ pub fn cs_cmp(cx: &ExtCtxt, span: Span,
|
||||
// an earlier nonmatching variant is Less than a
|
||||
// later one.
|
||||
[(self_var, _, _),
|
||||
(other_var, _, _)] => cx.expr_path(ordering_const(cx, span,
|
||||
self_var.cmp(&other_var))),
|
||||
(other_var, _, _)] => {
|
||||
let order = ordering_const(cx, span, self_var.cmp(&other_var));
|
||||
cx.expr_path(order)
|
||||
}
|
||||
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(TotalOrd)`")
|
||||
}
|
||||
},
|
||||
|
@ -21,7 +21,7 @@ use ext::deriving::generic::*;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
pub fn expand_deriving_decodable(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -53,7 +53,7 @@ pub fn expand_deriving_decodable(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn decodable_substructure(cx: &ExtCtxt, trait_span: Span,
|
||||
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
let decoder = substr.nonself_args[0];
|
||||
let recurse = ~[cx.ident_of("serialize"),
|
||||
@ -77,7 +77,7 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span,
|
||||
trait_span,
|
||||
substr.type_ident,
|
||||
summary,
|
||||
|span, name, field| {
|
||||
|cx, span, name, field| {
|
||||
cx.expr_method_call(span, blkdecoder, read_struct_field,
|
||||
~[cx.expr_str(span, name),
|
||||
cx.expr_uint(span, field),
|
||||
@ -108,10 +108,10 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span,
|
||||
v_span,
|
||||
name,
|
||||
parts,
|
||||
|span, _, field| {
|
||||
|cx, span, _, field| {
|
||||
let idx = cx.expr_uint(span, field);
|
||||
cx.expr_method_call(span, blkdecoder, rvariant_arg,
|
||||
~[cx.expr_uint(span, field),
|
||||
lambdadecode])
|
||||
~[idx, lambdadecode])
|
||||
});
|
||||
|
||||
arms.push(cx.arm(v_span,
|
||||
@ -143,11 +143,11 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span,
|
||||
/// Create a decoder for a single enum variant/struct:
|
||||
/// - `outer_pat_ident` is the name of this enum variant/struct
|
||||
/// - `getarg` should retrieve the `uint`-th field with name `@str`.
|
||||
fn decode_static_fields(cx: &ExtCtxt,
|
||||
fn decode_static_fields(cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
outer_pat_ident: Ident,
|
||||
fields: &StaticFields,
|
||||
getarg: |Span, InternedString, uint| -> @Expr)
|
||||
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> @Expr)
|
||||
-> @Expr {
|
||||
match *fields {
|
||||
Unnamed(ref fields) => {
|
||||
@ -155,7 +155,7 @@ fn decode_static_fields(cx: &ExtCtxt,
|
||||
cx.expr_ident(trait_span, outer_pat_ident)
|
||||
} else {
|
||||
let fields = fields.iter().enumerate().map(|(i, &span)| {
|
||||
getarg(span,
|
||||
getarg(cx, span,
|
||||
token::intern_and_get_ident(format!("_field{}",
|
||||
i)),
|
||||
i)
|
||||
@ -167,9 +167,8 @@ fn decode_static_fields(cx: &ExtCtxt,
|
||||
Named(ref fields) => {
|
||||
// use the field's span to get nicer error messages.
|
||||
let fields = fields.iter().enumerate().map(|(i, &(name, span))| {
|
||||
cx.field_imm(span,
|
||||
name,
|
||||
getarg(span, token::get_ident(name.name), i))
|
||||
let arg = getarg(cx, span, token::get_ident(name.name), i);
|
||||
cx.field_imm(span, name, arg)
|
||||
}).collect();
|
||||
cx.expr_struct_ident(trait_span, outer_pat_ident, fields)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_default(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_default(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -41,7 +41,7 @@ pub fn expand_deriving_default(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn default_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
let default_ident = ~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("default"),
|
||||
|
@ -82,7 +82,7 @@ use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
use parse::token;
|
||||
|
||||
pub fn expand_deriving_encodable(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -114,7 +114,7 @@ pub fn expand_deriving_encodable(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn encodable_substructure(cx: &ExtCtxt, trait_span: Span,
|
||||
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
let encoder = substr.nonself_args[0];
|
||||
// throw an underscore in front to suppress unused variable warnings
|
||||
|
@ -194,7 +194,7 @@ mod ty;
|
||||
|
||||
pub struct TraitDef<'a> {
|
||||
/// The extension context
|
||||
cx: &'a ExtCtxt<'a>,
|
||||
cx: &'a mut ExtCtxt<'a>,
|
||||
/// The span for the current #[deriving(Foo)] header.
|
||||
span: Span,
|
||||
|
||||
@ -304,7 +304,7 @@ Combine the values of all the fields together. The last argument is
|
||||
all the fields of all the structures, see above for details.
|
||||
*/
|
||||
pub type CombineSubstructureFunc<'a> =
|
||||
'a |&ExtCtxt, Span, &Substructure| -> @Expr;
|
||||
'a |&mut ExtCtxt, Span, &Substructure| -> @Expr;
|
||||
|
||||
/**
|
||||
Deal with non-matching enum variants, the arguments are a list
|
||||
@ -312,7 +312,7 @@ representing each variant: (variant index, ast::Variant instance,
|
||||
[variant fields]), and a list of the nonself args of the type
|
||||
*/
|
||||
pub type EnumNonMatchFunc<'a> =
|
||||
'a |&ExtCtxt,
|
||||
'a |&mut ExtCtxt,
|
||||
Span,
|
||||
&[(uint, P<ast::Variant>, ~[(Span, Option<Ident>, @Expr)])],
|
||||
&[@Expr]|
|
||||
@ -356,7 +356,7 @@ impl<'a> TraitDef<'a> {
|
||||
fn create_derived_impl(&self,
|
||||
type_ident: Ident, generics: &Generics,
|
||||
methods: ~[@ast::Method]) -> @ast::Item {
|
||||
let cx = self.cx;
|
||||
let cx = &*self.cx;
|
||||
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
|
||||
|
||||
let mut trait_generics = self.generics.to_generics(cx, self.span,
|
||||
@ -764,7 +764,7 @@ impl<'a> MethodDef<'a> {
|
||||
matches_so_far: &mut ~[(uint, P<ast::Variant>,
|
||||
~[(Span, Option<Ident>, @Expr)])],
|
||||
match_count: uint) -> @Expr {
|
||||
let cx = trait_.cx;
|
||||
let cx = &trait_.cx;
|
||||
if match_count == self_args.len() {
|
||||
// we've matched against all arguments, so make the final
|
||||
// expression at the bottom of the match tree
|
||||
@ -990,7 +990,7 @@ impl<'a> TraitDef<'a> {
|
||||
prefix: &str,
|
||||
mutbl: ast::Mutability)
|
||||
-> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
|
||||
let cx = self.cx;
|
||||
let cx = &self.cx;
|
||||
|
||||
if struct_def.fields.is_empty() {
|
||||
return (
|
||||
@ -1050,7 +1050,7 @@ impl<'a> TraitDef<'a> {
|
||||
prefix: &str,
|
||||
mutbl: ast::Mutability)
|
||||
-> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
|
||||
let cx = self.cx;
|
||||
let cx = &*self.cx;
|
||||
let variant_ident = variant.node.name;
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref variant_args) => {
|
||||
@ -1093,10 +1093,10 @@ Fold the fields. `use_foldl` controls whether this is done
|
||||
left-to-right (`true`) or right-to-left (`false`).
|
||||
*/
|
||||
pub fn cs_fold(use_foldl: bool,
|
||||
f: |&ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr,
|
||||
base: @Expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
@ -1132,9 +1132,9 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
|
||||
~~~
|
||||
*/
|
||||
#[inline]
|
||||
pub fn cs_same_method(f: |&ExtCtxt, Span, ~[@Expr]| -> @Expr,
|
||||
pub fn cs_same_method(f: |&mut ExtCtxt, Span, ~[@Expr]| -> @Expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
@ -1166,10 +1166,10 @@ fields. `use_foldl` controls whether this is done left-to-right
|
||||
*/
|
||||
#[inline]
|
||||
pub fn cs_same_method_fold(use_foldl: bool,
|
||||
f: |&ExtCtxt, Span, @Expr, @Expr| -> @Expr,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr,
|
||||
base: @Expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
@ -1196,7 +1196,7 @@ on all the fields.
|
||||
#[inline]
|
||||
pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt, trait_span: Span,
|
||||
cx: &mut ExtCtxt, trait_span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
cs_same_method_fold(
|
||||
true, // foldl is good enough
|
||||
@ -1214,7 +1214,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
||||
/// cs_binop with binop == or
|
||||
#[inline]
|
||||
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt, span: Span,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
cs_binop(ast::BiOr, cx.expr_bool(span, false),
|
||||
enum_nonmatch_f,
|
||||
@ -1224,7 +1224,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
/// cs_binop with binop == and
|
||||
#[inline]
|
||||
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &ExtCtxt, span: Span,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
cs_binop(ast::BiAnd, cx.expr_bool(span, true),
|
||||
enum_nonmatch_f,
|
||||
|
@ -15,7 +15,7 @@ use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
|
||||
pub fn expand_deriving_iter_bytes(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_iter_bytes(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -45,7 +45,7 @@ pub fn expand_deriving_iter_bytes(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn iter_bytes_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
fn iter_bytes_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
let (lsb0, f)= match substr.nonself_args {
|
||||
[l, f] => (l, f),
|
||||
_ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(IterBytes)`")
|
||||
|
@ -18,8 +18,7 @@ library.
|
||||
|
||||
*/
|
||||
|
||||
use ast::{EnumDef, Ident, Item, Generics, StructDef};
|
||||
use ast::{MetaItem, MetaList, MetaNameValue, MetaWord};
|
||||
use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
|
||||
use ext::base::ExtCtxt;
|
||||
use codemap::Span;
|
||||
|
||||
@ -29,6 +28,7 @@ pub mod encodable;
|
||||
pub mod decodable;
|
||||
pub mod rand;
|
||||
pub mod to_str;
|
||||
pub mod show;
|
||||
pub mod zero;
|
||||
pub mod default;
|
||||
pub mod primitive;
|
||||
@ -45,20 +45,7 @@ pub mod totalord;
|
||||
|
||||
pub mod generic;
|
||||
|
||||
pub type ExpandDerivingStructDefFn<'a> = 'a |&ExtCtxt,
|
||||
Span,
|
||||
x: &StructDef,
|
||||
Ident,
|
||||
y: &Generics|
|
||||
-> @Item;
|
||||
pub type ExpandDerivingEnumDefFn<'a> = 'a |&ExtCtxt,
|
||||
Span,
|
||||
x: &EnumDef,
|
||||
Ident,
|
||||
y: &Generics|
|
||||
-> @Item;
|
||||
|
||||
pub fn expand_meta_deriving(cx: &ExtCtxt,
|
||||
pub fn expand_meta_deriving(cx: &mut ExtCtxt,
|
||||
_span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -97,6 +84,7 @@ pub fn expand_meta_deriving(cx: &ExtCtxt,
|
||||
"Rand" => expand!(rand::expand_deriving_rand),
|
||||
|
||||
"ToStr" => expand!(to_str::expand_deriving_to_str),
|
||||
"Show" => expand!(show::expand_deriving_show),
|
||||
|
||||
"Zero" => expand!(zero::expand_deriving_zero),
|
||||
"Default" => expand!(default::expand_deriving_default),
|
||||
|
@ -16,7 +16,7 @@ use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
pub fn expand_deriving_from_primitive(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item]) -> ~[@Item] {
|
||||
@ -65,7 +65,7 @@ pub fn expand_deriving_from_primitive(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn cs_from(name: &str, cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
let n = match substr.nonself_args {
|
||||
[n] => n,
|
||||
_ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(FromPrimitive)`")
|
||||
|
@ -16,7 +16,7 @@ use ext::build::{AstBuilder};
|
||||
use ext::deriving::generic::*;
|
||||
use opt_vec;
|
||||
|
||||
pub fn expand_deriving_rand(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_rand(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -50,7 +50,7 @@ pub fn expand_deriving_rand(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
let rng = match substr.nonself_args {
|
||||
[rng] => ~[ rng ],
|
||||
_ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
|
||||
@ -112,9 +112,8 @@ fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @
|
||||
let i_expr = cx.expr_uint(v_span, i);
|
||||
let pat = cx.pat_lit(v_span, i_expr);
|
||||
|
||||
cx.arm(v_span,
|
||||
~[ pat ],
|
||||
rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp)))
|
||||
let thing = rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp));
|
||||
cx.arm(v_span, ~[ pat ], thing)
|
||||
}).collect::<~[ast::Arm]>();
|
||||
|
||||
// _ => {} at the end. Should never occur
|
||||
@ -128,7 +127,7 @@ fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @
|
||||
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
||||
};
|
||||
|
||||
fn rand_thing(cx: &ExtCtxt,
|
||||
fn rand_thing(cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
ctor_ident: Ident,
|
||||
summary: &StaticFields,
|
||||
|
138
src/libsyntax/ext/deriving/show.rs
Normal file
138
src/libsyntax/ext/deriving/show.rs
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ast;
|
||||
use ast::{MetaItem, Item, Expr};
|
||||
use codemap::Span;
|
||||
use ext::format;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
use parse::token;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
pub fn expand_deriving_show(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
-> ~[@Item] {
|
||||
// &mut ::std::fmt::Formatter
|
||||
let fmtr = Ptr(~Literal(Path::new(~["std", "fmt", "Formatter"])),
|
||||
Borrowed(None, ast::MutMutable));
|
||||
|
||||
let trait_def = TraitDef {
|
||||
cx: cx, span: span,
|
||||
|
||||
path: Path::new(~["std", "fmt", "Show"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: "fmt",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[fmtr],
|
||||
ret_ty: Literal(Path::new(~["std", "fmt", "Result"])),
|
||||
inline: false,
|
||||
const_nonmatching: false,
|
||||
combine_substructure: show_substructure
|
||||
}
|
||||
]
|
||||
};
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
// we construct a format string and then defer to std::fmt, since that
|
||||
// knows what's up with formatting at so on.
|
||||
fn show_substructure(cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
|
||||
// <field>: {}, ... }` based on the "shape".
|
||||
//
|
||||
// Easy start: they all start with the name.
|
||||
let name = match *substr.fields {
|
||||
Struct(_) => substr.type_ident,
|
||||
EnumMatching(_, v, _) => v.node.name,
|
||||
|
||||
EnumNonMatching(..) | StaticStruct(..) | StaticEnum(..) => {
|
||||
cx.span_bug(span, "nonsensical .fields in `#[deriving(Show)]`")
|
||||
}
|
||||
};
|
||||
|
||||
let mut format_string = token::get_ident(name.name).get().to_owned();
|
||||
// the internal fields we're actually formatting
|
||||
let mut exprs = ~[];
|
||||
|
||||
// Getting harder... making the format string:
|
||||
match *substr.fields {
|
||||
// unit struct/nullary variant: no work necessary!
|
||||
Struct([]) | EnumMatching(_, _, []) => {}
|
||||
|
||||
Struct(ref fields) | EnumMatching(_, _, ref fields) => {
|
||||
if fields[0].name.is_none() {
|
||||
// tuple struct/"normal" variant
|
||||
|
||||
format_string.push_str("(");
|
||||
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
if i != 0 { format_string.push_str(", "); }
|
||||
|
||||
format_string.push_str("{}");
|
||||
|
||||
exprs.push(field.self_);
|
||||
}
|
||||
|
||||
format_string.push_str(")");
|
||||
} else {
|
||||
// normal struct/struct variant
|
||||
|
||||
format_string.push_str(" \\{");
|
||||
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
if i != 0 { format_string.push_str(","); }
|
||||
|
||||
let name = token::get_ident(field.name.unwrap().name);
|
||||
format_string.push_str(" ");
|
||||
format_string.push_str(name.get());
|
||||
format_string.push_str(": {}");
|
||||
|
||||
exprs.push(field.self_);
|
||||
}
|
||||
|
||||
format_string.push_str(" \\}");
|
||||
}
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
||||
// AST construction!
|
||||
// we're basically calling
|
||||
//
|
||||
// format_arg!(|__args| ::std::fmt::write(fmt.buf, __args), "<format_string>", exprs...)
|
||||
//
|
||||
// but doing it directly via ext::format.
|
||||
let formatter = substr.nonself_args[0];
|
||||
let buf = cx.expr_field_access(span, formatter, cx.ident_of("buf"));
|
||||
|
||||
let std_write = ~[cx.ident_of("std"), cx.ident_of("fmt"), cx.ident_of("write")];
|
||||
let args = cx.ident_of("__args");
|
||||
let write_call = cx.expr_call_global(span, std_write, ~[buf, cx.expr_ident(span, args)]);
|
||||
let format_closure = cx.lambda_expr(span, ~[args], write_call);
|
||||
|
||||
let s = token::intern_and_get_ident(format_string);
|
||||
let format_string = cx.expr_str(span, s);
|
||||
|
||||
// phew, not our responsibility any more!
|
||||
format::expand_preparsed_format_args(cx, span,
|
||||
format_closure,
|
||||
format_string, exprs, HashMap::new())
|
||||
}
|
@ -17,7 +17,7 @@ use ext::deriving::generic::*;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
pub fn expand_deriving_to_str(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_to_str(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -49,7 +49,7 @@ pub fn expand_deriving_to_str(cx: &ExtCtxt,
|
||||
// doesn't invoke the to_str() method on each field. Hence we mirror
|
||||
// the logic of the repr_to_str() method, but with tweaks to call to_str()
|
||||
// on sub-fields.
|
||||
fn to_str_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure)
|
||||
fn to_str_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure)
|
||||
-> @Expr {
|
||||
let to_str = cx.ident_of("to_str");
|
||||
|
||||
|
@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_zero(cx: &ExtCtxt,
|
||||
pub fn expand_deriving_zero(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@Item])
|
||||
@ -57,7 +57,7 @@ pub fn expand_deriving_zero(cx: &ExtCtxt,
|
||||
trait_def.expand(mitem, in_items)
|
||||
}
|
||||
|
||||
fn zero_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
|
||||
let zero_ident = ~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("num"),
|
||||
|
@ -56,78 +56,83 @@ struct Context<'a> {
|
||||
next_arg: uint,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
/// Parses the arguments from the given list of tokens, returning None if
|
||||
/// there's a parse error so we can continue parsing other format! expressions.
|
||||
fn parse_args(&mut self, sp: Span, tts: &[ast::TokenTree])
|
||||
-> (@ast::Expr, Option<@ast::Expr>) {
|
||||
let mut p = rsparse::new_parser_from_tts(self.ecx.parse_sess(),
|
||||
self.ecx.cfg(),
|
||||
tts.to_owned());
|
||||
// Parse the leading function expression (maybe a block, maybe a path)
|
||||
let extra = p.parse_expr();
|
||||
if !p.eat(&token::COMMA) {
|
||||
self.ecx.span_err(sp, "expected token: `,`");
|
||||
return (extra, None);
|
||||
}
|
||||
/// Parses the arguments from the given list of tokens, returning None
|
||||
/// if there's a parse error so we can continue parsing other format!
|
||||
/// expressions.
|
||||
///
|
||||
/// If parsing succeeds, the second return value is:
|
||||
///
|
||||
/// Some((fmtstr, unnamed arguments, named arguments))
|
||||
fn parse_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
tts: &[ast::TokenTree]) -> (@ast::Expr, Option<(@ast::Expr, ~[@ast::Expr],
|
||||
HashMap<~str, @ast::Expr>)>) {
|
||||
let mut args = ~[];
|
||||
let mut names = HashMap::<~str, @ast::Expr>::new();
|
||||
|
||||
if p.token == token::EOF {
|
||||
self.ecx.span_err(sp, "requires at least a format string argument");
|
||||
return (extra, None);
|
||||
}
|
||||
let fmtstr = p.parse_expr();
|
||||
let mut named = false;
|
||||
while p.token != token::EOF {
|
||||
if !p.eat(&token::COMMA) {
|
||||
self.ecx.span_err(sp, "expected token: `,`");
|
||||
return (extra, None);
|
||||
}
|
||||
if p.token == token::EOF { break } // accept trailing commas
|
||||
if named || (token::is_ident(&p.token) &&
|
||||
p.look_ahead(1, |t| *t == token::EQ)) {
|
||||
named = true;
|
||||
let ident = match p.token {
|
||||
token::IDENT(i, _) => {
|
||||
p.bump();
|
||||
i
|
||||
}
|
||||
_ if named => {
|
||||
self.ecx.span_err(p.span,
|
||||
"expected ident, positional arguments \
|
||||
cannot follow named arguments");
|
||||
return (extra, None);
|
||||
}
|
||||
_ => {
|
||||
self.ecx.span_err(p.span,
|
||||
format!("expected ident for named \
|
||||
argument, but found `{}`",
|
||||
p.this_token_to_str()));
|
||||
return (extra, None);
|
||||
}
|
||||
};
|
||||
let interned_name = token::get_ident(ident.name);
|
||||
let name = interned_name.get();
|
||||
p.expect(&token::EQ);
|
||||
let e = p.parse_expr();
|
||||
match self.names.find_equiv(&name) {
|
||||
None => {}
|
||||
Some(prev) => {
|
||||
self.ecx.span_err(e.span, format!("duplicate argument \
|
||||
named `{}`", name));
|
||||
self.ecx.parse_sess.span_diagnostic.span_note(
|
||||
prev.span, "previously here");
|
||||
continue
|
||||
}
|
||||
}
|
||||
self.names.insert(name.to_str(), e);
|
||||
} else {
|
||||
self.args.push(p.parse_expr());
|
||||
self.arg_types.push(None);
|
||||
}
|
||||
}
|
||||
return (extra, Some(fmtstr));
|
||||
let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(),
|
||||
ecx.cfg(),
|
||||
tts.to_owned());
|
||||
// Parse the leading function expression (maybe a block, maybe a path)
|
||||
let extra = p.parse_expr();
|
||||
if !p.eat(&token::COMMA) {
|
||||
ecx.span_err(sp, "expected token: `,`");
|
||||
return (extra, None);
|
||||
}
|
||||
|
||||
if p.token == token::EOF {
|
||||
ecx.span_err(sp, "requires at least a format string argument");
|
||||
return (extra, None);
|
||||
}
|
||||
let fmtstr = p.parse_expr();
|
||||
let mut named = false;
|
||||
while p.token != token::EOF {
|
||||
if !p.eat(&token::COMMA) {
|
||||
ecx.span_err(sp, "expected token: `,`");
|
||||
return (extra, None);
|
||||
}
|
||||
if p.token == token::EOF { break } // accept trailing commas
|
||||
if named || (token::is_ident(&p.token) &&
|
||||
p.look_ahead(1, |t| *t == token::EQ)) {
|
||||
named = true;
|
||||
let ident = match p.token {
|
||||
token::IDENT(i, _) => {
|
||||
p.bump();
|
||||
i
|
||||
}
|
||||
_ if named => {
|
||||
ecx.span_err(p.span,
|
||||
"expected ident, positional arguments \
|
||||
cannot follow named arguments");
|
||||
return (extra, None);
|
||||
}
|
||||
_ => {
|
||||
ecx.span_err(p.span,
|
||||
format!("expected ident for named argument, but found `{}`",
|
||||
p.this_token_to_str()));
|
||||
return (extra, None);
|
||||
}
|
||||
};
|
||||
let interned_name = token::get_ident(ident.name);
|
||||
let name = interned_name.get();
|
||||
p.expect(&token::EQ);
|
||||
let e = p.parse_expr();
|
||||
match names.find_equiv(&name) {
|
||||
None => {}
|
||||
Some(prev) => {
|
||||
ecx.span_err(e.span, format!("duplicate argument named `{}`", name));
|
||||
ecx.parse_sess.span_diagnostic.span_note(prev.span, "previously here");
|
||||
continue
|
||||
}
|
||||
}
|
||||
names.insert(name.to_str(), e);
|
||||
} else {
|
||||
args.push(p.parse_expr());
|
||||
}
|
||||
}
|
||||
return (extra, Some((fmtstr, args, names)));
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
/// Verifies one piece of a parse string. All errors are not emitted as
|
||||
/// fatal so we can continue giving errors about this and possibly other
|
||||
/// format strings.
|
||||
@ -758,11 +763,28 @@ impl<'a> Context<'a> {
|
||||
|
||||
pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
tts: &[ast::TokenTree]) -> base::MacResult {
|
||||
|
||||
match parse_args(ecx, sp, tts) {
|
||||
(extra, Some((efmt, args, names))) => {
|
||||
MRExpr(expand_preparsed_format_args(ecx, sp, extra, efmt, args, names))
|
||||
}
|
||||
(_, None) => MRExpr(ecx.expr_uint(sp, 2))
|
||||
}
|
||||
}
|
||||
|
||||
/// Take the various parts of `format_args!(extra, efmt, args...,
|
||||
/// name=names...)` and construct the appropriate formatting
|
||||
/// expression.
|
||||
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
extra: @ast::Expr,
|
||||
efmt: @ast::Expr, args: ~[@ast::Expr],
|
||||
names: HashMap<~str, @ast::Expr>) -> @ast::Expr {
|
||||
let arg_types = vec::from_fn(args.len(), |_| None);
|
||||
let mut cx = Context {
|
||||
ecx: ecx,
|
||||
args: ~[],
|
||||
arg_types: ~[],
|
||||
names: HashMap::new(),
|
||||
args: args,
|
||||
arg_types: arg_types,
|
||||
names: names,
|
||||
name_positions: HashMap::new(),
|
||||
name_types: HashMap::new(),
|
||||
nest_level: 0,
|
||||
@ -771,10 +793,6 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
method_statics: ~[],
|
||||
fmtsp: sp,
|
||||
};
|
||||
let (extra, efmt) = match cx.parse_args(sp, tts) {
|
||||
(extra, Some(e)) => (extra, e),
|
||||
(_, None) => { return MRExpr(cx.ecx.expr_uint(sp, 2)); }
|
||||
};
|
||||
cx.fmtsp = efmt.span;
|
||||
// Be sure to recursively expand macros just in case the format string uses
|
||||
// a macro to build the format expression.
|
||||
@ -783,7 +801,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
expr,
|
||||
"format argument must be a string literal.") {
|
||||
Some((fmt, _)) => fmt,
|
||||
None => return MacResult::dummy_expr()
|
||||
None => return efmt
|
||||
};
|
||||
|
||||
let mut parser = parse::Parser::new(fmt.get());
|
||||
@ -801,7 +819,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
match parser.errors.shift() {
|
||||
Some(error) => {
|
||||
cx.ecx.span_err(efmt.span, "invalid format string: " + error);
|
||||
return MRExpr(efmt);
|
||||
return efmt;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
@ -818,5 +836,5 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
|
||||
}
|
||||
}
|
||||
|
||||
MRExpr(cx.to_expr(extra))
|
||||
cx.to_expr(extra)
|
||||
}
|
||||
|
@ -588,8 +588,8 @@ impl BytesContainer for InternedString {
|
||||
}
|
||||
|
||||
impl fmt::Show for InternedString {
|
||||
fn fmt(obj: &InternedString, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, "{}", obj.string.as_slice())
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, "{}", self.string.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
|
||||
|
||||
#[feature(struct_variant)];
|
||||
extern mod extra;
|
||||
|
||||
|
||||
struct Error;
|
||||
|
||||
#[deriving(Show)]
|
||||
enum Enum {
|
||||
A {
|
||||
x: Error //~ ERROR
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
26
src/test/compile-fail/deriving-span-Show-enum.rs
Normal file
26
src/test/compile-fail/deriving-span-Show-enum.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
|
||||
|
||||
#[feature(struct_variant)];
|
||||
extern mod extra;
|
||||
|
||||
|
||||
struct Error;
|
||||
|
||||
#[deriving(Show)]
|
||||
enum Enum {
|
||||
A(
|
||||
Error //~ ERROR
|
||||
)
|
||||
}
|
||||
|
||||
fn main() {}
|
24
src/test/compile-fail/deriving-span-Show-struct.rs
Normal file
24
src/test/compile-fail/deriving-span-Show-struct.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
|
||||
|
||||
#[feature(struct_variant)];
|
||||
extern mod extra;
|
||||
|
||||
|
||||
struct Error;
|
||||
|
||||
#[deriving(Show)]
|
||||
struct Struct {
|
||||
x: Error //~ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
24
src/test/compile-fail/deriving-span-Show-tuple-struct.rs
Normal file
24
src/test/compile-fail/deriving-span-Show-tuple-struct.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
|
||||
|
||||
#[feature(struct_variant)];
|
||||
extern mod extra;
|
||||
|
||||
|
||||
struct Error;
|
||||
|
||||
#[deriving(Show)]
|
||||
struct Struct(
|
||||
Error //~ ERROR
|
||||
);
|
||||
|
||||
fn main() {}
|
42
src/test/run-pass/deriving-show.rs
Normal file
42
src/test/run-pass/deriving-show.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[feature(struct_variant, macro_rules)];
|
||||
|
||||
#[deriving(Show)]
|
||||
struct Unit;
|
||||
|
||||
#[deriving(Show)]
|
||||
struct Tuple(int, uint);
|
||||
|
||||
#[deriving(Show)]
|
||||
struct Struct { x: int, y: uint }
|
||||
|
||||
#[deriving(Show)]
|
||||
enum Enum {
|
||||
Nullary,
|
||||
Variant(int, uint),
|
||||
StructVariant { x: int, y : uint }
|
||||
}
|
||||
|
||||
macro_rules! t {
|
||||
($x:expr, $expected:expr) => {
|
||||
assert_eq!(format!("{}", $x), $expected.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
t!(Unit, "Unit");
|
||||
t!(Tuple(1, 2), "Tuple(1, 2)");
|
||||
t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }");
|
||||
t!(Nullary, "Nullary");
|
||||
t!(Variant(1, 2), "Variant(1, 2)");
|
||||
t!(StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }");
|
||||
}
|
@ -23,12 +23,12 @@ struct A;
|
||||
struct B;
|
||||
|
||||
impl fmt::Signed for A {
|
||||
fn fmt(_: &A, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.buf.write("aloha".as_bytes())
|
||||
}
|
||||
}
|
||||
impl fmt::Signed for B {
|
||||
fn fmt(_: &B, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.buf.write("adios".as_bytes())
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ use std::fmt;
|
||||
struct Foo(Cell<int>);
|
||||
|
||||
impl fmt::Show for Foo {
|
||||
fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Foo(ref f) = *f;
|
||||
fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Foo(ref f) = *self;
|
||||
assert!(f.get() == 0);
|
||||
f.set(1);
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user