]> git.lizzy.rs Git - rust.git/commitdiff
Remove support for multiple traits in a single impl
authorTim Chevalier <chevalier@alum.wellesley.edu>
Fri, 7 Sep 2012 22:11:26 +0000 (15:11 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Sat, 8 Sep 2012 00:22:04 +0000 (17:22 -0700)
There was half-working support for them, but they were never fully
implemented or even approved. Remove them altogether.

Closes #3410

src/libsyntax/ast.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/rustc/metadata/encoder.rs
src/rustc/middle/resolve.rs
src/rustc/middle/ty.rs
src/rustc/middle/typeck/coherence.rs
src/rustdoc/tystr_pass.rs
src/test/compile-fail/multitrait.rs [new file with mode: 0644]

index b1f54e701ac8223c9835d929b10da816b0f9f0f4..140df4c29c0a298796402db43ad03af2aa0648c5 100644 (file)
@@ -1267,7 +1267,7 @@ enum item_ {
     item_class(@struct_def, ~[ty_param]),
     item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
     item_impl(~[ty_param],
-              ~[@trait_ref], /* traits this impl implements */
+              Option<@trait_ref>, /* (optional) trait this impl implements */
               @ty, /* self */
               ~[@method]),
     item_mac(mac),
index a21d9de7567dadd7e53daf857cd643a87dce76d3..2377555dfb3dcf7ba65a39658051648cd9df0cb8 100644 (file)
@@ -2571,11 +2571,11 @@ fn wrap_path(p: parser, pt: @path) -> @ty {
 
 
         // Parse traits, if necessary.
-        let traits = if self.token == token::COLON {
+        let opt_trait = if self.token == token::COLON {
             self.bump();
-            self.parse_trait_ref_list(token::LBRACE)
+            Some(self.parse_trait_ref())
         } else {
-            ~[]
+            None
         };
 
         let mut meths = ~[];
@@ -2584,7 +2584,7 @@ fn wrap_path(p: parser, pt: @path) -> @ty {
             let vis = self.parse_visibility();
             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.
index 451d5be1a500326752da1c70e75f8e65c36d9983..ae0eac571af7ab48434eb882c298a5a9e1f666bb 100644 (file)
@@ -499,7 +499,7 @@ fn print_item(s: ps, &&item: @ast::item) {
           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");
         if tps.is_not_empty() {
             print_type_params(s, tps);
@@ -507,12 +507,13 @@ fn print_item(s: ps, &&item: @ast::item) {
         }
         print_type(s, ty);
 
-        if vec::len(traits) != 0u {
-            word_space(s, ~":");
-            do commasep(s, inconsistent, traits) |s, p| {
-                print_path(s, p.path, false);
+        match opt_trait {
+            Some(t) => {
+                word_space(s, ~":");
+                print_path(s, t.path, false);
             }
-        }
+            None => ()
+        };
         space(s.s);
 
         bopen(s);
index 31f12a4b355ad2d74007c94c60912a06ea6be013..f45cd38fe832b45bb3a2ed44d1c3b04848cd26d1 100644 (file)
@@ -699,7 +699,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::Writer,
                                  else { None }, tps);
         }
       }
-      item_impl(tps, traits, _, methods) => {
+      item_impl(tps, opt_trait, _, methods) => {
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
@@ -714,10 +714,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::Writer,
             ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
             ebml_w.end_tag();
         }
-        if traits.len() > 1 {
-            fail ~"multiple traits!!";
-        }
-        for traits.each |associated_trait| {
+        do opt_trait.iter() |associated_trait| {
            encode_trait_ref(ebml_w, ecx, associated_trait)
         }
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
index 1b7f2d60bd7c709fd45569256e0eee1d1f4280f3..32f3348218ab2dc6f858e89e99aae003801c3c24 100644 (file)
@@ -3532,7 +3532,7 @@ fn resolve_method(rib_kind: RibKind,
     fn resolve_implementation(id: node_id,
                               span: span,
                               type_parameters: ~[ty_param],
-                              trait_references: ~[@trait_ref],
+                              opt_trait_reference: Option<@trait_ref>,
                               self_type: @ty,
                               methods: ~[@method],
                               visitor: ResolveVisitor) {
@@ -3549,10 +3549,10 @@ fn resolve_implementation(id: node_id,
 
             // Resolve the trait reference, if necessary.
             let original_trait_refs = self.current_trait_refs;
-            if trait_references.len() >= 1 {
-                let mut new_trait_refs = @DVec();
-                for trait_references.each |trait_reference| {
-                    match self.resolve_path(
+            match opt_trait_reference {
+              Some(trait_reference) => {
+                let new_trait_refs = @DVec();
+                match self.resolve_path(
                         trait_reference.path, TypeNS, true, visitor) {
                         None => {
                             self.session.span_err(span,
@@ -3566,11 +3566,11 @@ fn resolve_implementation(id: node_id,
                             (*new_trait_refs).push(def_id_of_def(def));
                         }
                     }
-                }
-
                 // Record the current set of trait references.
                 self.current_trait_refs = Some(new_trait_refs);
             }
+            None => ()
+            }
 
             // Resolve the self type.
             self.resolve_type(self_type, visitor);
index 4c81ccd21420878e9ef66f75fb19e4bc1de33619..1d6cd1f45c3acb0ab00f6d6b11edb749ee2d9bf6 100644 (file)
@@ -3121,13 +3121,13 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
         debug!("(impl_traits) searching for trait impl %?", id);
         match cx.items.find(id.node) {
            Some(ast_map::node_item(@{
-                        node: ast::item_impl(_, trait_refs, _, _),
+                        node: ast::item_impl(_, opt_trait, _, _),
                         _},
                     _)) => {
 
-                do vec::map(trait_refs) |trait_ref| {
-                    node_id_to_type(cx, trait_ref.ref_id)
-                }
+               do option::map_default(opt_trait, ~[]) |trait_ref| {
+                       ~[node_id_to_type(cx, trait_ref.ref_id)]
+                   }
            }
            Some(ast_map::node_item(@{node: ast::item_class(sd,_),
                            _},_)) => {
index 768431ce4fbb1db149ce82e26136e5864034eff4..434a2b1caf2601f2b12d83b7663e8ec1a8136c87 100644 (file)
@@ -231,8 +231,8 @@ fn check_coherence(crate: @crate) {
                        self.crate_context.tcx.sess.str_of(item.ident));
 
                 match item.node {
-                    item_impl(_, associated_traits, _, _) => {
-                        self.check_implementation(item, associated_traits);
+                    item_impl(_, opt_trait, _, _) => {
+                        self.check_implementation(item, opt_trait.to_vec());
                     }
                     item_class(struct_def, _) => {
                         self.check_implementation(item, struct_def.traits);
@@ -432,7 +432,7 @@ fn check_privileged_scopes(crate: @crate) {
                         // Then visit the module items.
                         visit_mod(module_, item.span, item.id, (), visitor);
                     }
-                    item_impl(_, associated_traits, _, _) => {
+                    item_impl(_, opt_trait, _, _) => {
                         match self.base_type_def_ids.find(
                             local_def(item.id)) {
 
@@ -453,7 +453,8 @@ fn check_privileged_scopes(crate: @crate) {
                                     // if the traits are defined in the same
                                     // crate.
 
-                                    if associated_traits.len() == 0 {
+                                  match opt_trait {
+                                    None => {
                                         // There is no trait to implement, so
                                         // this is an error.
 
@@ -470,8 +471,10 @@ fn check_privileged_scopes(crate: @crate) {
                                                           or new type \
                                                           instead");
                                     }
+                                    _ => ()
+                                  }
 
-                                    for associated_traits.each |trait_ref| {
+                                  do opt_trait.iter() |trait_ref| {
                                         // This is OK if and only if the
                                         // trait was defined in this
                                         // crate.
index 3ea9d0fa81b8dbb35dadd8d262b270feef562d5c..68a3c94316e6981fdbd08601e597142cb6adfec2 100644 (file)
@@ -243,10 +243,10 @@ fn fold_impl(
     let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
         match ctxt.ast_map.get(doc.id()) {
           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| {
-                pprust::path_to_str(p.path, extract::interner())
+            let trait_types = opt_trait_type.map_default(~[], |p| {
+                ~[pprust::path_to_str(p.path, extract::interner())]
             });
             (trait_types, Some(pprust::ty_to_str(self_ty,
                                                  extract::interner())))
diff --git a/src/test/compile-fail/multitrait.rs b/src/test/compile-fail/multitrait.rs
new file mode 100644 (file)
index 0000000..6ce063e
--- /dev/null
@@ -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" }
+}
\ No newline at end of file