Skip to content

Commit f5093df

Browse files
committed
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
1 parent 62ab9d7 commit f5093df

File tree

9 files changed

+44
-35
lines changed

9 files changed

+44
-35
lines changed

src/libsyntax/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ enum item_ {
12671267
item_class(@struct_def, ~[ty_param]),
12681268
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
12691269
item_impl(~[ty_param],
1270-
~[@trait_ref], /* traits this impl implements */
1270+
Option<@trait_ref>, /* (optional) trait this impl implements */
12711271
@ty, /* self */
12721272
~[@method]),
12731273
item_mac(mac),

src/libsyntax/parse/parser.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2571,11 +2571,11 @@ struct parser {
25712571

25722572

25732573
// Parse traits, if necessary.
2574-
let traits = if self.token == token::COLON {
2574+
let opt_trait = if self.token == token::COLON {
25752575
self.bump();
2576-
self.parse_trait_ref_list(token::LBRACE)
2576+
Some(self.parse_trait_ref())
25772577
} else {
2578-
~[]
2578+
None
25792579
};
25802580

25812581
let mut meths = ~[];
@@ -2584,7 +2584,7 @@ struct parser {
25842584
let vis = self.parse_visibility();
25852585
vec::push(meths, self.parse_method(vis));
25862586
}
2587-
(ident, item_impl(tps, traits, ty, meths), None)
2587+
(ident, item_impl(tps, opt_trait, ty, meths), None)
25882588
}
25892589

25902590
// Instantiates ident <i> with references to <typarams> as arguments.

src/libsyntax/print/pprust.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -499,20 +499,21 @@ fn print_item(s: ps, &&item: @ast::item) {
499499
print_struct(s, struct_def, tps, item.ident, item.span);
500500
}
501501

502-
ast::item_impl(tps, traits, ty, methods) => {
502+
ast::item_impl(tps, opt_trait, ty, methods) => {
503503
head(s, ~"impl");
504504
if tps.is_not_empty() {
505505
print_type_params(s, tps);
506506
space(s.s);
507507
}
508508
print_type(s, ty);
509509

510-
if vec::len(traits) != 0u {
511-
word_space(s, ~":");
512-
do commasep(s, inconsistent, traits) |s, p| {
513-
print_path(s, p.path, false);
510+
match opt_trait {
511+
Some(t) => {
512+
word_space(s, ~":");
513+
print_path(s, t.path, false);
514514
}
515-
}
515+
None => ()
516+
};
516517
space(s.s);
517518

518519
bopen(s);

src/rustc/metadata/encoder.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
699699
else { None }, tps);
700700
}
701701
}
702-
item_impl(tps, traits, _, methods) => {
702+
item_impl(tps, opt_trait, _, methods) => {
703703
add_to_index();
704704
ebml_w.start_tag(tag_items_data_item);
705705
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,
714714
ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
715715
ebml_w.end_tag();
716716
}
717-
if traits.len() > 1 {
718-
fail ~"multiple traits!!";
719-
}
720-
for traits.each |associated_trait| {
717+
do opt_trait.iter() |associated_trait| {
721718
encode_trait_ref(ebml_w, ecx, associated_trait)
722719
}
723720
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));

src/rustc/middle/resolve.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3532,7 +3532,7 @@ struct Resolver {
35323532
fn resolve_implementation(id: node_id,
35333533
span: span,
35343534
type_parameters: ~[ty_param],
3535-
trait_references: ~[@trait_ref],
3535+
opt_trait_reference: Option<@trait_ref>,
35363536
self_type: @ty,
35373537
methods: ~[@method],
35383538
visitor: ResolveVisitor) {
@@ -3549,10 +3549,10 @@ struct Resolver {
35493549

35503550
// Resolve the trait reference, if necessary.
35513551
let original_trait_refs = self.current_trait_refs;
3552-
if trait_references.len() >= 1 {
3553-
let mut new_trait_refs = @DVec();
3554-
for trait_references.each |trait_reference| {
3555-
match self.resolve_path(
3552+
match opt_trait_reference {
3553+
Some(trait_reference) => {
3554+
let new_trait_refs = @DVec();
3555+
match self.resolve_path(
35563556
trait_reference.path, TypeNS, true, visitor) {
35573557
None => {
35583558
self.session.span_err(span,
@@ -3566,11 +3566,11 @@ struct Resolver {
35663566
(*new_trait_refs).push(def_id_of_def(def));
35673567
}
35683568
}
3569-
}
3570-
35713569
// Record the current set of trait references.
35723570
self.current_trait_refs = Some(new_trait_refs);
35733571
}
3572+
None => ()
3573+
}
35743574

35753575
// Resolve the self type.
35763576
self.resolve_type(self_type, visitor);

src/rustc/middle/ty.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -3121,13 +3121,13 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
31213121
debug!("(impl_traits) searching for trait impl %?", id);
31223122
match cx.items.find(id.node) {
31233123
Some(ast_map::node_item(@{
3124-
node: ast::item_impl(_, trait_refs, _, _),
3124+
node: ast::item_impl(_, opt_trait, _, _),
31253125
_},
31263126
_)) => {
31273127

3128-
do vec::map(trait_refs) |trait_ref| {
3129-
node_id_to_type(cx, trait_ref.ref_id)
3130-
}
3128+
do option::map_default(opt_trait, ~[]) |trait_ref| {
3129+
~[node_id_to_type(cx, trait_ref.ref_id)]
3130+
}
31313131
}
31323132
Some(ast_map::node_item(@{node: ast::item_class(sd,_),
31333133
_},_)) => {

src/rustc/middle/typeck/coherence.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ struct CoherenceChecker {
231231
self.crate_context.tcx.sess.str_of(item.ident));
232232

233233
match item.node {
234-
item_impl(_, associated_traits, _, _) => {
235-
self.check_implementation(item, associated_traits);
234+
item_impl(_, opt_trait, _, _) => {
235+
self.check_implementation(item, opt_trait.to_vec());
236236
}
237237
item_class(struct_def, _) => {
238238
self.check_implementation(item, struct_def.traits);
@@ -432,7 +432,7 @@ struct CoherenceChecker {
432432
// Then visit the module items.
433433
visit_mod(module_, item.span, item.id, (), visitor);
434434
}
435-
item_impl(_, associated_traits, _, _) => {
435+
item_impl(_, opt_trait, _, _) => {
436436
match self.base_type_def_ids.find(
437437
local_def(item.id)) {
438438

@@ -453,7 +453,8 @@ struct CoherenceChecker {
453453
// if the traits are defined in the same
454454
// crate.
455455

456-
if associated_traits.len() == 0 {
456+
match opt_trait {
457+
None => {
457458
// There is no trait to implement, so
458459
// this is an error.
459460

@@ -470,8 +471,10 @@ struct CoherenceChecker {
470471
or new type \
471472
instead");
472473
}
474+
_ => ()
475+
}
473476

474-
for associated_traits.each |trait_ref| {
477+
do opt_trait.iter() |trait_ref| {
475478
// This is OK if and only if the
476479
// trait was defined in this
477480
// crate.

src/rustdoc/tystr_pass.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,10 @@ fn fold_impl(
243243
let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
244244
match ctxt.ast_map.get(doc.id()) {
245245
ast_map::node_item(@{
246-
node: ast::item_impl(_, trait_types, self_ty, _), _
246+
node: ast::item_impl(_, opt_trait_type, self_ty, _), _
247247
}, _) => {
248-
let trait_types = vec::map(trait_types, |p| {
249-
pprust::path_to_str(p.path, extract::interner())
248+
let trait_types = opt_trait_type.map_default(~[], |p| {
249+
~[pprust::path_to_str(p.path, extract::interner())]
250250
});
251251
(trait_types, Some(pprust::ty_to_str(self_ty,
252252
extract::interner())))

src/test/compile-fail/multitrait.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct S {
2+
y: int;
3+
}
4+
5+
impl S: Cmp, ToStr { //~ ERROR: expected `{` but found `,`
6+
fn eq(&&other: S) { false }
7+
fn to_str() -> ~str { ~"hi" }
8+
}

0 commit comments

Comments
 (0)