auto merge of #9535 : alexcrichton/rust/no-format-default, r=thestinger
As mentioned in #9456, the format! syntax extension would previously consider an empty format as a 'Unknown' format which could then also get coerced into a different style of format on another argument. This is unusual behavior because `{}` is a very common format and if you have `{0} {0:?}` you wouldn't expect them both to be coereced to the `Poly` formatter. This commit removes this coercion, but still retains the requirement that each argument has exactly one format specified for it (an empty format now counts as well). Perhaps at a later date we can add support for multiple formats of one argument, but this puts us in at least a backwards-compatible situation if we decide to do that.
This commit is contained in:
commit
78c3fac852
|
@ -1159,11 +1159,12 @@ impl<'self> fmt::Default for Sidebar<'self> {
|
||||||
write!(w, "<a class='{ty} {class}' href='{curty, select,
|
write!(w, "<a class='{ty} {class}' href='{curty, select,
|
||||||
mod{../}
|
mod{../}
|
||||||
other{}
|
other{}
|
||||||
}{ty, select,
|
}{tysel, select,
|
||||||
mod{{name}/index.html}
|
mod{{name}/index.html}
|
||||||
other{#.{name}.html}
|
other{#.{name}.html}
|
||||||
}'>{name}</a><br/>",
|
}'>{name}</a><br/>",
|
||||||
ty = short,
|
ty = short,
|
||||||
|
tysel = short,
|
||||||
class = class,
|
class = class,
|
||||||
curty = shortty(cur),
|
curty = shortty(cur),
|
||||||
name = item.as_slice());
|
name = item.as_slice());
|
||||||
|
|
|
@ -22,7 +22,6 @@ use std::vec;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
enum ArgumentType {
|
enum ArgumentType {
|
||||||
Unknown,
|
|
||||||
Known(@str),
|
Known(@str),
|
||||||
Unsigned,
|
Unsigned,
|
||||||
String,
|
String,
|
||||||
|
@ -153,14 +152,13 @@ impl Context {
|
||||||
parse::ArgumentIs(i) => Left(i),
|
parse::ArgumentIs(i) => Left(i),
|
||||||
parse::ArgumentNamed(s) => Right(s.to_managed()),
|
parse::ArgumentNamed(s) => Right(s.to_managed()),
|
||||||
};
|
};
|
||||||
let ty = if arg.format.ty == "" {
|
|
||||||
Unknown
|
|
||||||
} else { Known(arg.format.ty.to_managed()) };
|
|
||||||
self.verify_arg_type(pos, ty);
|
|
||||||
|
|
||||||
// and finally the method being applied
|
// and finally the method being applied
|
||||||
match arg.method {
|
match arg.method {
|
||||||
None => {}
|
None => {
|
||||||
|
let ty = Known(arg.format.ty.to_managed());
|
||||||
|
self.verify_arg_type(pos, ty);
|
||||||
|
}
|
||||||
Some(ref method) => { self.verify_method(pos, *method); }
|
Some(ref method) => { self.verify_method(pos, *method); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +251,7 @@ impl Context {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.verify_same(self.args[arg].span, ty, self.arg_types[arg]);
|
self.verify_same(self.args[arg].span, ty, self.arg_types[arg]);
|
||||||
if ty != Unknown || self.arg_types[arg].is_none() {
|
if self.arg_types[arg].is_none() {
|
||||||
self.arg_types[arg] = Some(ty);
|
self.arg_types[arg] = Some(ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +267,7 @@ impl Context {
|
||||||
};
|
};
|
||||||
self.verify_same(span, ty,
|
self.verify_same(span, ty,
|
||||||
self.name_types.find(&name).map(|&x| *x));
|
self.name_types.find(&name).map(|&x| *x));
|
||||||
if ty != Unknown || !self.name_types.contains_key(&name) {
|
if !self.name_types.contains_key(&name) {
|
||||||
self.name_types.insert(name, ty);
|
self.name_types.insert(name, ty);
|
||||||
}
|
}
|
||||||
// Assign this named argument a slot in the arguments array if
|
// Assign this named argument a slot in the arguments array if
|
||||||
|
@ -292,9 +290,8 @@ impl Context {
|
||||||
/// that: `Some(None) == Some(Some(x))`
|
/// that: `Some(None) == Some(Some(x))`
|
||||||
fn verify_same(&self, sp: Span, ty: ArgumentType,
|
fn verify_same(&self, sp: Span, ty: ArgumentType,
|
||||||
before: Option<ArgumentType>) {
|
before: Option<ArgumentType>) {
|
||||||
if ty == Unknown { return }
|
|
||||||
let cur = match before {
|
let cur = match before {
|
||||||
Some(Unknown) | None => return,
|
None => return,
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
};
|
};
|
||||||
if ty == cur { return }
|
if ty == cur { return }
|
||||||
|
@ -649,9 +646,9 @@ impl Context {
|
||||||
};
|
};
|
||||||
|
|
||||||
let fmt_trait = match ty {
|
let fmt_trait = match ty {
|
||||||
Unknown => "Default",
|
|
||||||
Known(tyname) => {
|
Known(tyname) => {
|
||||||
match tyname.as_slice() {
|
match tyname.as_slice() {
|
||||||
|
"" => "Default",
|
||||||
"?" => "Poly",
|
"?" => "Poly",
|
||||||
"b" => "Bool",
|
"b" => "Bool",
|
||||||
"c" => "Char",
|
"c" => "Char",
|
||||||
|
|
|
@ -65,8 +65,8 @@ fn main() {
|
||||||
// format strings because otherwise the "internal pointer of which argument
|
// format strings because otherwise the "internal pointer of which argument
|
||||||
// is next" would be invalidated if different cases had different numbers of
|
// is next" would be invalidated if different cases had different numbers of
|
||||||
// arguments.
|
// arguments.
|
||||||
format!("{0, select, other{{}}}", "a"); //~ ERROR: cannot use implicit
|
format!("{1, select, other{{}}}", 1, "a"); //~ ERROR: cannot use implicit
|
||||||
format!("{0, plural, other{{}}}", 1); //~ ERROR: cannot use implicit
|
format!("{1, plural, other{{}}}", 1, 1); //~ ERROR: cannot use implicit
|
||||||
format!("{0, plural, other{{1:.*d}}}", 1, 2); //~ ERROR: cannot use implicit
|
format!("{0, plural, other{{1:.*d}}}", 1, 2); //~ ERROR: cannot use implicit
|
||||||
|
|
||||||
format!("foo } bar"); //~ ERROR: unmatched `}` found
|
format!("foo } bar"); //~ ERROR: unmatched `}` found
|
||||||
|
|
|
@ -85,7 +85,6 @@ pub fn main() {
|
||||||
t!(format!("{1} {0}", 0, 1), "1 0");
|
t!(format!("{1} {0}", 0, 1), "1 0");
|
||||||
t!(format!("{foo} {bar}", foo=0, bar=1), "0 1");
|
t!(format!("{foo} {bar}", foo=0, bar=1), "0 1");
|
||||||
t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
|
t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
|
||||||
t!(format!("{} {0:s}", "a"), "a a");
|
|
||||||
t!(format!("{} {0}", "a"), "a a");
|
t!(format!("{} {0}", "a"), "a a");
|
||||||
t!(format!("{foo_bar}", foo_bar=1), "1");
|
t!(format!("{foo_bar}", foo_bar=1), "1");
|
||||||
|
|
||||||
|
@ -98,8 +97,8 @@ pub fn main() {
|
||||||
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "b"), "bb");
|
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "b"), "bb");
|
||||||
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "c"), "cc");
|
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "c"), "cc");
|
||||||
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "d"), "dd");
|
t!(format!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "d"), "dd");
|
||||||
t!(format!("{1, select, a{#{0:s}} other{#{1}}}", "b", "a"), "ab");
|
t!(format!("{1, select, a{#{0:s}} other{#}}", "b", "a"), "ab");
|
||||||
t!(format!("{1, select, a{#{0}} other{#{1}}}", "c", "b"), "bb");
|
t!(format!("{1, select, a{#{0}} other{#}}", "c", "b"), "b");
|
||||||
|
|
||||||
// Formatting strings and their arguments
|
// Formatting strings and their arguments
|
||||||
t!(format!("{:s}", "a"), "a");
|
t!(format!("{:s}", "a"), "a");
|
||||||
|
|
Loading…
Reference in New Issue