about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-03 15:02:01 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-03 15:02:53 -0700
commitb65dd9d0908ba75ee4cf128058858aea87e4508a (patch)
tree794ee6f47d188314a2b0256fd954cbcf8219331c
parenta805a1fb37443601819604954510cb312a724fe9 (diff)
downloadrust-b65dd9d0908ba75ee4cf128058858aea87e4508a.tar.gz
rust-b65dd9d0908ba75ee4cf128058858aea87e4508a.zip
rustc: Parse, serialize, and deserialize trait inheritance
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_map.rs10
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/parse/parser.rs12
-rw-r--r--src/libsyntax/print/pprust.rs7
-rw-r--r--src/libsyntax/visit.rs3
-rw-r--r--src/rustc/metadata/encoder.rs5
-rw-r--r--src/rustc/middle/resolve3.rs25
-rw-r--r--src/rustc/middle/typeck/check.rs4
-rw-r--r--src/rustc/middle/typeck/collect.rs13
-rw-r--r--src/rustdoc/attr_pass.rs2
-rw-r--r--src/rustdoc/extract.rs2
-rw-r--r--src/rustdoc/tystr_pass.rs2
13 files changed, 69 insertions, 21 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 1b60cb6c47b..34144a9f031 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -724,7 +724,7 @@ enum item_ {
                /* dtor is optional */
                option<class_dtor>
                ),
-    item_trait(~[ty_param], ~[trait_method]),
+    item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
     item_impl(~[ty_param],
               ~[@trait_ref], /* traits this impl implements */
               @ty, /* self */
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index acd20951328..c8daae0982d 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -231,7 +231,15 @@ fn map_item(i: @item, cx: ctx, v: vt) {
            // only need to handle methods
           do vec::iter(ms) |m| { map_method(d_id, p, m, cx); }
       }
-      item_trait(tps, methods) {
+      item_trait(tps, traits, methods) {
+        // Map trait refs to their parent classes. This is
+        // so we can find the self_ty
+        for traits.each |p| {
+            cx.map.insert(p.ref_id, node_item(i, item_path));
+            // This is so we can look up the right things when
+            // encoding/decoding
+            cx.map.insert(p.impl_id, node_item(i, item_path));
+        }
         for methods.each |tm| {
             let id = ast_util::trait_method_to_ty_method(tm).id;
             let d_id = ast_util::local_def(i.id);
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index bbf6df468f8..5fa9c584bc4 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -279,8 +279,9 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
                         fld.fold_ty(ty),
                         vec::map(methods, |x| fld.fold_method(x)))
           }
-          item_trait(tps, methods) {
+          item_trait(tps, traits, methods) {
             item_trait(fold_ty_params(tps, fld),
+                       vec::map(traits, |p| fold_trait_ref(p, fld)),
                        /* FIXME (#2543) */ copy methods)
           }
       item_mac(m) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 417d973ee0d..5f2ea6f42f6 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2278,8 +2278,18 @@ class parser {
         let ident = self.parse_ident();
         self.parse_region_param();
         let tps = self.parse_ty_params();
+        
+        // Parse traits, if necessary.
+        let traits;
+        if self.token == token::COLON {
+            self.bump();
+            traits = self.parse_trait_ref_list(token::LBRACE);
+        } else {
+            traits = ~[];
+        }
+
         let meths = self.parse_trait_methods();
-        (ident, item_trait(tps, meths), none)
+        (ident, item_trait(tps, traits, meths), none)
     }
 
     // Parses four variants (with the region/type params always optional):
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index feea800b44c..c4b643de8d7 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -590,10 +590,15 @@ fn print_item(s: ps, &&item: @ast::item) {
         }
         bclose(s, item.span);
       }
-      ast::item_trait(tps, methods) {
+      ast::item_trait(tps, traits, methods) {
         head(s, ~"trait");
         word(s.s, *item.ident);
         print_type_params(s, tps);
+        if vec::len(traits) != 0u {
+            word_space(s, ~":");
+            commasep(s, inconsistent, traits, |s, p|
+                print_path(s, p.path, false));
+        }
         word(s.s, ~" ");
         bopen(s);
         for methods.each |meth| { print_trait_method(s, meth); }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index f2159af34e7..61cbba5fc1f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -162,8 +162,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
                                     ast_util::local_def(i.id), e, v)
           };
       }
-      item_trait(tps, methods) {
+      item_trait(tps, traits, methods) {
         v.visit_ty_params(tps, e, v);
+        for traits.each |p| { visit_path(p.path, e, v); }
         for methods.each |m| {
             v.visit_trait_method(m, e, v);
         }
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 256d8e310c4..a5d398c7ad0 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -813,7 +813,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
                                    vec::append(tps, m.tps));
         }
       }
-      item_trait(tps, ms) {
+      item_trait(tps, traits, ms) {
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
@@ -844,6 +844,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
             i += 1u;
         }
         encode_path(ebml_w, path, ast_map::path_name(item.ident));
+        for traits.each |associated_trait| {
+           encode_trait_ref(ebml_w, ecx, associated_trait)
+        }
         ebml_w.end_tag();
       }
       item_mac(*) { fail ~"item macros unimplemented" }
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index 243c2af19b2..93173b4008f 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -988,7 +988,7 @@ class Resolver {
                 visit_item(item, new_parent, visitor);
             }
 
-            item_trait(_, methods) {
+            item_trait(_, _, methods) {
                 // Add the names of all the methods to the trait info.
                 let method_names = @atom_hashmap();
                 for methods.each |method| {
@@ -3063,7 +3063,7 @@ class Resolver {
                                             self_type, methods, visitor);
             }
 
-            item_trait(type_parameters, methods) {
+            item_trait(type_parameters, traits, methods) {
                 // Create a new rib for the self type.
                 let self_type_rib = @Rib(NormalRibKind);
                 (*self.type_ribs).push(self_type_rib);
@@ -3077,6 +3077,27 @@ class Resolver {
 
                     self.resolve_type_parameters(type_parameters, visitor);
 
+                    // Resolve derived traits.
+                    for traits.each |trt| {
+                        match self.resolve_path(trt.path, TypeNS, true,
+                                                visitor) {
+                            none =>
+                                self.session.span_err(trt.path.span,
+                                                      ~"attempt to derive a \
+                                                       nonexistent trait"),
+                            some(def) => {
+                                // Write a mapping from the trait ID to the
+                                // definition of the trait into the definition
+                                // map.
+
+                                debug!{"(resolving trait) found trait def: \
+                                       %?", def};
+
+                                self.record_def(trt.ref_id, def);
+                            }
+                        }
+                    }
+
                     for methods.each |method| {
                         // Create a new rib for the method-specific type
                         // parameters.
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 91caf75f602..65ad1b26a8d 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -419,7 +419,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
                          node_id: it.id };
         for ms.each |m| { check_method(ccx, m, self_info);}
       }
-      ast::item_trait(_, trait_methods) {
+      ast::item_trait(_, _, trait_methods) {
         for trait_methods.each |trait_method| {
             alt trait_method {
               required(ty_m) {
@@ -434,7 +434,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
             }
         }
       }
-      ast::item_class(tps, traits, members, m_ctor, m_dtor) {
+      ast::item_class(tps, _, members, m_ctor, m_dtor) {
         let tcx = ccx.tcx;
         let class_t = {self_ty: ty::node_id_to_type(tcx, it.id),
                        node_id: it.id};
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index da9575b898e..ae748b541ff 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -38,20 +38,19 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
                     let substs = {self_r: none, self_ty: none, tps: ~[]};
 
                     alt intrinsic_item.node {
-
-                      ast::item_trait(_, _) {
+                      ast::item_trait(*) => {
                         let ty = ty::mk_trait(ccx.tcx, def_id, substs);
                         ccx.tcx.intrinsic_defs.insert
                             (intrinsic_item.ident, (def_id, ty));
                       }
 
-                      ast::item_enum(_, _) {
+                      ast::item_enum(*) => {
                         let ty = ty::mk_enum(ccx.tcx, def_id, substs);
                         ccx.tcx.intrinsic_defs.insert
                             (intrinsic_item.ident, (def_id, ty));
                       }
 
-                     _ { }
+                      _ => {}
                     }
                 }
               }
@@ -147,7 +146,7 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id) {
     let tcx = ccx.tcx;
     let rp = tcx.region_paramd_items.contains_key(id);
     alt check tcx.items.get(id) {
-      ast_map::node_item(@{node: ast::item_trait(_, ms), _}, _) {
+      ast_map::node_item(@{node: ast::item_trait(_, _, ms), _}, _) {
         store_methods::<ast::trait_method>(ccx, id, ms, |m| {
             alt m {
               required(ty_m) {
@@ -339,7 +338,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
             check_methods_against_trait(ccx, tps, rp, selfty, t, cms);
         }
       }
-      ast::item_trait(tps, trait_methods) {
+      ast::item_trait(tps, _, trait_methods) {
         let tpt = ty_of_item(ccx, it);
         debug!{"item_trait(it.id=%d, tpt.ty=%s)",
                it.id, ty_to_str(tcx, tpt.ty)};
@@ -550,7 +549,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
         tcx.tcache.insert(local_def(it.id), tpt);
         return tpt;
       }
-      ast::item_trait(tps, ms) {
+      ast::item_trait(tps, _, ms) {
         let {bounds, substs} = mk_substs(ccx, tps, rp);
         let t = ty::mk_trait(tcx, local_def(it.id), substs);
         let tpt = {bounds: bounds, rp: rp, ty: t};
diff --git a/src/rustdoc/attr_pass.rs b/src/rustdoc/attr_pass.rs
index a5c41d23574..e22f3a1c9bb 100644
--- a/src/rustdoc/attr_pass.rs
+++ b/src/rustdoc/attr_pass.rs
@@ -205,7 +205,7 @@ fn merge_method_attrs(
     let attrs: ~[(~str, option<~str>)] = do astsrv::exec(srv) |ctxt| {
         alt ctxt.ast_map.get(item_id) {
           ast_map::node_item(@{
-            node: ast::item_trait(_, methods), _
+            node: ast::item_trait(_, _, methods), _
           }, _) {
             vec::map(methods, |method| {
                 alt method {
diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs
index 0028887d490..a6c653de326 100644
--- a/src/rustdoc/extract.rs
+++ b/src/rustdoc/extract.rs
@@ -84,7 +84,7 @@ fn moddoc_from_mod(
                     enumdoc_from_enum(itemdoc, variants)
                 ))
               }
-              ast::item_trait(_, methods) {
+              ast::item_trait(_, _, methods) {
                 some(doc::traittag(
                     traitdoc_from_trait(itemdoc, methods)
                 ))
diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs
index 865a4361aac..ce1f921af27 100644
--- a/src/rustdoc/tystr_pass.rs
+++ b/src/rustdoc/tystr_pass.rs
@@ -169,7 +169,7 @@ fn get_method_sig(
     do astsrv::exec(srv) |ctxt| {
         alt check ctxt.ast_map.get(item_id) {
           ast_map::node_item(@{
-            node: ast::item_trait(_, methods), _
+            node: ast::item_trait(_, _, methods), _
           }, _) {
             alt check vec::find(methods, |method| {
                 alt method {