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:
bors 2014-02-07 20:46:30 -08:00
commit dde2e0b386
41 changed files with 627 additions and 339 deletions

View File

@ -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:

View File

@ -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

View File

@ -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():

View File

@ -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() {

View File

@ -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("&lt;".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{ -&gt; {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),
}
}
}

View File

@ -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())

View File

@ -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;

View File

@ -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(())

View File

@ -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,

View File

@ -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(())
}

View File

@ -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),
}

View File

@ -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")
}

View File

@ -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 => {

View File

@ -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))
}
}

View File

@ -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)
}

View File

@ -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,

View File

@ -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;

View File

@ -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)
}

View File

@ -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,

View File

@ -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)
}

View File

@ -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)`")
}
},

View File

@ -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)
}

View File

@ -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"),

View File

@ -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

View File

@ -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,

View File

@ -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)`")

View File

@ -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),

View File

@ -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)`")

View File

@ -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,

View 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())
}

View File

@ -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");

View File

@ -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"),

View File

@ -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)
}

View File

@ -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())
}
}

View 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 {
x: Error //~ ERROR
}
}
fn main() {}

View 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() {}

View 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() {}

View 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() {}

View 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 }");
}

View File

@ -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())
}
}

View File

@ -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(())