about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-19 22:26:32 -0700
committerbors <bors@rust-lang.org>2014-04-19 22:26:32 -0700
commitfc2815a5cc703523c9a9aa2f2982e667e58a0402 (patch)
tree93a2455c9ddd26ba2e2eaaabc14c7f27d67e81db /src/libsyntax
parent7b6e7ebe73b5f046faa81406ed58866364f6cfee (diff)
parentff04aa8e385f343f66c5bed6a34d1ebf6c971e4d (diff)
downloadrust-fc2815a5cc703523c9a9aa2f2982e667e58a0402.tar.gz
rust-fc2815a5cc703523c9a9aa2f2982e667e58a0402.zip
auto merge of #12562 : nick29581/rust/fields, r=nikomatsakis
No subtyping, no interaction with traits. Partially addresses #9912.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/libsyntax/fold.rs12
-rw-r--r--src/libsyntax/parse/parser.rs35
-rw-r--r--src/libsyntax/parse/token.rs29
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/visit.rs4
6 files changed, 73 insertions, 21 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 33c0f2c46bb..2b6f94e6bf5 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1080,7 +1080,9 @@ pub struct StructDef {
     pub fields: Vec<StructField>, /* fields, not including ctor */
     /* ID of the constructor. This is only used for tuple- or enum-like
      * structs. */
-    pub ctor_id: Option<NodeId>
+    pub ctor_id: Option<NodeId>,
+    pub super_struct: Option<P<Ty>>, // Super struct, if specified.
+    pub is_virtual: bool,            // True iff the struct may be inherited from.
 }
 
 /*
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index fc4f427d8d7..73ad2664be4 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -235,7 +235,12 @@ pub trait Folder {
                 kind = StructVariantKind(@ast::StructDef {
                     fields: struct_def.fields.iter()
                         .map(|f| self.fold_struct_field(f)).collect(),
-                    ctor_id: struct_def.ctor_id.map(|c| self.new_id(c))
+                    ctor_id: struct_def.ctor_id.map(|c| self.new_id(c)),
+                    super_struct: match struct_def.super_struct {
+                        Some(t) => Some(self.fold_ty(t)),
+                        None => None
+                    },
+                    is_virtual: struct_def.is_virtual,
                 })
             }
         }
@@ -480,6 +485,11 @@ fn fold_struct_def<T: Folder>(struct_def: @StructDef, fld: &mut T) -> @StructDef
     @ast::StructDef {
         fields: struct_def.fields.iter().map(|f| fold_struct_field(f, fld)).collect(),
         ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)),
+        super_struct: match struct_def.super_struct {
+            Some(t) => Some(fld.fold_ty(t)),
+            None => None
+        },
+        is_virtual: struct_def.is_virtual,
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 58634be1995..3d09147d8f3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3884,11 +3884,26 @@ impl<'a> Parser<'a> {
     }
 
     // parse struct Foo { ... }
-    fn parse_item_struct(&mut self) -> ItemInfo {
+    fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
         let class_name = self.parse_ident();
         let generics = self.parse_generics();
 
-        let mut fields: Vec<StructField> ;
+        let super_struct = if self.eat(&token::COLON) {
+            let ty = self.parse_ty(false);
+            match ty.node {
+                TyPath(_, None, _) => {
+                    Some(ty)
+                }
+                _ => {
+                    self.span_err(ty.span, "not a struct");
+                    None
+                }
+            }
+        } else {
+            None
+        };
+
+        let mut fields: Vec<StructField>;
         let is_tuple_like;
 
         if self.eat(&token::LBRACE) {
@@ -3938,7 +3953,9 @@ impl<'a> Parser<'a> {
         (class_name,
          ItemStruct(@ast::StructDef {
              fields: fields,
-             ctor_id: if is_tuple_like { Some(new_id) } else { None }
+             ctor_id: if is_tuple_like { Some(new_id) } else { None },
+             super_struct: super_struct,
+             is_virtual: is_virtual,
          }, generics),
          None)
     }
@@ -4329,7 +4346,9 @@ impl<'a> Parser<'a> {
 
         return @ast::StructDef {
             fields: fields,
-            ctor_id: None
+            ctor_id: None,
+            super_struct: None,
+            is_virtual: false,
         };
     }
 
@@ -4514,6 +4533,12 @@ impl<'a> Parser<'a> {
                             format!("expected `\\{` or `fn` but found `{}`", token_str));
         }
 
+        let is_virtual = self.eat_keyword(keywords::Virtual);
+        if is_virtual && !self.is_keyword(keywords::Struct) {
+            self.span_err(self.span,
+                          "`virtual` keyword may only be used with `struct`");
+        }
+
         // the rest are all guaranteed to be items:
         if self.is_keyword(keywords::Static) {
             // STATIC ITEM
@@ -4614,7 +4639,7 @@ impl<'a> Parser<'a> {
         }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_struct();
+            let (ident, item_, extra_attrs) = self.parse_item_struct(is_virtual);
             let item = self.mk_item(lo,
                                     self.last_span.hi,
                                     ident,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 77743cdb9df..611ce7cc527 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -474,22 +474,23 @@ declare_special_idents_and_keywords! {
         (35,                         Type,       "type");
         (36,                         Unsafe,     "unsafe");
         (37,                         Use,        "use");
-        (38,                         While,      "while");
-        (39,                         Continue,   "continue");
-        (40,                         Proc,       "proc");
-        (41,                         Box,        "box");
+        (38,                         Virtual,    "virtual");
+        (39,                         While,      "while");
+        (40,                         Continue,   "continue");
+        (41,                         Proc,       "proc");
+        (42,                         Box,        "box");
 
         'reserved:
-        (42,                         Alignof,    "alignof");
-        (43,                         Be,         "be");
-        (44,                         Offsetof,   "offsetof");
-        (45,                         Priv,       "priv");
-        (46,                         Pure,       "pure");
-        (47,                         Sizeof,     "sizeof");
-        (48,                         Typeof,     "typeof");
-        (49,                         Unsized,    "unsized");
-        (50,                         Yield,      "yield");
-        (51,                         Do,         "do");
+        (43,                         Alignof,    "alignof");
+        (44,                         Be,         "be");
+        (45,                         Offsetof,   "offsetof");
+        (46,                         Priv,       "priv");
+        (47,                         Pure,       "pure");
+        (48,                         Sizeof,     "sizeof");
+        (49,                         Typeof,     "typeof");
+        (50,                         Unsized,    "unsized");
+        (51,                         Yield,      "yield");
+        (52,                         Do,         "do");
     }
 }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7041a6585a0..f4e337e2048 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -640,6 +640,9 @@ impl<'a> State<'a> {
                 ));
             }
             ast::ItemStruct(struct_def, ref generics) => {
+                if struct_def.is_virtual {
+                    try!(self.word_space("virtual"));
+                }
                 try!(self.head(visibility_qualified(item.vis, "struct")));
                 try!(self.print_struct(struct_def, generics, item.ident, item.span));
             }
@@ -754,6 +757,13 @@ impl<'a> State<'a> {
                         span: codemap::Span) -> IoResult<()> {
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
+        match struct_def.super_struct {
+            Some(t) => {
+                try!(self.word_space(":"));
+                try!(self.print_type(t));
+            },
+            None => {},
+        }
         if ast_util::struct_def_is_tuple_like(struct_def) {
             if !struct_def.fields.is_empty() {
                 try!(self.popen());
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 266de67b81d..1f75c2e062f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -571,6 +571,10 @@ pub fn walk_struct_def<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                                 _: &Generics,
                                                 _: NodeId,
                                                 env: E) {
+    match struct_definition.super_struct {
+        Some(t) => visitor.visit_ty(t, env.clone()),
+        None => {},
+    }
     for field in struct_definition.fields.iter() {
         visitor.visit_struct_field(field, env.clone())
     }