1
Fork 0

core: Update all tests for fmt movement

This commit is contained in:
Alex Crichton 2014-05-11 11:14:14 -07:00
parent d12a136b22
commit 2e2160b026
27 changed files with 277 additions and 161 deletions

View file

@ -41,15 +41,15 @@ impl FromStr for Mode {
impl fmt::Show for Mode { impl fmt::Show for Mode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match *self { let msg = match *self {
CompileFail => "compile-fail", CompileFail => "compile-fail",
RunFail => "run-fail", RunFail => "run-fail",
RunPass => "run-pass", RunPass => "run-pass",
Pretty => "pretty", Pretty => "pretty",
DebugInfoGdb => "debuginfo-gdb", DebugInfoGdb => "debuginfo-gdb",
DebugInfoLldb => "debuginfo-lldb", DebugInfoLldb => "debuginfo-lldb",
Codegen => "codegen", Codegen => "codegen",
}; };
write!(f.buf, "{}", msg) msg.fmt(f)
} }
} }

View file

@ -166,12 +166,12 @@ mod tests {
match a.as_ref::<uint>() { match a.as_ref::<uint>() {
Some(&5) => {} Some(&5) => {}
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match a.as_ref::<Test>() { match a.as_ref::<Test>() {
None => {} None => {}
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
} }
@ -189,7 +189,7 @@ mod tests {
assert_eq!(*x, 5u); assert_eq!(*x, 5u);
*x = 612; *x = 612;
} }
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match b_r.as_mut::<uint>() { match b_r.as_mut::<uint>() {
@ -197,27 +197,27 @@ mod tests {
assert_eq!(*x, 7u); assert_eq!(*x, 7u);
*x = 413; *x = 413;
} }
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match a_r.as_mut::<Test>() { match a_r.as_mut::<Test>() {
None => (), None => (),
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match b_r.as_mut::<Test>() { match b_r.as_mut::<Test>() {
None => (), None => (),
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match a_r.as_mut::<uint>() { match a_r.as_mut::<uint>() {
Some(&612) => {} Some(&612) => {}
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
match b_r.as_mut::<uint>() { match b_r.as_mut::<uint>() {
Some(&413) => {} Some(&413) => {}
x => fail!("Unexpected value {:?}", x) x => fail!("Unexpected value {}", x)
} }
} }
@ -229,11 +229,11 @@ mod tests {
let b = box Test as Box<Any>; let b = box Test as Box<Any>;
match a.move::<uint>() { match a.move::<uint>() {
Ok(a) => { assert_eq!(a, box 8u); } Ok(a) => { assert!(a == box 8u); }
Err(..) => fail!() Err(..) => fail!()
} }
match b.move::<Test>() { match b.move::<Test>() {
Ok(a) => { assert_eq!(a, box Test); } Ok(a) => { assert!(a == box Test); }
Err(..) => fail!() Err(..) => fail!()
} }
@ -246,13 +246,14 @@ mod tests {
#[test] #[test]
fn test_show() { fn test_show() {
let a = box 8u as Box<::realcore::any::Any>; use realstd::to_str::ToStr;
let b = box Test as Box<::realcore::any::Any>; let a = box 8u as Box<::realstd::any::Any>;
assert_eq!(format!("{}", a), "Box<Any>".to_owned()); let b = box Test as Box<::realstd::any::Any>;
assert_eq!(format!("{}", b), "Box<Any>".to_owned()); assert_eq!(a.to_str(), "Box<Any>".to_owned());
assert_eq!(b.to_str(), "Box<Any>".to_owned());
let a = &8u as &::realcore::any::Any; let a = &8u as &Any;
let b = &Test as &::realcore::any::Any; let b = &Test as &Any;
assert_eq!(format!("{}", a), "&Any".to_owned()); assert_eq!(format!("{}", a), "&Any".to_owned());
assert_eq!(format!("{}", b), "&Any".to_owned()); assert_eq!(format!("{}", b), "&Any".to_owned());
} }

View file

@ -255,7 +255,7 @@ mod test {
fn cell_has_sensible_show() { fn cell_has_sensible_show() {
use str::StrSlice; use str::StrSlice;
let x = ::realcore::cell::Cell::new("foo bar"); let x = Cell::new("foo bar");
assert!(format!("{}", x).contains(x.get())); assert!(format!("{}", x).contains(x.get()));
x.set("baz qux"); x.set("baz qux");

View file

@ -633,9 +633,9 @@ impl Default for char {
mod test { mod test {
use super::{escape_unicode, escape_default}; use super::{escape_unicode, escape_default};
use realcore::char::Char; use char::Char;
use slice::ImmutableVector; use slice::ImmutableVector;
use realstd::option::{Some, None}; use option::{Some, None};
use realstd::strbuf::StrBuf; use realstd::strbuf::StrBuf;
use realstd::str::StrAllocating; use realstd::str::StrAllocating;

View file

@ -131,7 +131,7 @@ mod test {
fn test_owned_clone() { fn test_owned_clone() {
let a = box 5i; let a = box 5i;
let b: Box<int> = realclone(&a); let b: Box<int> = realclone(&a);
assert_eq!(a, b); assert!(a == b);
} }
#[test] #[test]

View file

@ -352,8 +352,16 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
let mut filler = Filler { buf: buf, end: &mut end }; let mut filler = Filler { buf: buf, end: &mut end };
match sign { match sign {
SignNeg => { let _ = write!(&mut filler, "{:-}", exp); } SignNeg => {
SignNone | SignAll => { let _ = write!(&mut filler, "{}", exp); } let _ = format_args!(|args| {
fmt::write(&mut filler, args)
}, "{:-}", exp);
}
SignNone | SignAll => {
let _ = format_args!(|args| {
fmt::write(&mut filler, args)
}, "{}", exp);
}
} }
} }
} }

View file

@ -13,16 +13,15 @@
#![allow(unused_variable)] #![allow(unused_variable)]
use any; use any;
use cast;
use cell::Cell; use cell::Cell;
use char::Char; use char::Char;
use container::Container; use container::Container;
use iter::{Iterator, range}; use iter::{Iterator, range};
use kinds::Copy; use kinds::Copy;
use mem;
use option::{Option, Some, None}; use option::{Option, Some, None};
use owned::Box;
use result;
use result::{Ok, Err}; use result::{Ok, Err};
use result;
use slice::{Vector, ImmutableVector}; use slice::{Vector, ImmutableVector};
use slice; use slice;
use str::StrSlice; use str::StrSlice;
@ -34,8 +33,7 @@ pub use self::num::RadixFmt;
macro_rules! write( macro_rules! write(
($dst:expr, $($arg:tt)*) => ({ ($dst:expr, $($arg:tt)*) => ({
let dst: &mut ::fmt::FormatWriter = $dst; format_args!(|args| { $dst.write_fmt(args) }, $($arg)*)
format_args!(|args| { ::std::fmt::write(dst, args) }, $($arg)*)
}) })
) )
@ -104,7 +102,7 @@ impl<'a> Arguments<'a> {
#[doc(hidden)] #[inline] #[doc(hidden)] #[inline]
pub unsafe fn new<'a>(fmt: &'static [rt::Piece<'static>], pub unsafe fn new<'a>(fmt: &'static [rt::Piece<'static>],
args: &'a [Argument<'a>]) -> Arguments<'a> { args: &'a [Argument<'a>]) -> Arguments<'a> {
Arguments{ fmt: cast::transmute(fmt), args: args } Arguments{ fmt: mem::transmute(fmt), args: args }
} }
} }
@ -329,7 +327,7 @@ impl<'a> Formatter<'a> {
rt::Plural(offset, ref selectors, ref default) => { rt::Plural(offset, ref selectors, ref default) => {
// This is validated at compile-time to be a pointer to a // This is validated at compile-time to be a pointer to a
// '&uint' value. // '&uint' value.
let value: &uint = unsafe { cast::transmute(arg.value) }; let value: &uint = unsafe { mem::transmute(arg.value) };
let value = *value; let value = *value;
// First, attempt to match against explicit values without the // First, attempt to match against explicit values without the
@ -372,7 +370,7 @@ impl<'a> Formatter<'a> {
rt::Select(ref selectors, ref default) => { rt::Select(ref selectors, ref default) => {
// This is validated at compile-time to be a pointer to a // This is validated at compile-time to be a pointer to a
// string slice, // string slice,
let value: & &str = unsafe { cast::transmute(arg.value) }; let value: & &str = unsafe { mem::transmute(arg.value) };
let value = *value; let value = *value;
for s in selectors.iter() { for s in selectors.iter() {
@ -565,12 +563,35 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
t: &'a T) -> Argument<'a> { t: &'a T) -> Argument<'a> {
unsafe { unsafe {
Argument { Argument {
formatter: cast::transmute(f), formatter: mem::transmute(f),
value: cast::transmute(t) value: mem::transmute(t)
} }
} }
} }
#[cfg(test)]
pub fn format(args: &Arguments) -> ~str {
use str;
use realstd::str::StrAllocating;
use realstd::io::MemWriter;
fn mywrite<T: ::realstd::io::Writer>(t: &mut T, b: &[u8]) {
use realstd::io::Writer;
let _ = t.write(b);
}
impl FormatWriter for MemWriter {
fn write(&mut self, bytes: &[u8]) -> Result {
mywrite(self, bytes);
Ok(())
}
}
let mut i = MemWriter::new();
let _ = write(&mut i, args);
str::from_utf8(i.get_ref()).unwrap().to_owned()
}
/// When the compiler determines that the type of an argument *must* be a string /// When the compiler determines that the type of an argument *must* be a string
/// (such as for select), then it invokes this method. /// (such as for select), then it invokes this method.
#[doc(hidden)] #[inline] #[doc(hidden)] #[inline]
@ -590,12 +611,12 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
impl<T: Show> Show for @T { impl<T: Show> Show for @T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) } fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
} }
impl<T: Show> Show for Box<T> {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
}
impl<'a, T: Show> Show for &'a T { impl<'a, T: Show> Show for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) } fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
} }
impl<'a, T: Show> Show for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
}
impl Bool for bool { impl Bool for bool {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
@ -613,7 +634,7 @@ impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
let mut utf8 = [0u8, ..4]; let mut utf8 = [0u8, ..4];
let amt = self.encode_utf8(utf8); let amt = self.encode_utf8(utf8);
let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) }; let s: &str = unsafe { mem::transmute(utf8.slice_to(amt)) };
secret_string(&s, f) secret_string(&s, f)
} }
} }
@ -738,20 +759,20 @@ macro_rules! tuple (
impl<$($name:Show),*> Show for ($($name,)*) { impl<$($name:Show),*> Show for ($($name,)*) {
#[allow(uppercase_variables, dead_assignment)] #[allow(uppercase_variables, dead_assignment)]
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
try!(write!(f.buf, "(")); try!(write!(f, "("));
let ($(ref $name,)*) = *self; let ($(ref $name,)*) = *self;
let mut n = 0; let mut n = 0;
$( $(
if n > 0 { if n > 0 {
try!(write!(f.buf, ", ")); try!(write!(f, ", "));
} }
try!(write!(f.buf, "{}", *$name)); try!(write!(f, "{}", *$name));
n += 1; n += 1;
)* )*
if n == 1 { if n == 1 {
try!(write!(f.buf, ",")); try!(write!(f, ","));
} }
write!(f.buf, ")") write!(f, ")")
} }
} }
peel!($($name,)*) peel!($($name,)*)
@ -760,10 +781,6 @@ macro_rules! tuple (
tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
impl Show for Box<any::Any> {
fn fmt(&self, f: &mut Formatter) -> Result { f.pad("Box<Any>") }
}
impl<'a> Show for &'a any::Any { impl<'a> Show for &'a any::Any {
fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") } fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
} }
@ -771,19 +788,19 @@ impl<'a> Show for &'a any::Any {
impl<'a, T: Show> Show for &'a [T] { impl<'a, T: Show> Show for &'a [T] {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
try!(write!(f.buf, "[")); try!(write!(f, "["));
} }
let mut is_first = true; let mut is_first = true;
for x in self.iter() { for x in self.iter() {
if is_first { if is_first {
is_first = false; is_first = false;
} else { } else {
try!(write!(f.buf, ", ")); try!(write!(f, ", "));
} }
try!(write!(f.buf, "{}", *x)) try!(write!(f, "{}", *x))
} }
if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
try!(write!(f.buf, "]")); try!(write!(f, "]"));
} }
Ok(()) Ok(())
} }
@ -809,7 +826,7 @@ impl Show for () {
impl<T: Copy + Show> Show for Cell<T> { impl<T: Copy + Show> Show for Cell<T> {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
write!(f.buf, r"Cell \{ value: {} \}", self.get()) write!(f, r"Cell \{ value: {} \}", self.get())
} }
} }

View file

@ -172,7 +172,7 @@ macro_rules! integer {
int_base!(Octal for $Int as $Uint -> Octal) int_base!(Octal for $Int as $Uint -> Octal)
int_base!(LowerHex for $Int as $Uint -> LowerHex) int_base!(LowerHex for $Int as $Uint -> LowerHex)
int_base!(UpperHex for $Int as $Uint -> UpperHex) int_base!(UpperHex for $Int as $Uint -> UpperHex)
radix_fmt!($Int as $Uint, fmt_int) radix_fmt!($Int as $Int, fmt_int)
int_base!(Show for $Uint as $Uint -> Decimal) int_base!(Show for $Uint as $Uint -> Decimal)
int_base!(Unsigned for $Uint as $Uint -> Decimal) int_base!(Unsigned for $Uint as $Uint -> Decimal)
@ -194,7 +194,7 @@ mod tests {
use fmt::radix; use fmt::radix;
use super::{Binary, Octal, Decimal, LowerHex, UpperHex}; use super::{Binary, Octal, Decimal, LowerHex, UpperHex};
use super::{GenericRadix, Radix}; use super::{GenericRadix, Radix};
use str::StrAllocating; use realstd::str::StrAllocating;
#[test] #[test]
fn test_radix_base() { fn test_radix_base() {

View file

@ -2329,19 +2329,48 @@ pub mod order {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use realstd::prelude::*; use prelude::*;
use realstd::iter::*; use iter::*;
use realstd::num; use num;
use realstd::vec::Vec;
use realstd::slice::Vector;
use cmp; use cmp;
use realstd::owned::Box; use realstd::owned::Box;
use uint; use uint;
impl<T> FromIterator<T> for Vec<T> {
fn from_iter<I: Iterator<T>>(mut iterator: I) -> Vec<T> {
let mut v = Vec::new();
for e in iterator {
v.push(e);
}
return v;
}
}
impl<'a, T> Iterator<&'a T> for ::realcore::slice::Items<'a, T> {
fn next(&mut self) -> Option<&'a T> {
use RealSome = realcore::option::Some;
use RealNone = realcore::option::None;
fn mynext<T, I: ::realcore::iter::Iterator<T>>(i: &mut I)
-> ::realcore::option::Option<T>
{
use realcore::iter::Iterator;
i.next()
}
match mynext(self) {
RealSome(t) => Some(t),
RealNone => None,
}
}
}
#[test] #[test]
fn test_counter_from_iter() { fn test_counter_from_iter() {
let it = count(0, 5).take(10); let it = count(0, 5).take(10);
let xs: Vec<int> = FromIterator::from_iter(it); let xs: Vec<int> = FromIterator::from_iter(it);
assert_eq!(xs, vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
} }
#[test] #[test]
@ -2371,7 +2400,7 @@ mod tests {
fn test_filter_map() { fn test_filter_map() {
let mut it = count(0u, 1u).take(10) let mut it = count(0u, 1u).take(10)
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None }); .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
assert_eq!(it.collect::<Vec<uint>>(), vec![0*0, 2*2, 4*4, 6*6, 8*8]); assert!(it.collect::<Vec<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
} }
#[test] #[test]
@ -2630,7 +2659,7 @@ mod tests {
fn test_collect() { fn test_collect() {
let a = vec![1, 2, 3, 4, 5]; let a = vec![1, 2, 3, 4, 5];
let b: Vec<int> = a.iter().map(|&x| x).collect(); let b: Vec<int> = a.iter().map(|&x| x).collect();
assert_eq!(a, b); assert!(a == b);
} }
#[test] #[test]
@ -2702,7 +2731,8 @@ mod tests {
let mut it = xs.iter(); let mut it = xs.iter();
it.next(); it.next();
it.next(); it.next();
assert_eq!(it.rev().map(|&x| x).collect::<Vec<int>>(), vec![16, 14, 12, 10, 8, 6]); assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
vec![16, 14, 12, 10, 8, 6]);
} }
#[test] #[test]
@ -2940,12 +2970,12 @@ mod tests {
#[test] #[test]
fn test_double_ended_range() { fn test_double_ended_range() {
assert_eq!(range(11i, 14).rev().collect::<Vec<int>>(), vec![13i, 12, 11]); assert!(range(11i, 14).rev().collect::<Vec<int>>() == vec![13i, 12, 11]);
for _ in range(10i, 0).rev() { for _ in range(10i, 0).rev() {
fail!("unreachable"); fail!("unreachable");
} }
assert_eq!(range(11u, 14).rev().collect::<Vec<uint>>(), vec![13u, 12, 11]); assert!(range(11u, 14).rev().collect::<Vec<uint>>() == vec![13u, 12, 11]);
for _ in range(10u, 0).rev() { for _ in range(10u, 0).rev() {
fail!("unreachable"); fail!("unreachable");
} }
@ -2997,14 +3027,14 @@ mod tests {
} }
} }
assert_eq!(range(0i, 5).collect::<Vec<int>>(), vec![0i, 1, 2, 3, 4]); assert!(range(0i, 5).collect::<Vec<int>>() == vec![0i, 1, 2, 3, 4]);
assert_eq!(range(-10i, -1).collect::<Vec<int>>(), assert!(range(-10i, -1).collect::<Vec<int>>() ==
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]); vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
assert_eq!(range(0i, 5).rev().collect::<Vec<int>>(), vec![4, 3, 2, 1, 0]); assert!(range(0i, 5).rev().collect::<Vec<int>>() == vec![4, 3, 2, 1, 0]);
assert_eq!(range(200, -5).collect::<Vec<int>>(), vec![]); assert_eq!(range(200, -5).len(), 0);
assert_eq!(range(200, -5).rev().collect::<Vec<int>>(), vec![]); assert_eq!(range(200, -5).rev().len(), 0);
assert_eq!(range(200, 200).collect::<Vec<int>>(), vec![]); assert_eq!(range(200, 200).len(), 0);
assert_eq!(range(200, 200).rev().collect::<Vec<int>>(), vec![]); assert_eq!(range(200, 200).rev().len(), 0);
assert_eq!(range(0i, 100).size_hint(), (100, Some(100))); assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
// this test is only meaningful when sizeof uint < sizeof u64 // this test is only meaningful when sizeof uint < sizeof u64
@ -3015,32 +3045,44 @@ mod tests {
#[test] #[test]
fn test_range_inclusive() { fn test_range_inclusive() {
assert_eq!(range_inclusive(0i, 5).collect::<Vec<int>>(), vec![0i, 1, 2, 3, 4, 5]); assert!(range_inclusive(0i, 5).collect::<Vec<int>>() ==
assert_eq!(range_inclusive(0i, 5).rev().collect::<Vec<int>>(), vec![5i, 4, 3, 2, 1, 0]); vec![0i, 1, 2, 3, 4, 5]);
assert_eq!(range_inclusive(200, -5).collect::<Vec<int>>(), vec![]); assert!(range_inclusive(0i, 5).rev().collect::<Vec<int>>() ==
assert_eq!(range_inclusive(200, -5).rev().collect::<Vec<int>>(), vec![]); vec![5i, 4, 3, 2, 1, 0]);
assert_eq!(range_inclusive(200, 200).collect::<Vec<int>>(), vec![200]); assert_eq!(range_inclusive(200, -5).len(), 0);
assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<int>>(), vec![200]); assert_eq!(range_inclusive(200, -5).rev().len(), 0);
assert!(range_inclusive(200, 200).collect::<Vec<int>>() == vec![200]);
assert!(range_inclusive(200, 200).rev().collect::<Vec<int>>() == vec![200]);
} }
#[test] #[test]
fn test_range_step() { fn test_range_step() {
assert_eq!(range_step(0i, 20, 5).collect::<Vec<int>>(), vec![0, 5, 10, 15]); assert!(range_step(0i, 20, 5).collect::<Vec<int>>() ==
assert_eq!(range_step(20i, 0, -5).collect::<Vec<int>>(), vec![20, 15, 10, 5]); vec![0, 5, 10, 15]);
assert_eq!(range_step(20i, 0, -6).collect::<Vec<int>>(), vec![20, 14, 8, 2]); assert!(range_step(20i, 0, -5).collect::<Vec<int>>() ==
assert_eq!(range_step(200u8, 255, 50).collect::<Vec<u8>>(), vec![200u8, 250]); vec![20, 15, 10, 5]);
assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), vec![]); assert!(range_step(20i, 0, -6).collect::<Vec<int>>() ==
assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), vec![]); vec![20, 14, 8, 2]);
assert!(range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
vec![200u8, 250]);
assert!(range_step(200, -5, 1).collect::<Vec<int>>() == vec![]);
assert!(range_step(200, 200, 1).collect::<Vec<int>>() == vec![]);
} }
#[test] #[test]
fn test_range_step_inclusive() { fn test_range_step_inclusive() {
assert_eq!(range_step_inclusive(0i, 20, 5).collect::<Vec<int>>(), vec![0, 5, 10, 15, 20]); assert!(range_step_inclusive(0i, 20, 5).collect::<Vec<int>>() ==
assert_eq!(range_step_inclusive(20i, 0, -5).collect::<Vec<int>>(), vec![20, 15, 10, 5, 0]); vec![0, 5, 10, 15, 20]);
assert_eq!(range_step_inclusive(20i, 0, -6).collect::<Vec<int>>(), vec![20, 14, 8, 2]); assert!(range_step_inclusive(20i, 0, -5).collect::<Vec<int>>() ==
assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>(), vec![200u8, 250]); vec![20, 15, 10, 5, 0]);
assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), vec![]); assert!(range_step_inclusive(20i, 0, -6).collect::<Vec<int>>() ==
assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), vec![200]); vec![20, 14, 8, 2]);
assert!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
vec![200u8, 250]);
assert!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>() ==
vec![]);
assert!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>() ==
vec![200]);
} }
#[test] #[test]

View file

@ -11,7 +11,7 @@
//! The Rust core library //! The Rust core library
//! //!
//! This library is meant to represent the core functionality of rust that is //! This library is meant to represent the core functionality of rust that is
//! maximally portable to other platforms. To that exent, this library has no //! maximally portable to other platforms. To that extent, this library has no
//! knowledge of things like allocation, threads, I/O, etc. This library is //! knowledge of things like allocation, threads, I/O, etc. This library is
//! built on the assumption of a few existing symbols: //! built on the assumption of a few existing symbols:
//! //!
@ -48,15 +48,14 @@
#[cfg(test)] extern crate realcore = "core"; #[cfg(test)] extern crate realcore = "core";
#[cfg(test)] extern crate libc; #[cfg(test)] extern crate libc;
#[cfg(test)] extern crate native; #[cfg(test)] extern crate native;
#[phase(syntax, link)] #[cfg(test)] extern crate realstd = "std"; #[cfg(test)] extern crate rand;
#[phase(syntax, link)] #[cfg(test)] extern crate log; #[cfg(test)] extern crate realstd = "std";
#[cfg(test)] pub use cmp = realcore::cmp; #[cfg(test)] pub use cmp = realcore::cmp;
#[cfg(test)] pub use kinds = realcore::kinds; #[cfg(test)] pub use kinds = realcore::kinds;
#[cfg(test)] pub use ops = realcore::ops; #[cfg(test)] pub use ops = realcore::ops;
#[cfg(test)] pub use ty = realcore::ty; #[cfg(test)] pub use ty = realcore::ty;
#[cfg(not(test))]
mod macros; mod macros;
#[path = "num/float_macros.rs"] mod float_macros; #[path = "num/float_macros.rs"] mod float_macros;
@ -131,13 +130,13 @@ mod core {
mod std { mod std {
pub use clone; pub use clone;
pub use cmp; pub use cmp;
pub use fmt;
pub use kinds; pub use kinds;
pub use option; pub use option;
pub use fmt;
#[cfg(test)] pub use realstd::fmt; // needed for fail!()
#[cfg(test)] pub use realstd::rt; // needed for fail!() #[cfg(test)] pub use realstd::rt; // needed for fail!()
#[cfg(test)] pub use realstd::option; // needed for assert!() // #[cfg(test)] pub use realstd::option; // needed for fail!()
// #[cfg(test)] pub use realstd::fmt; // needed for fail!()
#[cfg(test)] pub use realstd::os; // needed for tests #[cfg(test)] pub use realstd::os; // needed for tests
#[cfg(test)] pub use realstd::slice; // needed for tests #[cfg(test)] pub use realstd::slice; // needed for tests
#[cfg(test)] pub use realstd::vec; // needed for vec![] #[cfg(test)] pub use realstd::vec; // needed for vec![]

View file

@ -54,6 +54,17 @@ macro_rules! assert(
); );
) )
/// Runtime assertion for equality, for details see std::macros
macro_rules! assert_eq(
($cond1:expr, $cond2:expr) => ({
let c1 = $cond1;
let c2 = $cond2;
if c1 != c2 || c2 != c1 {
fail!("expressions not equal, left: {}, right: {}", c1, c2);
}
})
)
/// Runtime assertion, disableable at compile time /// Runtime assertion, disableable at compile time
#[macro_export] #[macro_export]
macro_rules! debug_assert( macro_rules! debug_assert(
@ -65,3 +76,13 @@ macro_rules! debug_assert(
macro_rules! try( macro_rules! try(
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
) )
#[cfg(test)]
macro_rules! vec( ($($e:expr),*) => ({
let mut _v = ::std::vec::Vec::new();
$(_v.push($e);)*
_v
}) )
#[cfg(test)]
macro_rules! format( ($($arg:tt)*) => (format_args!(::fmt::format, $($arg)*)) )

View file

@ -595,9 +595,11 @@ pub fn collect<T, Iter: Iterator<Option<T>>, V: FromIterator<T>>(iter: Iter) ->
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use realstd::option::collect; use realstd::vec::Vec;
use realstd::prelude::*; use realstd::str::StrAllocating;
use realstd::iter::range; use option::collect;
use prelude::*;
use iter::range;
use str::StrSlice; use str::StrSlice;
use kinds::marker; use kinds::marker;
@ -638,7 +640,7 @@ mod tests {
impl ::ops::Drop for R { impl ::ops::Drop for R {
fn drop(&mut self) { fn drop(&mut self) {
let ii = &*self.i; let ii = &*self.i;
let i = ii.borrow().clone(); let i = *ii.borrow();
*ii.borrow_mut() = i + 1; *ii.borrow_mut() = i + 1;
} }
} }
@ -649,9 +651,14 @@ mod tests {
} }
} }
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
use realstd::clone::Clone;
t.clone()
}
let i = Rc::new(RefCell::new(0)); let i = Rc::new(RefCell::new(0));
{ {
let x = R(i.clone()); let x = R(realclone(&i));
let opt = Some(x); let opt = Some(x);
let _y = opt.unwrap(); let _y = opt.unwrap();
} }
@ -849,21 +856,21 @@ mod tests {
fn test_collect() { fn test_collect() {
let v: Option<Vec<int>> = collect(range(0, 0) let v: Option<Vec<int>> = collect(range(0, 0)
.map(|_| Some(0))); .map(|_| Some(0)));
assert_eq!(v, Some(vec![])); assert!(v == Some(vec![]));
let v: Option<Vec<int>> = collect(range(0, 3) let v: Option<Vec<int>> = collect(range(0, 3)
.map(|x| Some(x))); .map(|x| Some(x)));
assert_eq!(v, Some(vec![0, 1, 2])); assert!(v == Some(vec![0, 1, 2]));
let v: Option<Vec<int>> = collect(range(0, 3) let v: Option<Vec<int>> = collect(range(0, 3)
.map(|x| if x > 1 { None } else { Some(x) })); .map(|x| if x > 1 { None } else { Some(x) }));
assert_eq!(v, None); assert!(v == None);
// test that it does not take more elements than it needs // test that it does not take more elements than it needs
let mut functions = [|| Some(()), || None, || fail!()]; let mut functions = [|| Some(()), || None, || fail!()];
let v: Option<Vec<()>> = collect(functions.mut_iter().map(|f| (*f)())); let v: Option<Vec<()>> = collect(functions.mut_iter().map(|f| (*f)()));
assert_eq!(v, None); assert!(v == None);
} }
} }

View file

@ -480,7 +480,7 @@ impl<T> Ord for *mut T {
#[cfg(test)] #[cfg(test)]
pub mod ptr_tests { pub mod ptr_tests {
use super::*; use super::*;
use realstd::prelude::*; use prelude::*;
use realstd::c_str::ToCStr; use realstd::c_str::ToCStr;
use mem; use mem;
@ -660,9 +660,6 @@ pub mod ptr_tests {
let expected = expected_arr[ctr].with_ref(|buf| { let expected = expected_arr[ctr].with_ref(|buf| {
str::raw::from_c_str(buf) str::raw::from_c_str(buf)
}); });
debug!(
"test_ptr_array_each_with_len e: {}, a: {}",
expected, actual);
assert_eq!(actual, expected); assert_eq!(actual, expected);
ctr += 1; ctr += 1;
iteration_count += 1; iteration_count += 1;
@ -696,9 +693,6 @@ pub mod ptr_tests {
let expected = expected_arr[ctr].with_ref(|buf| { let expected = expected_arr[ctr].with_ref(|buf| {
str::raw::from_c_str(buf) str::raw::from_c_str(buf)
}); });
debug!(
"test_ptr_array_each e: {}, a: {}",
expected, actual);
assert_eq!(actual, expected); assert_eq!(actual, expected);
ctr += 1; ctr += 1;
iteration_count += 1; iteration_count += 1;

View file

@ -268,7 +268,7 @@
use clone::Clone; use clone::Clone;
use cmp::Eq; use cmp::Eq;
use fmt::Show; use std::fmt::Show;
use iter::{Iterator, FromIterator}; use iter::{Iterator, FromIterator};
use option::{None, Option, Some}; use option::{None, Option, Some};
@ -621,9 +621,12 @@ pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use realstd::result::{collect, fold, fold_}; use realstd::vec::Vec;
use realstd::prelude::*; use realstd::str::StrAllocating;
use realstd::iter::range;
use result::{collect, fold, fold_};
use prelude::*;
use iter::range;
pub fn op1() -> Result<int, ~str> { Ok(666) } pub fn op1() -> Result<int, ~str> { Ok(666) }
pub fn op2() -> Result<int, ~str> { Err("sadface".to_owned()) } pub fn op2() -> Result<int, ~str> { Err("sadface".to_owned()) }
@ -670,33 +673,37 @@ mod tests {
#[test] #[test]
pub fn test_impl_map() { pub fn test_impl_map() {
assert_eq!(Ok::<~str, ~str>("a".to_owned()).map(|x| x + "b"), Ok("ab".to_owned())); assert_eq!(Ok::<~str, ~str>("a".to_owned()).map(|x| x + "b"),
assert_eq!(Err::<~str, ~str>("a".to_owned()).map(|x| x + "b"), Err("a".to_owned())); Ok("ab".to_owned()));
assert_eq!(Err::<~str, ~str>("a".to_owned()).map(|x| x + "b"),
Err("a".to_owned()));
} }
#[test] #[test]
pub fn test_impl_map_err() { pub fn test_impl_map_err() {
assert_eq!(Ok::<~str, ~str>("a".to_owned()).map_err(|x| x + "b"), Ok("a".to_owned())); assert_eq!(Ok::<~str, ~str>("a".to_owned()).map_err(|x| x + "b"),
assert_eq!(Err::<~str, ~str>("a".to_owned()).map_err(|x| x + "b"), Err("ab".to_owned())); Ok("a".to_owned()));
assert_eq!(Err::<~str, ~str>("a".to_owned()).map_err(|x| x + "b"),
Err("ab".to_owned()));
} }
#[test] #[test]
fn test_collect() { fn test_collect() {
let v: Result<Vec<int>, ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0))); let v: Result<Vec<int>, ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
assert_eq!(v, Ok(vec![])); assert!(v == Ok(vec![]));
let v: Result<Vec<int>, ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x))); let v: Result<Vec<int>, ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
assert_eq!(v, Ok(vec![0, 1, 2])); assert!(v == Ok(vec![0, 1, 2]));
let v: Result<Vec<int>, int> = collect(range(0, 3) let v: Result<Vec<int>, int> = collect(range(0, 3)
.map(|x| if x > 1 { Err(x) } else { Ok(x) })); .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
assert_eq!(v, Err(2)); assert!(v == Err(2));
// test that it does not take more elements than it needs // test that it does not take more elements than it needs
let mut functions = [|| Ok(()), || Err(1), || fail!()]; let mut functions = [|| Ok(()), || Err(1), || fail!()];
let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)())); let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)()));
assert_eq!(v, Err(1)); assert!(v == Err(1));
} }
#[test] #[test]
@ -720,15 +727,6 @@ mod tests {
Err(1)); Err(1));
} }
#[test]
pub fn test_to_str() {
let ok: Result<int, ~str> = Ok(100);
let err: Result<int, ~str> = Err("Err".to_owned());
assert_eq!(ok.to_str(), "Ok(100)".to_owned());
assert_eq!(err.to_str(), "Err(Err)".to_owned());
}
#[test] #[test]
pub fn test_fmt_default() { pub fn test_fmt_default() {
let ok: Result<int, ~str> = Ok(100); let ok: Result<int, ~str> = Ok(100);

View file

@ -20,7 +20,7 @@
// 1. Implement DST // 1. Implement DST
// 2. Make `Box<T>` not a language feature // 2. Make `Box<T>` not a language feature
// 3. Move `Box<T>` to a separate crate, liballoc. // 3. Move `Box<T>` to a separate crate, liballoc.
// 4. Implement relevant trais in liballoc, not libcore // 4. Implement relevant traits in liballoc, not libcore
// //
// Currently, no progress has been made on this list. // Currently, no progress has been made on this list.

View file

@ -103,12 +103,24 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
ty::walk_ty(original_type, |t| { ty::walk_ty(original_type, |t| {
match get(t).sty { match get(t).sty {
ty_enum(def_id, _) | ty_enum(def_id, _) |
ty_trait(box ty::TyTrait { def_id, .. }) |
ty_struct(def_id, _) => { ty_struct(def_id, _) => {
if def_id.krate == ast::LOCAL_CRATE { if def_id.krate == ast::LOCAL_CRATE {
found_nominal = true; found_nominal = true;
} }
} }
ty_trait(box ty::TyTrait { def_id, ref store, .. }) => {
if def_id.krate == ast::LOCAL_CRATE {
found_nominal = true;
}
if *store == ty::UniqTraitStore {
match tcx.lang_items.owned_box() {
Some(did) if did.krate == ast::LOCAL_CRATE => {
found_nominal = true;
}
_ => {}
}
}
}
ty_uniq(..) => { ty_uniq(..) => {
match tcx.lang_items.owned_box() { match tcx.lang_items.owned_box() {
Some(did) if did.krate == ast::LOCAL_CRATE => { Some(did) if did.krate == ast::LOCAL_CRATE => {

View file

@ -290,7 +290,7 @@ impl fmt::Show for clean::Type {
} }
clean::ResolvedPath{ did, ref typarams, ref path} => { clean::ResolvedPath{ did, ref typarams, ref path} => {
try!(resolved_path(f, did, path, false)); try!(resolved_path(f, did, path, false));
tybounds(f.buf, typarams) tybounds(f, typarams)
} }
clean::Self(..) => f.write("Self".as_bytes()), clean::Self(..) => f.write("Self".as_bytes()),
clean::Primitive(prim) => { clean::Primitive(prim) => {

View file

@ -285,10 +285,10 @@ use std::io;
format_args!(fmt::format, "this returns {}", "~str"); format_args!(fmt::format, "this returns {}", "~str");
let some_writer: &mut io::Writer = &mut io::stdout(); let some_writer: &mut io::Writer = &mut io::stdout();
format_args!(|args| { fmt::write(some_writer, args) }, "print with a {}", "closure"); format_args!(|args| { write!(some_writer, "{}", args) }, "print with a {}", "closure");
fn my_fmt_fn(args: &fmt::Arguments) { fn my_fmt_fn(args: &fmt::Arguments) {
fmt::write(&mut io::stdout(), args); write!(&mut io::stdout(), "{}", args);
} }
format_args!(my_fmt_fn, "or a {} too", "function"); format_args!(my_fmt_fn, "or a {} too", "function");
# } # }
@ -490,6 +490,7 @@ use repr;
use result::{Ok, Err}; use result::{Ok, Err};
use str::{StrAllocating}; use str::{StrAllocating};
use str; use str;
use strbuf::StrBuf;
use slice::Vector; use slice::Vector;
pub use core::fmt::{Formatter, Result, FormatWriter, Show, rt}; pub use core::fmt::{Formatter, Result, FormatWriter, Show, rt};
@ -550,6 +551,13 @@ pub fn format(args: &Arguments) -> ~str {
str::from_utf8(output.unwrap().as_slice()).unwrap().to_owned() str::from_utf8(output.unwrap().as_slice()).unwrap().to_owned()
} }
/// Temporary transition utility
pub fn format_strbuf(args: &Arguments) -> StrBuf {
let mut output = io::MemWriter::new();
let _ = write!(&mut output, "{}", args);
str::from_utf8(output.unwrap().as_slice()).unwrap().into_strbuf()
}
impl<T> Poly for T { impl<T> Poly for T {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
match (f.width, f.precision) { match (f.width, f.precision) {

View file

@ -308,9 +308,9 @@ impl fmt::Show for Command {
/// non-utf8 data is lossily converted using the utf8 replacement /// non-utf8 data is lossily converted using the utf8 replacement
/// character. /// character.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, "{}", str::from_utf8_lossy(self.program.as_bytes_no_nul()))); try!(write!(f, "{}", str::from_utf8_lossy(self.program.as_bytes_no_nul())));
for arg in self.args.iter() { for arg in self.args.iter() {
try!(write!(f.buf, " '{}'", str::from_utf8_lossy(arg.as_bytes_no_nul()))); try!(write!(f, " '{}'", str::from_utf8_lossy(arg.as_bytes_no_nul())));
} }
Ok(()) Ok(())
} }

View file

@ -19,7 +19,6 @@ use from_str::FromStr;
use intrinsics; use intrinsics;
use libc::c_int; use libc::c_int;
use num::strconv; use num::strconv;
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
use num; use num;
pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE}; pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};

View file

@ -15,6 +15,7 @@
use prelude::*; use prelude::*;
use from_str::FromStr; use from_str::FromStr;
use intrinsics;
use libc::c_int; use libc::c_int;
use num::strconv; use num::strconv;
use num; use num;

View file

@ -68,11 +68,7 @@ pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
let mut buf = [0u8, ..65]; let mut buf = [0u8, ..65];
let amt = { let amt = {
let mut wr = ::io::BufWriter::new(buf); let mut wr = ::io::BufWriter::new(buf);
if radix == 10 { (write!(&mut wr, "{}", ::fmt::radix(n, radix as u8))).unwrap();
(write!(&mut wr, "{}", n)).unwrap()
} else {
(write!(&mut wr, "{}", ::fmt::radix(n, radix as u8))).unwrap()
}
wr.tell().unwrap() as uint wr.tell().unwrap() as uint
}; };
f(buf.slice(0, amt)) f(buf.slice(0, amt))
@ -82,11 +78,7 @@ impl ToStrRadix for $T {
/// Convert to a string in a given base. /// Convert to a string in a given base.
#[inline] #[inline]
fn to_str_radix(&self, radix: uint) -> ~str { fn to_str_radix(&self, radix: uint) -> ~str {
if radix == 10 { format!("{}", ::fmt::radix(*self, radix as u8))
format!("{}", *self)
} else {
format!("{}", ::fmt::radix(*self, radix as u8))
}
} }
} }

View file

@ -19,7 +19,6 @@ use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num; use num;
use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Add, Sub, Mul, Div, Rem, Neg};
use option::{None, Option, Some}; use option::{None, Option, Some};
use result::ResultUnwrap;
use slice::{CloneableVector, ImmutableVector, MutableVector}; use slice::{CloneableVector, ImmutableVector, MutableVector};
use std::cmp::{Ord, Eq}; use std::cmp::{Ord, Eq};
use str::{StrAllocating, StrSlice}; use str::{StrAllocating, StrSlice};

View file

@ -14,6 +14,7 @@ use any::{Any, AnyRefExt};
use clone::Clone; use clone::Clone;
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering};
use default::Default; use default::Default;
use fmt;
use intrinsics; use intrinsics;
use mem; use mem;
use raw::TraitObject; use raw::TraitObject;
@ -99,3 +100,16 @@ impl AnyOwnExt for Box<Any> {
} }
} }
} }
impl<T: fmt::Show> fmt::Show for Box<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
#[cfg(not(stage0))]
impl fmt::Show for Box<Any> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Box<Any>")
}
}

View file

@ -49,7 +49,6 @@ use str::{Str, SendStr, IntoMaybeOwned};
#[cfg(test)] use any::AnyRefExt; #[cfg(test)] use any::AnyRefExt;
#[cfg(test)] use owned::AnyOwnExt; #[cfg(test)] use owned::AnyOwnExt;
#[cfg(test)] use realstd::result::ResultUnwrap;
#[cfg(test)] use result; #[cfg(test)] use result;
#[cfg(test)] use str::StrAllocating; #[cfg(test)] use str::StrAllocating;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// no-pretty-expanded
#![feature(phase)] #![feature(phase)]
#[phase(syntax)] extern crate green; #[phase(syntax)] extern crate green;
@ -33,7 +35,7 @@ impl fmt::Show for Color {
Yellow => "yellow", Yellow => "yellow",
Blue => "blue", Blue => "blue",
}; };
f.buf.write(str.as_bytes()) write!(f, "{}", str)
} }
} }
@ -82,7 +84,7 @@ impl fmt::Show for Number {
} }
for s in out.iter().rev() { for s in out.iter().rev() {
try!(f.buf.write(s.as_bytes())); try!(write!(f, "{}", s))
} }
Ok(()) Ok(())
} }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// no-pretty-expanded
#![allow(unused_must_use, dead_code)] #![allow(unused_must_use, dead_code)]
#![feature(macro_rules)] #![feature(macro_rules)]
@ -22,8 +24,9 @@ fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) {
write!(foo.writer, "{}", foo.other); write!(foo.writer, "{}", foo.other);
} }
pub fn main() { fn main() {
let mut w = MemWriter::new(); let mut w = MemWriter::new();
write!(&mut w as &mut Writer, ""); write!(&mut w as &mut Writer, "");
write!(&mut w, ""); // should coerce write!(&mut w, ""); // should coerce
println!("ok");
} }