Merge struct fields and struct kind
This commit is contained in:
parent
30af54dede
commit
40aa09e4c9
36 changed files with 222 additions and 148 deletions
|
@ -138,7 +138,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||||
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 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||||
}
|
}
|
||||||
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 @@ impl<'ast> Map<'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
||||||
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>,
|
||||||
// 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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||||
_: &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,
|
||||||
|
|
||||||
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
|
||||||
|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) -
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ use print::pprust;
|
||||||
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 @@ impl StructFieldKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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,
|
||||||
|
|
||||||
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 @@ impl<'a> State<'a> {
|
||||||
-> 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 @@ impl<'a> State<'a> {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ impl LateLintPass for NonSnakeCase {
|
||||||
|
|
||||||
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 @@ impl LateLintPass for BoxPointers {
|
||||||
// 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 @@ impl<'v> Visitor<'v> for ParentVisitor {
|
||||||
_: &'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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
// 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 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
// 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 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
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 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
&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 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
&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 {
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
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 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
||||||
|
|
||||||
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,15 +115,14 @@ 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 \
|
||||||
non-enum, non-struct parent")
|
non-enum, non-struct parent")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
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>,
|
||||||
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) {
|
||||||
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>,
|
||||||
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>,
|
||||||
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>,
|
||||||
{
|
{
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
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 @@ use std::fmt;
|
||||||
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 @@ impl StructFieldKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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_
|
||||||
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_ {
|
||||||
|
ast::VariantData_::Struct(fields) => {
|
||||||
|
ast::VariantData_::Struct(fields.into_iter().filter(|m| {
|
||||||
(cx.in_cfg)(&m.node.attrs)
|
(cx.in_cfg)(&m.node.attrs)
|
||||||
}).collect(),
|
}).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 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
}}
|
}}
|
||||||
}).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 @@ impl<'a> TraitDef<'a> {
|
||||||
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 @@ impl<'a> TraitDef<'a> {
|
||||||
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 @@ impl<'a> TraitDef<'a> {
|
||||||
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 @@ impl<'a> TraitDef<'a> {
|
||||||
-> (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 @@ impl<'a> TraitDef<'a> {
|
||||||
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
|
||||||
|
|
||||||
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
|
||||||
|
|
||||||
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>(
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild, PatWildMulti};
|
||||||
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 @@ impl<'a> Parser<'a> {
|
||||||
// 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 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
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 @@ impl<'a> Parser<'a> {
|
||||||
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 @@ impl<'a> Parser<'a> {
|
||||||
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 @@ pub trait PrintState<'a> {
|
||||||
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 @@ impl<'a> State<'a> {
|
||||||
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 @@ impl<'a> State<'a> {
|
||||||
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 @@ mod tests {
|
||||||
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
|
||||||
|
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue