提交 40aa09e4 编写于 作者: V Vadim Petrochenkov

Merge struct fields and struct kind

上级 30af54de
...@@ -138,7 +138,7 @@ fn visit_item(&mut self, i: &'ast Item) { ...@@ -138,7 +138,7 @@ fn visit_item(&mut self, i: &'ast Item) {
NodeVariant(&**v), NodeVariant(&**v),
DefPathData::EnumVariant(v.node.name)); DefPathData::EnumVariant(v.node.name));
for field in &v.node.data.fields { for field in v.node.data.fields() {
self.create_def_with_parent( self.create_def_with_parent(
Some(variant_def_index), Some(variant_def_index),
field.node.id, field.node.id,
...@@ -150,13 +150,13 @@ fn visit_item(&mut self, i: &'ast Item) { ...@@ -150,13 +150,13 @@ fn visit_item(&mut self, i: &'ast Item) {
} }
ItemStruct(ref struct_def, _) => { ItemStruct(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor. // If this is a tuple-like struct, register the constructor.
if struct_def.kind != VariantKind::Struct { if !struct_def.is_struct() {
self.insert_def(struct_def.id, self.insert_def(struct_def.id,
NodeStructCtor(&**struct_def), NodeStructCtor(&**struct_def),
DefPathData::StructCtor); DefPathData::StructCtor);
} }
for field in &struct_def.fields { for field in struct_def.fields() {
self.create_def(field.node.id, DefPathData::Field(field.node.kind)); self.create_def(field.node.id, DefPathData::Field(field.node.kind));
} }
} }
......
...@@ -480,9 +480,10 @@ pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData { ...@@ -480,9 +480,10 @@ pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData {
} }
} }
Some(NodeVariant(variant)) => { Some(NodeVariant(variant)) => {
match variant.node.data.kind { if variant.node.data.is_struct() {
VariantKind::Struct => &variant.node.data, &variant.node.data
_ => panic!("struct ID bound to enum variant that isn't struct-like"), } else {
panic!("struct ID bound to enum variant that isn't struct-like")
} }
} }
_ => panic!(format!("expected struct, found {}", self.node_to_string(id))), _ => panic!(format!("expected struct, found {}", self.node_to_string(id))),
......
...@@ -381,7 +381,7 @@ fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where ...@@ -381,7 +381,7 @@ fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where
match item.node { match item.node {
hir::ItemStruct(ref struct_def, _) => { hir::ItemStruct(ref struct_def, _) => {
// If this is a newtype struct, return the constructor. // If this is a newtype struct, return the constructor.
if struct_def.kind == hir::VariantKind::Tuple { if struct_def.is_tuple() {
continue_ = callback(struct_def.id); continue_ = callback(struct_def.id);
} }
} }
...@@ -1068,7 +1068,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ...@@ -1068,7 +1068,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
// Encode inherent implementations for this structure. // Encode inherent implementations for this structure.
encode_inherent_implementations(ecx, rbml_w, def_id); encode_inherent_implementations(ecx, rbml_w, def_id);
if struct_def.kind != hir::VariantKind::Struct { if !struct_def.is_struct() {
let ctor_did = ecx.tcx.map.local_def_id(struct_def.id); let ctor_did = ecx.tcx.map.local_def_id(struct_def.id);
rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor,
def_to_u64(ctor_did)); def_to_u64(ctor_did));
...@@ -1081,7 +1081,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ...@@ -1081,7 +1081,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
} }
// If this is a tuple-like struct, encode the type of the constructor. // If this is a tuple-like struct, encode the type of the constructor.
if struct_def.kind != hir::VariantKind::Struct { if !struct_def.is_struct() {
encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id, index, item.id); encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id, index, item.id);
} }
} }
......
...@@ -1320,7 +1320,7 @@ fn copy_item_type(dcx: &DecodeContext, ...@@ -1320,7 +1320,7 @@ fn copy_item_type(dcx: &DecodeContext,
} }
} }
hir::ItemStruct(ref def, _) => { hir::ItemStruct(ref def, _) => {
if def.kind != hir::VariantKind::Struct { if !def.is_struct() {
let ctor_did = dcx.tcx.lookup_adt_def(orig_did) let ctor_did = dcx.tcx.lookup_adt_def(orig_did)
.struct_variant().did; .struct_variant().did;
debug!("astencode: copying ctor {:?} => {:?}", ctor_did, debug!("astencode: copying ctor {:?} => {:?}", ctor_did,
......
...@@ -219,7 +219,7 @@ fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name, ...@@ -219,7 +219,7 @@ fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name,
_: &hir::Generics, _: ast::NodeId, _: codemap::Span) { _: &hir::Generics, _: ast::NodeId, _: codemap::Span) {
let has_extern_repr = self.struct_has_extern_repr; let has_extern_repr = self.struct_has_extern_repr;
let inherited_pub_visibility = self.inherited_pub_visibility; let inherited_pub_visibility = self.inherited_pub_visibility;
let live_fields = def.fields.iter().filter(|f| { let live_fields = def.fields().filter(|f| {
has_extern_repr || inherited_pub_visibility || match f.node.kind { has_extern_repr || inherited_pub_visibility || match f.node.kind {
hir::NamedField(_, hir::Public) => true, hir::NamedField(_, hir::Public) => true,
_ => false _ => false
...@@ -426,7 +426,7 @@ fn find_live(tcx: &ty::ctxt, ...@@ -426,7 +426,7 @@ fn find_live(tcx: &ty::ctxt,
fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> { fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
match item.node { match item.node {
hir::ItemStruct(ref struct_def, _) if struct_def.kind != hir::VariantKind::Struct => { hir::ItemStruct(ref struct_def, _) if !struct_def.is_struct() => {
Some(struct_def.id) Some(struct_def.id)
} }
_ => None _ => None
......
...@@ -185,7 +185,7 @@ fn visit_item(&mut self, i: &Item) { ...@@ -185,7 +185,7 @@ fn visit_item(&mut self, i: &Item) {
|v| visit::walk_item(v, i), required); |v| visit::walk_item(v, i), required);
if let hir::ItemStruct(ref sd, _) = i.node { if let hir::ItemStruct(ref sd, _) = i.node {
if sd.kind != hir::VariantKind::Struct { if !sd.is_struct() {
self.annotate(sd.id, true, &i.attrs, i.span, |_| {}, true) self.annotate(sd.id, true, &i.attrs, i.span, |_| {}, true)
} }
} }
......
...@@ -694,11 +694,18 @@ pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) - ...@@ -694,11 +694,18 @@ pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) -
} }
pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> { pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
struct_def.map(|VariantData { fields, id, kind }| { struct_def.map(|VariantData { data_, id }| {
VariantData { VariantData {
fields: fields.move_map(|f| fld.fold_struct_field(f)), data_: match data_ {
VariantData_::Struct(fields) => {
VariantData_::Struct(fields.move_map(|f| fld.fold_struct_field(f)))
}
VariantData_::Tuple(fields) => {
VariantData_::Tuple(fields.move_map(|f| fld.fold_struct_field(f)))
}
VariantData_::Unit => VariantData_::Unit
},
id: fld.new_id(id), id: fld.new_id(id),
kind: kind,
} }
}) })
} }
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
use util; use util;
use std::fmt; use std::fmt;
use std::{iter, option, slice};
use serialize::{Encodable, Encoder, Decoder}; use serialize::{Encodable, Encoder, Decoder};
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
...@@ -1160,21 +1161,42 @@ pub fn is_unnamed(&self) -> bool { ...@@ -1160,21 +1161,42 @@ pub fn is_unnamed(&self) -> bool {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum VariantKind { pub enum VariantData_ {
Struct, Struct(Vec<StructField>),
Tuple, Tuple(Vec<StructField>),
Unit, Unit,
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct VariantData { pub struct VariantData {
/// Fields, not including ctor pub data_: VariantData_,
pub fields: Vec<StructField>,
/// ID of the constructor. This is only used for tuple- or enum-like /// ID of the constructor. This is only used for tuple- or enum-like
/// structs. /// structs.
pub id: NodeId, pub id: NodeId,
pub kind: VariantKind, }
pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
slice::Iter<'a, StructField>,
fn(&Vec<StructField>) -> slice::Iter<StructField>>;
impl VariantData {
pub fn fields(&self) -> FieldIter {
fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
match self.data_ {
VariantData_::Struct(ref fields) | VariantData_::Tuple(ref fields) => Some(fields),
_ => None,
}.into_iter().flat_map(vec_iter)
}
pub fn is_struct(&self) -> bool {
if let VariantData_::Struct(..) = self.data_ { true } else { false }
}
pub fn is_tuple(&self) -> bool {
if let VariantData_::Tuple(..) = self.data_ { true } else { false }
}
pub fn is_unit(&self) -> bool {
if let VariantData_::Unit = self.data_ { true } else { false }
}
} }
/* /*
......
...@@ -500,12 +500,15 @@ pub fn lower_where_predicate(_lctx: &LoweringContext, ...@@ -500,12 +500,15 @@ pub fn lower_where_predicate(_lctx: &LoweringContext,
pub fn lower_struct_def(sd: &VariantData) -> P<hir::VariantData> { pub fn lower_struct_def(sd: &VariantData) -> P<hir::VariantData> {
P(hir::VariantData { P(hir::VariantData {
fields: sd.fields.iter().map(|f| lower_struct_field(_lctx, f)).collect(),
id: sd.id, id: sd.id,
kind: match sd.kind { data_: match sd.data_ {
VariantKind::Struct => hir::VariantKind::Struct, VariantData_::Struct(ref fields) => {
VariantKind::Tuple => hir::VariantKind::Tuple, hir::VariantData_::Struct(fields.iter().map(|f| lower_struct_field(_lctx, f)).collect())
VariantKind::Unit => hir::VariantKind::Unit, }
VariantData_::Tuple(ref fields) => {
hir::VariantData_::Tuple(fields.iter().map(|f| lower_struct_field(_lctx, f)).collect())
}
VariantData_::Unit => hir::VariantData_::Unit
} }
}) })
} }
......
...@@ -896,11 +896,11 @@ pub fn print_struct(&mut self, ...@@ -896,11 +896,11 @@ pub fn print_struct(&mut self,
-> io::Result<()> { -> io::Result<()> {
try!(self.print_name(name)); try!(self.print_name(name));
try!(self.print_generics(generics)); try!(self.print_generics(generics));
if struct_def.kind != hir::VariantKind::Struct { if !struct_def.is_struct() {
if struct_def.kind == hir::VariantKind::Tuple { if struct_def.is_tuple() {
try!(self.popen()); try!(self.popen());
try!(self.commasep(Inconsistent, try!(self.commasep_iter(Inconsistent,
&struct_def.fields, struct_def.fields(),
|s, field| { |s, field| {
match field.node.kind { match field.node.kind {
hir::NamedField(..) => panic!("unexpected named field"), hir::NamedField(..) => panic!("unexpected named field"),
...@@ -925,7 +925,7 @@ pub fn print_struct(&mut self, ...@@ -925,7 +925,7 @@ pub fn print_struct(&mut self,
try!(self.bopen()); try!(self.bopen());
try!(self.hardbreak_if_not_bol()); try!(self.hardbreak_if_not_bol());
for field in &struct_def.fields { for field in struct_def.fields() {
match field.node.kind { match field.node.kind {
hir::UnnamedField(..) => panic!("unexpected unnamed field"), hir::UnnamedField(..) => panic!("unexpected unnamed field"),
hir::NamedField(name, visibility) => { hir::NamedField(name, visibility) => {
......
...@@ -629,7 +629,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt ...@@ -629,7 +629,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
} }
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
walk_list!(visitor, visit_struct_field, &struct_definition.fields); walk_list!(visitor, visit_struct_field, struct_definition.fields());
} }
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
......
...@@ -282,7 +282,7 @@ fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { ...@@ -282,7 +282,7 @@ fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData, fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
_: ast::Name, _: &hir::Generics, _: ast::NodeId) { _: ast::Name, _: &hir::Generics, _: ast::NodeId) {
for sf in &s.fields { for sf in s.fields() {
if let hir::StructField_ { kind: hir::NamedField(name, _), .. } = sf.node { if let hir::StructField_ { kind: hir::NamedField(name, _), .. } = sf.node {
self.check_snake_case(cx, "structure field", &name.as_str(), self.check_snake_case(cx, "structure field", &name.as_str(),
Some(sf.span)); Some(sf.span));
......
...@@ -123,7 +123,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { ...@@ -123,7 +123,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
// If it's a struct, we also have to check the fields' types // If it's a struct, we also have to check the fields' types
match it.node { match it.node {
hir::ItemStruct(ref struct_def, _) => { hir::ItemStruct(ref struct_def, _) => {
for struct_field in &struct_def.fields { for struct_field in struct_def.fields() {
self.check_heap_type(cx, struct_field.span, self.check_heap_type(cx, struct_field.span,
cx.tcx.node_id_to_type(struct_field.node.id)); cx.tcx.node_id_to_type(struct_field.node.id));
} }
......
...@@ -132,13 +132,13 @@ fn visit_variant_data(&mut self, s: &hir::VariantData, _: ast::Name, ...@@ -132,13 +132,13 @@ fn visit_variant_data(&mut self, s: &hir::VariantData, _: ast::Name,
_: &'v hir::Generics, item_id: ast::NodeId, _: Span) { _: &'v hir::Generics, item_id: ast::NodeId, _: Span) {
// Struct constructors are parented to their struct definitions because // Struct constructors are parented to their struct definitions because
// they essentially are the struct definitions. // they essentially are the struct definitions.
if s.kind != hir::VariantKind::Struct { if !s.is_struct() {
self.parents.insert(s.id, item_id); self.parents.insert(s.id, item_id);
} }
// While we have the id of the struct definition, go ahead and parent // While we have the id of the struct definition, go ahead and parent
// all the fields. // all the fields.
for field in &s.fields { for field in s.fields() {
self.parents.insert(field.node.id, self.curparent); self.parents.insert(field.node.id, self.curparent);
} }
visit::walk_struct_def(self, s) visit::walk_struct_def(self, s)
...@@ -319,11 +319,11 @@ fn visit_item(&mut self, item: &hir::Item) { ...@@ -319,11 +319,11 @@ fn visit_item(&mut self, item: &hir::Item) {
// Struct constructors are public if the struct is all public. // Struct constructors are public if the struct is all public.
hir::ItemStruct(ref def, _) if public_first => { hir::ItemStruct(ref def, _) if public_first => {
if def.kind != hir::VariantKind::Struct { if !def.is_struct() {
self.exported_items.insert(def.id); self.exported_items.insert(def.id);
} }
// fields can be public or private, so lets check // fields can be public or private, so lets check
for field in &def.fields { for field in def.fields() {
let vis = match field.node.kind { let vis = match field.node.kind {
hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
}; };
...@@ -1089,7 +1089,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) { ...@@ -1089,7 +1089,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) {
} }
} }
let check_struct = |def: &hir::VariantData| { let check_struct = |def: &hir::VariantData| {
for f in &def.fields { for f in def.fields() {
match f.node.kind { match f.node.kind {
hir::NamedField(_, p) => check_inherited(tcx, f.span, p), hir::NamedField(_, p) => check_inherited(tcx, f.span, p),
hir::UnnamedField(..) => {} hir::UnnamedField(..) => {}
......
...@@ -492,9 +492,10 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> ...@@ -492,9 +492,10 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
// These items live in both the type and value namespaces. // These items live in both the type and value namespaces.
ItemStruct(ref struct_def, _) => { ItemStruct(ref struct_def, _) => {
// Adding to both Type and Value namespaces or just Type? // Adding to both Type and Value namespaces or just Type?
let (forbid, ctor_id) = match struct_def.kind { let (forbid, ctor_id) = if struct_def.is_struct() {
hir::VariantKind::Struct => (ForbidDuplicateTypesAndModules, None), (ForbidDuplicateTypesAndModules, None)
_ => (ForbidDuplicateTypesAndValues, Some(struct_def.id)), } else {
(ForbidDuplicateTypesAndValues, Some(struct_def.id))
}; };
let name_bindings = self.add_child(name, parent, forbid, sp); let name_bindings = self.add_child(name, parent, forbid, sp);
...@@ -513,7 +514,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> ...@@ -513,7 +514,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
} }
// Record the def ID and fields of this struct. // Record the def ID and fields of this struct.
let named_fields = struct_def.fields.iter().filter_map(|f| { let named_fields = struct_def.fields().filter_map(|f| {
match f.node.kind { match f.node.kind {
NamedField(name, _) => Some(name), NamedField(name, _) => Some(name),
UnnamedField(_) => None UnnamedField(_) => None
...@@ -587,14 +588,13 @@ fn build_reduced_graph_for_variant(&mut self, ...@@ -587,14 +588,13 @@ fn build_reduced_graph_for_variant(&mut self,
item_id: DefId, item_id: DefId,
parent: &Rc<Module>) { parent: &Rc<Module>) {
let name = variant.node.name; let name = variant.node.name;
let is_exported = match variant.node.data.kind { let is_exported = if variant.node.data.is_struct() {
hir::VariantKind::Struct => { // Not adding fields for variants as they are not accessed with a self receiver
// Not adding fields for variants as they are not accessed with a self receiver let variant_def_id = self.ast_map.local_def_id(variant.node.data.id);
let variant_def_id = self.ast_map.local_def_id(variant.node.data.id); self.structs.insert(variant_def_id, Vec::new());
self.structs.insert(variant_def_id, Vec::new()); true
true } else {
} false
_ => false,
}; };
let child = self.add_child(name, parent, let child = self.add_child(name, parent,
......
...@@ -473,7 +473,7 @@ fn process_struct(&mut self, ...@@ -473,7 +473,7 @@ fn process_struct(&mut self,
&val); &val);
// fields // fields
for field in &def.fields { for field in def.fields() {
self.process_struct_field_def(field, item.id); self.process_struct_field_def(field, item.id);
self.visit_ty(&field.node.ty); self.visit_ty(&field.node.ty);
} }
...@@ -510,7 +510,7 @@ fn process_enum(&mut self, ...@@ -510,7 +510,7 @@ fn process_enum(&mut self,
&val, &val,
enum_data.id); enum_data.id);
for field in &variant.node.data.fields { for field in variant.node.data.fields() {
self.process_struct_field_def(field, variant.node.data.id); self.process_struct_field_def(field, variant.node.data.id);
self.visit_ty(&*field.node.ty); self.visit_ty(&*field.node.ty);
} }
......
...@@ -2428,12 +2428,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { ...@@ -2428,12 +2428,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
hir_map::NodeVariant(ref v) => { hir_map::NodeVariant(ref v) => {
let llfn; let llfn;
let fields = if v.node.data.kind == hir::VariantKind::Struct { let fields = if v.node.data.is_struct() {
ccx.sess().bug("struct variant kind unexpected in get_item_val") ccx.sess().bug("struct variant kind unexpected in get_item_val")
} else { } else {
&v.node.data.fields v.node.data.fields()
}; };
assert!(!fields.is_empty()); assert!(fields.count() != 0);
let ty = ccx.tcx().node_id_to_type(id); let ty = ccx.tcx().node_id_to_type(id);
let parent = ccx.tcx().map.get_parent(id); let parent = ccx.tcx().map.get_parent(id);
let enm = ccx.tcx().map.expect_item(parent); let enm = ccx.tcx().map.expect_item(parent);
...@@ -2454,12 +2454,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { ...@@ -2454,12 +2454,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
hir_map::NodeStructCtor(struct_def) => { hir_map::NodeStructCtor(struct_def) => {
// Only register the constructor if this is a tuple-like struct. // Only register the constructor if this is a tuple-like struct.
let ctor_id = match struct_def.kind { let ctor_id = if struct_def.is_struct() {
hir::VariantKind::Struct => { ccx.sess().bug("attempt to register a constructor of \
ccx.sess().bug("attempt to register a constructor of \ a non-tuple-like struct")
a non-tuple-like struct") } else {
} struct_def.id
_ => struct_def.id,
}; };
let parent = ccx.tcx().map.get_parent(id); let parent = ccx.tcx().map.get_parent(id);
let struct_item = ccx.tcx().map.expect_item(parent); let struct_item = ccx.tcx().map.expect_item(parent);
......
...@@ -418,7 +418,7 @@ fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool { ...@@ -418,7 +418,7 @@ fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool {
match map_node { match map_node {
hir_map::NodeVariant(v) => { hir_map::NodeVariant(v) => {
v.node.data.kind == hir::VariantKind::Tuple v.node.data.is_tuple()
} }
hir_map::NodeStructCtor(_) => true, hir_map::NodeStructCtor(_) => true,
_ => false _ => false
......
...@@ -115,13 +115,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) ...@@ -115,13 +115,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
} }
} }
hir::ItemStruct(ref struct_def, _) => { hir::ItemStruct(ref struct_def, _) => {
match struct_def.kind { if struct_def.is_struct() {
hir::VariantKind::Struct => ccx.sess().bug("instantiate_inline: called on a \ ccx.sess().bug("instantiate_inline: called on a \
non-tuple struct"), non-tuple struct")
_ => { } else {
ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id)); ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id));
my_id = struct_def.id; my_id = struct_def.id;
}
} }
} }
_ => ccx.sess().bug("instantiate_inline: item has a \ _ => ccx.sess().bug("instantiate_inline: item has a \
......
...@@ -246,7 +246,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ...@@ -246,7 +246,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
hir_map::NodeStructCtor(struct_def) => { hir_map::NodeStructCtor(struct_def) => {
let d = mk_lldecl(abi::Rust); let d = mk_lldecl(abi::Rust);
attributes::inline(d, attributes::InlineAttr::Hint); attributes::inline(d, attributes::InlineAttr::Hint);
if struct_def.kind == hir::VariantKind::Struct { if struct_def.is_struct() {
panic!("ast-mapped struct didn't have a ctor id") panic!("ast-mapped struct didn't have a ctor id")
} }
base::trans_tuple_struct(ccx, base::trans_tuple_struct(ccx,
......
...@@ -627,8 +627,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ...@@ -627,8 +627,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
struct_def: &hir::VariantData) struct_def: &hir::VariantData)
-> AdtVariant<'tcx> { -> AdtVariant<'tcx> {
let fields = let fields =
struct_def.fields struct_def.fields()
.iter()
.map(|field| { .map(|field| {
let field_ty = fcx.tcx().node_id_to_type(field.node.id); let field_ty = fcx.tcx().node_id_to_type(field.node.id);
let field_ty = fcx.instantiate_type_scheme(field.span, let field_ty = fcx.instantiate_type_scheme(field.span,
......
...@@ -524,8 +524,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ...@@ -524,8 +524,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
struct_def: &hir::VariantData) struct_def: &hir::VariantData)
-> AdtVariant<'tcx> { -> AdtVariant<'tcx> {
let fields = let fields =
struct_def.fields struct_def.fields()
.iter()
.map(|field| { .map(|field| {
let field_ty = fcx.tcx().node_id_to_type(field.node.id); let field_ty = fcx.tcx().node_id_to_type(field.node.id);
let field_ty = fcx.instantiate_type_scheme(field.span, let field_ty = fcx.instantiate_type_scheme(field.span,
......
...@@ -1010,11 +1010,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { ...@@ -1010,11 +1010,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
let it_def_id = ccx.tcx.map.local_def_id(it.id); let it_def_id = ccx.tcx.map.local_def_id(it.id);
let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant(); let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) { for (f, ty_f) in struct_def.fields().zip(variant.fields.iter()) {
convert_field(ccx, &scheme.generics, &predicates, f, ty_f) convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
} }
if struct_def.kind != hir::VariantKind::Struct { if !struct_def.is_struct() {
convert_variant_ctor(tcx, struct_def.id, variant, scheme, predicates); convert_variant_ctor(tcx, struct_def.id, variant, scheme, predicates);
} }
}, },
...@@ -1067,7 +1067,7 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ...@@ -1067,7 +1067,7 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
variants: &[P<hir::Variant>]) { variants: &[P<hir::Variant>]) {
// fill the field types // fill the field types
for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) { for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
for (f, ty_f) in variant.node.data.fields.iter().zip(ty_variant.fields.iter()) { for (f, ty_f) in variant.node.data.fields().zip(ty_variant.fields.iter()) {
convert_field(ccx, &scheme.generics, &predicates, f, ty_f) convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
} }
...@@ -1089,7 +1089,7 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>, ...@@ -1089,7 +1089,7 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
disr_val: ty::Disr, disr_val: ty::Disr,
def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> { def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap(); let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
let fields = def.fields.iter().map(|f| { let fields = def.fields().map(|f| {
let fid = tcx.map.local_def_id(f.node.id); let fid = tcx.map.local_def_id(f.node.id);
match f.node.kind { match f.node.kind {
hir::NamedField(name, vis) => { hir::NamedField(name, vis) => {
...@@ -1125,7 +1125,7 @@ fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>, ...@@ -1125,7 +1125,7 @@ fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
{ {
let did = tcx.map.local_def_id(it.id); let did = tcx.map.local_def_id(it.id);
let ctor_id = if def.kind != hir::VariantKind::Struct { let ctor_id = if !def.is_struct() {
tcx.map.local_def_id(def.id) tcx.map.local_def_id(def.id)
} else { } else {
did did
......
...@@ -1809,7 +1809,7 @@ impl Clean<VariantStruct> for ::rustc_front::hir::VariantData { ...@@ -1809,7 +1809,7 @@ impl Clean<VariantStruct> for ::rustc_front::hir::VariantData {
fn clean(&self, cx: &DocContext) -> VariantStruct { fn clean(&self, cx: &DocContext) -> VariantStruct {
VariantStruct { VariantStruct {
struct_type: doctree::struct_type_from_def(self), struct_type: doctree::struct_type_from_def(self),
fields: self.fields.clean(cx), fields: self.fields().map(|x| x.clean(cx)).collect(),
fields_stripped: false, fields_stripped: false,
} }
} }
...@@ -1918,12 +1918,12 @@ pub enum VariantKind { ...@@ -1918,12 +1918,12 @@ pub enum VariantKind {
} }
fn struct_def_to_variant_kind(struct_def: &hir::VariantData, cx: &DocContext) -> VariantKind { fn struct_def_to_variant_kind(struct_def: &hir::VariantData, cx: &DocContext) -> VariantKind {
if struct_def.kind == hir::VariantKind::Struct { if struct_def.is_struct() {
StructVariant(struct_def.clean(cx)) StructVariant(struct_def.clean(cx))
} else if struct_def.kind == hir::VariantKind::Unit { } else if struct_def.is_unit() {
CLikeVariant CLikeVariant
} else { } else {
TupleVariant(struct_def.fields.iter().map(|x| x.node.ty.clean(cx)).collect()) TupleVariant(struct_def.fields().map(|x| x.node.ty.clean(cx)).collect())
} }
} }
......
...@@ -234,9 +234,9 @@ pub struct Import { ...@@ -234,9 +234,9 @@ pub struct Import {
} }
pub fn struct_type_from_def(sd: &hir::VariantData) -> StructType { pub fn struct_type_from_def(sd: &hir::VariantData) -> StructType {
if sd.kind != hir::VariantKind::Struct { if !sd.is_struct() {
// We are in a tuple-struct // We are in a tuple-struct
match sd.fields.len() { match sd.fields().count() {
0 => Unit, 0 => Unit,
1 => Newtype, 1 => Newtype,
_ => Tuple _ => Tuple
......
...@@ -97,7 +97,7 @@ pub fn visit_variant_data(&mut self, item: &hir::Item, ...@@ -97,7 +97,7 @@ pub fn visit_variant_data(&mut self, item: &hir::Item,
stab: self.stability(item.id), stab: self.stability(item.id),
attrs: item.attrs.clone(), attrs: item.attrs.clone(),
generics: generics.clone(), generics: generics.clone(),
fields: sd.fields.clone(), fields: sd.fields().cloned().collect(),
whence: item.span whence: item.span
} }
} }
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
use std::rc::Rc; use std::rc::Rc;
use std::borrow::Cow; use std::borrow::Cow;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::{iter, option, slice};
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
/// A name is a part of an identifier, representing a string or gensym. It's /// A name is a part of an identifier, representing a string or gensym. It's
...@@ -1740,21 +1741,42 @@ pub fn is_unnamed(&self) -> bool { ...@@ -1740,21 +1741,42 @@ pub fn is_unnamed(&self) -> bool {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum VariantKind { pub enum VariantData_ {
Struct, Struct(Vec<StructField>),
Tuple, Tuple(Vec<StructField>),
Unit, Unit,
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct VariantData { pub struct VariantData {
/// Fields, not including ctor pub data_: VariantData_,
pub fields: Vec<StructField>,
/// ID of the constructor. This is only used for tuple- or enum-like /// ID of the constructor. This is only used for tuple- or enum-like
/// structs. /// structs.
pub id: NodeId, pub id: NodeId,
pub kind: VariantKind, }
pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
slice::Iter<'a, StructField>,
fn(&Vec<StructField>) -> slice::Iter<StructField>>;
impl VariantData {
pub fn fields(&self) -> FieldIter {
fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
match self.data_ {
VariantData_::Struct(ref fields) | VariantData_::Tuple(ref fields) => Some(fields),
_ => None,
}.into_iter().flat_map(vec_iter)
}
pub fn is_struct(&self) -> bool {
if let VariantData_::Struct(..) = self.data_ { true } else { false }
}
pub fn is_tuple(&self) -> bool {
if let VariantData_::Tuple(..) = self.data_ { true } else { false }
}
pub fn is_unit(&self) -> bool {
if let VariantData_::Unit = self.data_ { true } else { false }
}
} }
/* /*
......
...@@ -167,13 +167,22 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ ...@@ -167,13 +167,22 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::VariantData>) -> P<ast::VariantData> where fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::VariantData>) -> P<ast::VariantData> where
F: FnMut(&[ast::Attribute]) -> bool F: FnMut(&[ast::Attribute]) -> bool
{ {
def.map(|ast::VariantData { fields, id, kind }| { def.map(|ast::VariantData { data_, id }| {
ast::VariantData { ast::VariantData {
fields: fields.into_iter().filter(|m| { data_: match data_ {
(cx.in_cfg)(&m.node.attrs) ast::VariantData_::Struct(fields) => {
}).collect(), ast::VariantData_::Struct(fields.into_iter().filter(|m| {
(cx.in_cfg)(&m.node.attrs)
}).collect())
}
ast::VariantData_::Tuple(fields) => {
ast::VariantData_::Tuple(fields.into_iter().filter(|m| {
(cx.in_cfg)(&m.node.attrs)
}).collect())
}
ast::VariantData_::Unit => ast::VariantData_::Unit
},
id: id, id: id,
kind: kind,
} }
}) })
} }
......
...@@ -1002,15 +1002,18 @@ fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Varian ...@@ -1002,15 +1002,18 @@ fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Varian
}} }}
}).collect(); }).collect();
let kind = if fields.is_empty() { ast::VariantKind::Unit } else { ast::VariantKind::Tuple }; let data_ = if fields.is_empty() {
ast::VariantData_::Unit
} else {
ast::VariantData_::Tuple(fields)
};
respan(span, respan(span,
ast::Variant_ { ast::Variant_ {
name: name, name: name,
attrs: Vec::new(), attrs: Vec::new(),
data: P(ast::VariantData { fields: fields, data: P(ast::VariantData { data_: data_,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID}),
kind: kind }),
disr_expr: None, disr_expr: None,
}) })
} }
......
...@@ -652,7 +652,7 @@ fn expand_struct_def(&self, ...@@ -652,7 +652,7 @@ fn expand_struct_def(&self,
struct_def: &'a VariantData, struct_def: &'a VariantData,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> P<ast::Item> { generics: &Generics) -> P<ast::Item> {
let field_tys: Vec<P<ast::Ty>> = struct_def.fields.iter() let field_tys: Vec<P<ast::Ty>> = struct_def.fields()
.map(|field| field.node.ty.clone()) .map(|field| field.node.ty.clone())
.collect(); .collect();
...@@ -700,7 +700,7 @@ fn expand_enum_def(&self, ...@@ -700,7 +700,7 @@ fn expand_enum_def(&self,
let mut field_tys = Vec::new(); let mut field_tys = Vec::new();
for variant in &enum_def.variants { for variant in &enum_def.variants {
field_tys.extend(variant.node.data.fields.iter() field_tys.extend(variant.node.data.fields()
.map(|field| field.node.ty.clone())); .map(|field| field.node.ty.clone()));
} }
...@@ -1444,7 +1444,7 @@ fn summarise_struct(&self, ...@@ -1444,7 +1444,7 @@ fn summarise_struct(&self,
struct_def: &VariantData) -> StaticFields { struct_def: &VariantData) -> StaticFields {
let mut named_idents = Vec::new(); let mut named_idents = Vec::new();
let mut just_spans = Vec::new(); let mut just_spans = Vec::new();
for field in struct_def.fields.iter(){ for field in struct_def.fields(){
let sp = self.set_expn_info(cx, field.span); let sp = self.set_expn_info(cx, field.span);
match field.node.kind { match field.node.kind {
ast::NamedField(ident, _) => named_idents.push((ident, sp)), ast::NamedField(ident, _) => named_idents.push((ident, sp)),
...@@ -1483,7 +1483,7 @@ fn create_struct_pattern(&self, ...@@ -1483,7 +1483,7 @@ fn create_struct_pattern(&self,
-> (P<ast::Pat>, Vec<(Span, Option<Ident>, -> (P<ast::Pat>, Vec<(Span, Option<Ident>,
P<Expr>, P<Expr>,
&'a [ast::Attribute])>) { &'a [ast::Attribute])>) {
if struct_def.fields.is_empty() { if struct_def.fields().count() == 0 {
return (cx.pat_enum(self.span, struct_path, vec![]), vec![]); return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
} }
...@@ -1491,7 +1491,7 @@ fn create_struct_pattern(&self, ...@@ -1491,7 +1491,7 @@ fn create_struct_pattern(&self,
let mut ident_expr = Vec::new(); let mut ident_expr = Vec::new();
let mut struct_type = Unknown; let mut struct_type = Unknown;
for (i, struct_field) in struct_def.fields.iter().enumerate() { for (i, struct_field) in struct_def.fields().enumerate() {
let sp = self.set_expn_info(cx, struct_field.span); let sp = self.set_expn_info(cx, struct_field.span);
let opt_id = match struct_field.node.kind { let opt_id = match struct_field.node.kind {
ast::NamedField(ident, _) if (struct_type == Unknown || ast::NamedField(ident, _) if (struct_type == Unknown ||
......
...@@ -95,7 +95,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure ...@@ -95,7 +95,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
for variant in &enum_def.variants { for variant in &enum_def.variants {
let def = &variant.node.data; let def = &variant.node.data;
if def.kind != ast::VariantKind::Unit { if !def.is_unit() {
cx.span_err(trait_span, "`FromPrimitive` cannot be derived \ cx.span_err(trait_span, "`FromPrimitive` cannot be derived \
for enums with non-unit variants"); for enums with non-unit variants");
return cx.expr_fail(trait_span, return cx.expr_fail(trait_span,
......
...@@ -859,11 +859,11 @@ fn visit_item(&mut self, i: &ast::Item) { ...@@ -859,11 +859,11 @@ fn visit_item(&mut self, i: &ast::Item) {
fn visit_variant_data(&mut self, s: &'v ast::VariantData, _: ast::Ident, fn visit_variant_data(&mut self, s: &'v ast::VariantData, _: ast::Ident,
_: &'v ast::Generics, _: ast::NodeId, span: Span) { _: &'v ast::Generics, _: ast::NodeId, span: Span) {
if s.fields.is_empty() { if s.fields().count() == 0 {
if s.kind == ast::VariantKind::Struct { if s.is_struct() {
self.gate_feature("braced_empty_structs", span, self.gate_feature("braced_empty_structs", span,
"empty structs and enum variants with braces are unstable"); "empty structs and enum variants with braces are unstable");
} else if s.kind == ast::VariantKind::Tuple { } else if s.is_tuple() {
self.context.span_handler.span_err(span, "empty tuple structs and enum variants \ self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
are not allowed, use unit structs and \ are not allowed, use unit structs and \
enum variants instead"); enum variants instead");
......
...@@ -815,10 +815,17 @@ pub fn noop_fold_where_predicate<T: Folder>( ...@@ -815,10 +815,17 @@ pub fn noop_fold_where_predicate<T: Folder>(
} }
pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> { pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
struct_def.map(|VariantData { fields, id, kind }| VariantData { struct_def.map(|VariantData { data_, id }| VariantData {
fields: fields.move_map(|f| fld.fold_struct_field(f)), data_: match data_ {
ast::VariantData_::Struct(fields) => {
ast::VariantData_::Struct(fields.move_map(|f| fld.fold_struct_field(f)))
}
ast::VariantData_::Tuple(fields) => {
ast::VariantData_::Tuple(fields.move_map(|f| fld.fold_struct_field(f)))
}
ast::VariantData_::Unit => ast::VariantData_::Unit
},
id: fld.new_id(id), id: fld.new_id(id),
kind: kind,
}) })
} }
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
use ast::PatWildSingle; use ast::PatWildSingle;
use ast::{PolyTraitRef, QSelf}; use ast::{PolyTraitRef, QSelf};
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField, VariantKind}; use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField, VariantData_};
use ast::{BiSub, StrStyle}; use ast::{BiSub, StrStyle};
use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
...@@ -4640,26 +4640,24 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> { ...@@ -4640,26 +4640,24 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
// Otherwise if we look ahead and see a paren we parse a tuple-style // Otherwise if we look ahead and see a paren we parse a tuple-style
// struct. // struct.
let (fields, kind) = if self.token.is_keyword(keywords::Where) { let data_ = if self.token.is_keyword(keywords::Where) {
generics.where_clause = try!(self.parse_where_clause()); generics.where_clause = try!(self.parse_where_clause());
if try!(self.eat(&token::Semi)) { if try!(self.eat(&token::Semi)) {
// If we see a: `struct Foo<T> where T: Copy;` style decl. // If we see a: `struct Foo<T> where T: Copy;` style decl.
(Vec::new(), VariantKind::Unit) VariantData_::Unit
} else { } else {
// If we see: `struct Foo<T> where T: Copy { ... }` // If we see: `struct Foo<T> where T: Copy { ... }`
(try!(self.parse_record_struct_body()), VariantKind::Struct) VariantData_::Struct(try!(self.parse_record_struct_body()))
} }
// No `where` so: `struct Foo<T>;` // No `where` so: `struct Foo<T>;`
} else if try!(self.eat(&token::Semi) ){ } else if try!(self.eat(&token::Semi) ){
(Vec::new(), VariantKind::Unit) VariantData_::Unit
// Record-style struct definition // Record-style struct definition
} else if self.token == token::OpenDelim(token::Brace) { } else if self.token == token::OpenDelim(token::Brace) {
let fields = try!(self.parse_record_struct_body()); VariantData_::Struct(try!(self.parse_record_struct_body()))
(fields, VariantKind::Struct)
// Tuple-style struct definition with optional where-clause. // Tuple-style struct definition with optional where-clause.
} else if self.token == token::OpenDelim(token::Paren) { } else if self.token == token::OpenDelim(token::Paren) {
let fields = try!(self.parse_tuple_struct_body(&mut generics)); VariantData_::Tuple(try!(self.parse_tuple_struct_body(&mut generics)))
(fields, VariantKind::Tuple)
} else { } else {
let token_str = self.this_token_to_string(); let token_str = self.this_token_to_string();
return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \ return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \
...@@ -4668,9 +4666,8 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> { ...@@ -4668,9 +4666,8 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
Ok((class_name, Ok((class_name,
ItemStruct(P(ast::VariantData { ItemStruct(P(ast::VariantData {
fields: fields, data_: data_,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: kind,
}), generics), }), generics),
None)) None))
} }
...@@ -5111,9 +5108,8 @@ fn parse_struct_def(&mut self) -> PResult<P<VariantData>> { ...@@ -5111,9 +5108,8 @@ fn parse_struct_def(&mut self) -> PResult<P<VariantData>> {
try!(self.bump()); try!(self.bump());
Ok(P(VariantData { Ok(P(VariantData {
fields: fields, data_: VariantData_::Struct(fields),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: VariantKind::Struct,
})) }))
} }
...@@ -5150,19 +5146,16 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> { ...@@ -5150,19 +5146,16 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
}}); }});
} }
struct_def = P(VariantData { fields: fields, struct_def = P(VariantData { data_: ast::VariantData_::Tuple(fields),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID});
kind: ast::VariantKind::Tuple });
} else if try!(self.eat(&token::Eq) ){ } else if try!(self.eat(&token::Eq) ){
disr_expr = Some(try!(self.parse_expr_nopanic())); disr_expr = Some(try!(self.parse_expr_nopanic()));
any_disr = disr_expr.as_ref().map(|expr| expr.span); any_disr = disr_expr.as_ref().map(|expr| expr.span);
struct_def = P(VariantData { fields: Vec::new(), struct_def = P(VariantData { data_: ast::VariantData_::Unit,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID});
kind: ast::VariantKind::Unit });
} else { } else {
struct_def = P(VariantData { fields: Vec::new(), struct_def = P(VariantData { data_: ast::VariantData_::Unit,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID});
kind: ast::VariantKind::Unit });
} }
let vr = ast::Variant_ { let vr = ast::Variant_ {
......
...@@ -520,6 +520,18 @@ fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> ...@@ -520,6 +520,18 @@ fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()>
self.end() self.end()
} }
fn commasep_iter<'it, T: 'it, F, I>(&mut self, b: Breaks, elts: I, mut op: F) -> io::Result<()>
where F: FnMut(&mut Self, &T) -> io::Result<()>,
I: Iterator<Item=&'it T>,
{
try!(self.rbox(0, b));
let mut first = true;
for elt in elts {
if first { first = false; } else { try!(self.word_space(",")); }
try!(op(self, elt));
}
self.end()
}
fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> { fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
let mut cur_lit = self.cur_cmnt_and_lit().cur_lit; let mut cur_lit = self.cur_cmnt_and_lit().cur_lit;
...@@ -1392,11 +1404,11 @@ pub fn print_struct(&mut self, ...@@ -1392,11 +1404,11 @@ pub fn print_struct(&mut self,
print_finalizer: bool) -> io::Result<()> { print_finalizer: bool) -> io::Result<()> {
try!(self.print_ident(ident)); try!(self.print_ident(ident));
try!(self.print_generics(generics)); try!(self.print_generics(generics));
if struct_def.kind != ast::VariantKind::Struct { if !struct_def.is_struct() {
if struct_def.kind == ast::VariantKind::Tuple { if struct_def.is_tuple() {
try!(self.popen()); try!(self.popen());
try!(self.commasep( try!(self.commasep_iter(
Inconsistent, &struct_def.fields, Inconsistent, struct_def.fields(),
|s, field| { |s, field| {
match field.node.kind { match field.node.kind {
ast::NamedField(..) => panic!("unexpected named field"), ast::NamedField(..) => panic!("unexpected named field"),
...@@ -1422,7 +1434,7 @@ pub fn print_struct(&mut self, ...@@ -1422,7 +1434,7 @@ pub fn print_struct(&mut self,
try!(self.bopen()); try!(self.bopen());
try!(self.hardbreak_if_not_bol()); try!(self.hardbreak_if_not_bol());
for field in &struct_def.fields { for field in struct_def.fields() {
match field.node.kind { match field.node.kind {
ast::UnnamedField(..) => panic!("unexpected unnamed field"), ast::UnnamedField(..) => panic!("unexpected unnamed field"),
ast::NamedField(ident, visibility) => { ast::NamedField(ident, visibility) => {
...@@ -3119,9 +3131,8 @@ fn test_variant_to_string() { ...@@ -3119,9 +3131,8 @@ fn test_variant_to_string() {
name: ident, name: ident,
attrs: Vec::new(), attrs: Vec::new(),
// making this up as I go.... ? // making this up as I go.... ?
data: P(ast::VariantData { fields: Vec::new(), data: P(ast::VariantData { data_: ast::VariantData_::Unit,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID}),
kind: ast::VariantKind::Unit }),
disr_expr: None, disr_expr: None,
}); });
......
...@@ -604,7 +604,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt ...@@ -604,7 +604,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
struct_definition: &'v VariantData) { struct_definition: &'v VariantData) {
walk_list!(visitor, visit_struct_field, &struct_definition.fields); walk_list!(visitor, visit_struct_field, struct_definition.fields());
} }
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册