1
Fork 0

Remove support for multiple traits in a single impl

There was half-working support for them, but they were never fully
implemented or even approved. Remove them altogether.

Closes #3410
This commit is contained in:
Tim Chevalier 2012-09-07 15:11:26 -07:00
parent 62ab9d70f4
commit f5093dff7b
9 changed files with 44 additions and 35 deletions

View file

@ -1267,7 +1267,7 @@ enum item_ {
item_class(@struct_def, ~[ty_param]), item_class(@struct_def, ~[ty_param]),
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]), item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
item_impl(~[ty_param], item_impl(~[ty_param],
~[@trait_ref], /* traits this impl implements */ Option<@trait_ref>, /* (optional) trait this impl implements */
@ty, /* self */ @ty, /* self */
~[@method]), ~[@method]),
item_mac(mac), item_mac(mac),

View file

@ -2571,11 +2571,11 @@ struct parser {
// Parse traits, if necessary. // Parse traits, if necessary.
let traits = if self.token == token::COLON { let opt_trait = if self.token == token::COLON {
self.bump(); self.bump();
self.parse_trait_ref_list(token::LBRACE) Some(self.parse_trait_ref())
} else { } else {
~[] None
}; };
let mut meths = ~[]; let mut meths = ~[];
@ -2584,7 +2584,7 @@ struct parser {
let vis = self.parse_visibility(); let vis = self.parse_visibility();
vec::push(meths, self.parse_method(vis)); vec::push(meths, self.parse_method(vis));
} }
(ident, item_impl(tps, traits, ty, meths), None) (ident, item_impl(tps, opt_trait, ty, meths), None)
} }
// Instantiates ident <i> with references to <typarams> as arguments. // Instantiates ident <i> with references to <typarams> as arguments.

View file

@ -499,7 +499,7 @@ fn print_item(s: ps, &&item: @ast::item) {
print_struct(s, struct_def, tps, item.ident, item.span); print_struct(s, struct_def, tps, item.ident, item.span);
} }
ast::item_impl(tps, traits, ty, methods) => { ast::item_impl(tps, opt_trait, ty, methods) => {
head(s, ~"impl"); head(s, ~"impl");
if tps.is_not_empty() { if tps.is_not_empty() {
print_type_params(s, tps); print_type_params(s, tps);
@ -507,12 +507,13 @@ fn print_item(s: ps, &&item: @ast::item) {
} }
print_type(s, ty); print_type(s, ty);
if vec::len(traits) != 0u { match opt_trait {
word_space(s, ~":"); Some(t) => {
do commasep(s, inconsistent, traits) |s, p| { word_space(s, ~":");
print_path(s, p.path, false); print_path(s, t.path, false);
} }
} None => ()
};
space(s.s); space(s.s);
bopen(s); bopen(s);

View file

@ -699,7 +699,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
else { None }, tps); else { None }, tps);
} }
} }
item_impl(tps, traits, _, methods) => { item_impl(tps, opt_trait, _, methods) => {
add_to_index(); add_to_index();
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id)); encode_def_id(ebml_w, local_def(item.id));
@ -714,10 +714,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id)))); ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
ebml_w.end_tag(); ebml_w.end_tag();
} }
if traits.len() > 1 { do opt_trait.iter() |associated_trait| {
fail ~"multiple traits!!";
}
for traits.each |associated_trait| {
encode_trait_ref(ebml_w, ecx, associated_trait) encode_trait_ref(ebml_w, ecx, associated_trait)
} }
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));

View file

@ -3532,7 +3532,7 @@ struct Resolver {
fn resolve_implementation(id: node_id, fn resolve_implementation(id: node_id,
span: span, span: span,
type_parameters: ~[ty_param], type_parameters: ~[ty_param],
trait_references: ~[@trait_ref], opt_trait_reference: Option<@trait_ref>,
self_type: @ty, self_type: @ty,
methods: ~[@method], methods: ~[@method],
visitor: ResolveVisitor) { visitor: ResolveVisitor) {
@ -3549,10 +3549,10 @@ struct Resolver {
// Resolve the trait reference, if necessary. // Resolve the trait reference, if necessary.
let original_trait_refs = self.current_trait_refs; let original_trait_refs = self.current_trait_refs;
if trait_references.len() >= 1 { match opt_trait_reference {
let mut new_trait_refs = @DVec(); Some(trait_reference) => {
for trait_references.each |trait_reference| { let new_trait_refs = @DVec();
match self.resolve_path( match self.resolve_path(
trait_reference.path, TypeNS, true, visitor) { trait_reference.path, TypeNS, true, visitor) {
None => { None => {
self.session.span_err(span, self.session.span_err(span,
@ -3566,11 +3566,11 @@ struct Resolver {
(*new_trait_refs).push(def_id_of_def(def)); (*new_trait_refs).push(def_id_of_def(def));
} }
} }
}
// Record the current set of trait references. // Record the current set of trait references.
self.current_trait_refs = Some(new_trait_refs); self.current_trait_refs = Some(new_trait_refs);
} }
None => ()
}
// Resolve the self type. // Resolve the self type.
self.resolve_type(self_type, visitor); self.resolve_type(self_type, visitor);

View file

@ -3121,13 +3121,13 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
debug!("(impl_traits) searching for trait impl %?", id); debug!("(impl_traits) searching for trait impl %?", id);
match cx.items.find(id.node) { match cx.items.find(id.node) {
Some(ast_map::node_item(@{ Some(ast_map::node_item(@{
node: ast::item_impl(_, trait_refs, _, _), node: ast::item_impl(_, opt_trait, _, _),
_}, _},
_)) => { _)) => {
do vec::map(trait_refs) |trait_ref| { do option::map_default(opt_trait, ~[]) |trait_ref| {
node_id_to_type(cx, trait_ref.ref_id) ~[node_id_to_type(cx, trait_ref.ref_id)]
} }
} }
Some(ast_map::node_item(@{node: ast::item_class(sd,_), Some(ast_map::node_item(@{node: ast::item_class(sd,_),
_},_)) => { _},_)) => {

View file

@ -231,8 +231,8 @@ struct CoherenceChecker {
self.crate_context.tcx.sess.str_of(item.ident)); self.crate_context.tcx.sess.str_of(item.ident));
match item.node { match item.node {
item_impl(_, associated_traits, _, _) => { item_impl(_, opt_trait, _, _) => {
self.check_implementation(item, associated_traits); self.check_implementation(item, opt_trait.to_vec());
} }
item_class(struct_def, _) => { item_class(struct_def, _) => {
self.check_implementation(item, struct_def.traits); self.check_implementation(item, struct_def.traits);
@ -432,7 +432,7 @@ struct CoherenceChecker {
// Then visit the module items. // Then visit the module items.
visit_mod(module_, item.span, item.id, (), visitor); visit_mod(module_, item.span, item.id, (), visitor);
} }
item_impl(_, associated_traits, _, _) => { item_impl(_, opt_trait, _, _) => {
match self.base_type_def_ids.find( match self.base_type_def_ids.find(
local_def(item.id)) { local_def(item.id)) {
@ -453,7 +453,8 @@ struct CoherenceChecker {
// if the traits are defined in the same // if the traits are defined in the same
// crate. // crate.
if associated_traits.len() == 0 { match opt_trait {
None => {
// There is no trait to implement, so // There is no trait to implement, so
// this is an error. // this is an error.
@ -470,8 +471,10 @@ struct CoherenceChecker {
or new type \ or new type \
instead"); instead");
} }
_ => ()
}
for associated_traits.each |trait_ref| { do opt_trait.iter() |trait_ref| {
// This is OK if and only if the // This is OK if and only if the
// trait was defined in this // trait was defined in this
// crate. // crate.

View file

@ -243,10 +243,10 @@ fn fold_impl(
let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| { let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
match ctxt.ast_map.get(doc.id()) { match ctxt.ast_map.get(doc.id()) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_impl(_, trait_types, self_ty, _), _ node: ast::item_impl(_, opt_trait_type, self_ty, _), _
}, _) => { }, _) => {
let trait_types = vec::map(trait_types, |p| { let trait_types = opt_trait_type.map_default(~[], |p| {
pprust::path_to_str(p.path, extract::interner()) ~[pprust::path_to_str(p.path, extract::interner())]
}); });
(trait_types, Some(pprust::ty_to_str(self_ty, (trait_types, Some(pprust::ty_to_str(self_ty,
extract::interner()))) extract::interner())))

View file

@ -0,0 +1,8 @@
struct S {
y: int;
}
impl S: Cmp, ToStr { //~ ERROR: expected `{` but found `,`
fn eq(&&other: S) { false }
fn to_str() -> ~str { ~"hi" }
}