diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0bd08250617..19a52c3550f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2791,8 +2791,9 @@ impl Parser { (ident, item_trait(tps, traits, meths), None) } - // Parses four variants (with the region/type params always optional): + // Parses two variants (with the region/type params always optional): // impl ~[T] : to_str { ... } + // impl to_str for ~[T] { ... } fn parse_item_impl() -> item_info { fn wrap_path(p: Parser, pt: @path) -> @Ty { @Ty { @@ -2802,8 +2803,6 @@ impl Parser { } } - // We do two separate paths here: old-style impls and new-style impls. - // First, parse type parameters if necessary. let mut tps; if self.token == token::LT { @@ -2816,14 +2815,32 @@ impl Parser { // XXX: clownshoes let ident = special_idents::clownshoes_extensions; - // Parse the type. - let ty = self.parse_ty(false); - + // Parse the type. (If this is `impl trait for type`, however, this + // actually parses the trait.) + let mut ty = self.parse_ty(false); // Parse traits, if necessary. let opt_trait = if self.token == token::COLON { + // Old-style trait. self.bump(); Some(self.parse_trait_ref()) + } else if self.eat_keyword(~"for") { + // New-style trait. Reinterpret the type as a trait. + let opt_trait_ref = match ty.node { + ty_path(path, node_id) => { + Some(@trait_ref { + path: path, + ref_id: node_id + }) + } + _ => { + self.span_err(copy self.span, ~"not a trait"); + None + } + }; + + ty = self.parse_ty(false); + opt_trait_ref } else { None }; diff --git a/src/test/run-pass/new-impl-syntax.rs b/src/test/run-pass/new-impl-syntax.rs new file mode 100644 index 00000000000..4cb30ffa213 --- /dev/null +++ b/src/test/run-pass/new-impl-syntax.rs @@ -0,0 +1,26 @@ +struct Thingy { + x: int, + y: int +} + +impl ToStr for Thingy { + pure fn to_str() -> ~str { + fmt!("{ x: %d, y: %d }", self.x, self.y) + } +} + +struct PolymorphicThingy { + x: T +} + +impl ToStr for PolymorphicThingy { + pure fn to_str() -> ~str { + self.x.to_str() + } +} + +fn main() { + io::println(Thingy { x: 1, y: 2 }.to_str()); + io::println(PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_str()); +} +