提交 8b026a6e 编写于 作者: V Vadim Petrochenkov

Use numeric field `Name`s ("0", "1" etc) for positional fields

上级 8b60b948
......@@ -83,7 +83,7 @@ pub enum DefPathData {
TypeParam(ast::Name),
LifetimeDef(ast::Name),
EnumVariant(ast::Name),
Field(Option<ast::Name>),
Field(ast::Name),
StructCtor, // implicit ctor for a tuple-like struct
Initializer, // initializer for a const
Binding(ast::Name), // pattern binding
......@@ -185,14 +185,10 @@ pub fn as_interned_str(&self) -> InternedString {
EnumVariant(name) |
DetachedCrate(name) |
Binding(name) |
Field(Some(name)) => {
Field(name) => {
name.as_str()
}
Field(None) => {
InternedString::new("{{field}}")
}
// note that this does not show up in user printouts
CrateRoot => {
InternedString::new("{{root}}")
......
......@@ -429,13 +429,12 @@ fn should_warn_about_item(&mut self, item: &hir::Item) -> bool {
}
fn should_warn_about_field(&mut self, node: &hir::StructField_) -> bool {
let is_named = node.name.is_some();
let field_type = self.tcx.node_id_to_type(node.id);
let is_marker_field = match field_type.ty_to_def_id() {
Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
_ => false
};
is_named
!node.is_positional()
&& !self.symbol_is_live(node.id, None)
&& !is_marker_field
&& !has_allow_dead_code_or_lang_attr(&node.attrs)
......@@ -546,7 +545,7 @@ fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
fn visit_struct_field(&mut self, field: &hir::StructField) {
if self.should_warn_about_field(&field.node) {
self.warn_dead_code(field.node.id, field.span,
field.node.name.unwrap(), "struct field");
field.node.name, "struct field");
}
intravisit::walk_struct_field(self, field);
......
......@@ -1371,8 +1371,6 @@ pub struct FieldDefData<'tcx, 'container: 'tcx> {
/// The field's DefId. NOTE: the fields of tuple-like enum variants
/// are not real items, and don't have entries in tcache etc.
pub did: DefId,
/// special_idents::unnamed_field.name
/// if this is a tuple-like field
pub name: Name,
pub vis: hir::Visibility,
/// TyIVar is used here to allow for variance (see the doc at
......
......@@ -1242,45 +1242,22 @@ pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct StructField_ {
pub name: Option<Name>,
pub name: Name,
pub vis: Visibility,
pub id: NodeId,
pub ty: P<Ty>,
pub attrs: HirVec<Attribute>,
}
// impl StructField_ {
// pub fn name(&self) -> Option<Name> {
// match self.kind {
// NamedField(name, _) => Some(name),
// UnnamedField(_) => None,
// }
// }
// }
pub type StructField = Spanned<StructField_>;
// #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
// pub enum StructFieldKind {
// NamedField(Name, Visibility),
// /// Element of a tuple-like struct
// UnnamedField(Visibility),
// }
// impl StructFieldKind {
// pub fn is_unnamed(&self) -> bool {
// match *self {
// UnnamedField(..) => true,
// NamedField(..) => false,
// }
// }
// pub fn visibility(&self) -> Visibility {
// match *self {
// NamedField(_, vis) | UnnamedField(vis) => vis,
// }
// }
// }
impl StructField_ {
// Still necessary in couple of places
pub fn is_positional(&self) -> bool {
let first = self.name.as_str().as_bytes()[0];
first >= b'0' && first <= b'9'
}
}
/// Fields and Ids of enum variants and structs
///
......
......@@ -669,7 +669,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &
}
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
walk_opt_name(visitor, struct_field.span, struct_field.node.name);
visitor.visit_name(struct_field.span, struct_field.node.name);
visitor.visit_ty(&struct_field.node.ty);
walk_list!(visitor, visit_attribute, &struct_field.node.attrs);
}
......
......@@ -578,12 +578,14 @@ pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::V
match *vdata {
VariantData::Struct(ref fields, id) => {
hir::VariantData::Struct(fields.iter()
.enumerate()
.map(|f| lower_struct_field(lctx, f))
.collect(),
id)
}
VariantData::Tuple(ref fields, id) => {
hir::VariantData::Tuple(fields.iter()
.enumerate()
.map(|f| lower_struct_field(lctx, f))
.collect(),
id)
......@@ -607,11 +609,14 @@ pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::Po
}
}
pub fn lower_struct_field(lctx: &LoweringContext, f: &StructField) -> hir::StructField {
pub fn lower_struct_field(lctx: &LoweringContext,
(index, f): (usize, &StructField))
-> hir::StructField {
Spanned {
node: hir::StructField_ {
id: f.node.id,
name: f.node.ident().map(|ident| ident.name),
name: f.node.ident().map(|ident| ident.name)
.unwrap_or(token::intern(&index.to_string())),
vis: lower_visibility(lctx, f.node.kind.visibility()),
ty: lower_ty(lctx, &f.node.ty),
attrs: lower_attrs(lctx, &f.node.attrs),
......
......@@ -938,7 +938,7 @@ pub fn print_struct(&mut self,
try!(self.maybe_print_comment(field.span.lo));
try!(self.print_outer_attributes(&field.node.attrs));
try!(self.print_visibility(field.node.vis));
try!(self.print_name(field.node.name.unwrap()));
try!(self.print_name(field.node.name));
try!(self.word_nbsp(":"));
try!(self.print_type(&field.node.ty));
try!(word(&mut self.s, ","));
......
......@@ -283,10 +283,7 @@ fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
_: ast::Name, _: &hir::Generics, _: ast::NodeId) {
for sf in s.fields() {
if let Some(name) = sf.node.name {
self.check_snake_case(cx, "structure field", &name.as_str(),
Some(sf.span));
}
self.check_snake_case(cx, "structure field", &sf.node.name.as_str(), Some(sf.span));
}
}
}
......
......@@ -428,7 +428,7 @@ fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) {
}
fn check_struct_field(&mut self, cx: &LateContext, sf: &hir::StructField) {
if sf.node.name.is_some() {
if !sf.node.is_positional() {
if sf.node.vis == hir::Public || self.in_variant {
let cur_struct_def = *self.struct_def_stack.last()
.expect("empty struct_def_stack");
......
......@@ -48,8 +48,7 @@
use rbml;
use serialize::Decodable;
use syntax::attr;
use syntax::parse::token::{IdentInterner, special_idents};
use syntax::parse::token;
use syntax::parse::token::{self, IdentInterner};
use syntax::ast;
use syntax::abi::Abi;
use syntax::codemap::{self, Span, BytePos, NO_EXPANSION};
......@@ -406,6 +405,7 @@ fn get_variant_fields<'tcx>(intr: &IdentInterner,
cdata: Cmd,
doc: rbml::Doc,
tcx: &ty::ctxt<'tcx>) -> Vec<ty::FieldDefData<'tcx, 'tcx>> {
let mut index = 0;
reader::tagged_docs(doc, tag_item_field).map(|f| {
let ff = item_family(f);
match ff {
......@@ -417,8 +417,9 @@ fn get_variant_fields<'tcx>(intr: &IdentInterner,
struct_field_family_to_visibility(ff))
}).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| {
let ff = item_family(f);
ty::FieldDefData::new(item_def_id(f, cdata),
special_idents::unnamed_field.name,
let name = intr.intern(&index.to_string());
index += 1;
ty::FieldDefData::new(item_def_id(f, cdata), name,
struct_field_family_to_visibility(ff))
})).collect()
}
......@@ -1153,10 +1154,13 @@ fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex)
-> Vec<ast::Name> {
let item = cdata.lookup_item(id);
let mut index = 0;
reader::tagged_docs(item, tag_item_field).map(|an_item| {
item_name(intr, an_item)
}).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| {
special_idents::unnamed_field.name
let name = intr.intern(&index.to_string());
index += 1;
name
})).collect()
}
......
......@@ -46,7 +46,6 @@
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::errors::Handler;
use syntax::parse::token::special_idents;
use syntax;
use rbml::writer::Encoder;
......@@ -249,7 +248,7 @@ fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
fn encode_struct_fields(rbml_w: &mut Encoder,
variant: ty::VariantDef) {
for f in &variant.fields {
if f.name == special_idents::unnamed_field.name {
if variant.is_tuple_struct() {
rbml_w.start_tag(tag_item_unnamed_field);
} else {
rbml_w.start_tag(tag_item_field);
......
......@@ -380,12 +380,12 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: Module<'b>) -> M
}
// Record the def ID and fields of this struct.
let named_fields = struct_def.fields()
.iter()
.filter_map(|f| f.node.name)
.collect();
let field_names = struct_def.fields()
.iter()
.map(|f| f.node.name)
.collect();
let item_def_id = self.ast_map.local_def_id(item.id);
self.structs.insert(item_def_id, named_fields);
self.structs.insert(item_def_id, field_names);
parent
}
......
......@@ -21,7 +21,6 @@
use syntax::ast;
use syntax::codemap::{self, Span};
use syntax::parse::token::special_idents;
/// check_drop_impl confirms that the Drop implementation identfied by
/// `drop_impl_did` is not any more specialized than the type it is
......@@ -299,7 +298,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
// no need for an additional note if the overflow
// was somehow on the root.
}
TypeContext::ADT { def_id, variant, field, field_index } => {
TypeContext::ADT { def_id, variant, field } => {
let adt = tcx.lookup_adt_def(def_id);
let variant_name = match adt.adt_kind() {
ty::AdtKind::Enum => format!("enum {} variant {}",
......@@ -308,17 +307,12 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
ty::AdtKind::Struct => format!("struct {}",
tcx.item_path_str(def_id))
};
let field_name = if field == special_idents::unnamed_field.name {
format!("#{}", field_index)
} else {
format!("`{}`", field)
};
span_note!(
&mut err,
span,
"overflowed on {} field {} type: {}",
variant_name,
field_name,
field,
detected_on_typ);
}
}
......@@ -338,7 +332,6 @@ enum TypeContext {
def_id: DefId,
variant: ast::Name,
field: ast::Name,
field_index: usize
}
}
......@@ -452,7 +445,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
let did = def.did;
for variant in &def.variants {
for (i, field) in variant.fields.iter().enumerate() {
for field in variant.fields.iter() {
let fty = field.ty(tcx, substs);
let fty = cx.rcx.fcx.resolve_type_vars_if_possible(
cx.rcx.fcx.normalize_associated_types_in(cx.span, &fty));
......@@ -462,7 +455,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
def_id: did,
field: field.name,
variant: variant.name,
field_index: i
},
fty,
depth+1))
......
......@@ -36,7 +36,6 @@
use std::cell::RefCell;
use std::rc::Rc;
use syntax::codemap::Span;
use syntax::parse::token;
use util::nodemap::{DefIdMap, FnvHashMap};
use rustc::dep_graph::DepNode;
use rustc::front::map as hir_map;
......@@ -449,13 +448,7 @@ fn check_implementations_of_coerce_unsized(&self) {
for a coercion between structures with one field \
being coerced, but {} fields need coercions: {}",
diff_fields.len(), diff_fields.iter().map(|&(i, a, b)| {
let name = fields[i].name;
format!("{} ({} to {})",
if name == token::special_names::unnamed_field {
i.to_string()
} else {
name.to_string()
}, a, b)
format!("{} ({} to {})", fields[i].name, a, b)
}).collect::<Vec<_>>().join(", "));
return;
}
......
......@@ -978,22 +978,18 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
let fields = def.fields().iter().map(|f| {
let fid = tcx.map.local_def_id(f.node.id);
if let Some(name) = f.node.name {
let dup_span = seen_fields.get(&name).cloned();
if let Some(prev_span) = dup_span {
let mut err = struct_span_err!(tcx.sess, f.span, E0124,
"field `{}` is already declared",
name);
span_note!(&mut err, prev_span, "previously declared here");
err.emit();
} else {
seen_fields.insert(name, f.span);
}
ty::FieldDefData::new(fid, name, f.node.vis)
let dup_span = seen_fields.get(&f.node.name).cloned();
if let Some(prev_span) = dup_span {
let mut err = struct_span_err!(tcx.sess, f.span, E0124,
"field `{}` is already declared",
f.node.name);
span_note!(&mut err, prev_span, "previously declared here");
err.emit();
} else {
ty::FieldDefData::new(fid, special_idents::unnamed_field.name, f.node.vis)
seen_fields.insert(f.node.name, f.span);
}
ty::FieldDefData::new(fid, f.node.name, f.node.vis)
}).collect();
ty::VariantDefData {
did: did,
......
......@@ -188,8 +188,6 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: DefId) -> clean
}
fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: DefId) -> clean::Struct {
use syntax::parse::token::special_idents::unnamed_field;
let t = tcx.lookup_item_type(did);
let predicates = tcx.lookup_predicates(did);
let variant = tcx.lookup_adt_def(did).struct_variant();
......@@ -197,8 +195,8 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: DefId) -> clean::Struct {
clean::Struct {
struct_type: match &*variant.fields {
[] => doctree::Unit,
[ref f] if f.name == unnamed_field.name => doctree::Newtype,
[ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
[_] if variant.kind == ty::VariantKind::Tuple => doctree::Newtype,
[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple,
_ => doctree::Plain,
},
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
......
......@@ -1735,15 +1735,12 @@ pub enum StructField {
impl Clean<Item> for hir::StructField {
fn clean(&self, cx: &DocContext) -> Item {
let (name, vis) = match self.node.kind {
hir::NamedField(id, vis) => (Some(id), vis),
hir::UnnamedField(vis) => (None, vis)
};
let name = if self.node.is_positional() { None } else { Some(self.node.name) };
Item {
name: name.clean(cx),
attrs: self.node.attrs.clean(cx),
source: self.span.clean(cx),
visibility: Some(vis),
visibility: Some(self.node.vis),
stability: get_stability(cx, cx.map.local_def_id(self.node.id)),
deprecation: get_deprecation(cx, cx.map.local_def_id(self.node.id)),
def_id: cx.map.local_def_id(self.node.id),
......@@ -1754,12 +1751,15 @@ fn clean(&self, cx: &DocContext) -> Item {
impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
fn clean(&self, cx: &DocContext) -> Item {
use syntax::parse::token::special_idents::unnamed_field;
// FIXME: possible O(n^2)-ness! Not my fault.
let attr_map =
cx.tcx().sess.cstore.crate_struct_field_attrs(self.did.krate);
let (name, attrs) = if self.name == unnamed_field.name {
let is_positional = {
let first = self.name.as_str().as_bytes()[0];
first >= b'0' && first <= b'9'
};
let (name, attrs) = if is_positional {
(None, None)
} else {
(Some(self.name), Some(attr_map.get(&self.did).unwrap()))
......@@ -1884,7 +1884,6 @@ fn clean(&self, cx: &DocContext) -> Item {
impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
fn clean(&self, cx: &DocContext) -> Item {
// use syntax::parse::token::special_idents::unnamed_field;
let kind = match self.kind() {
ty::VariantKind::Unit => CLikeVariant,
ty::VariantKind::Tuple => {
......
......@@ -542,7 +542,7 @@ pub mod special_idents {
// outside of libsyntax
(7, clownshoe_abi, "__rust_abi");
(8, opaque, "<opaque>");
(9, unnamed_field, "<unnamed_field>");
(9, __unused1, "<__unused1>");
(super::SELF_TYPE_KEYWORD_NAME_NUM, type_self, "Self");
(11, prelude_import, "prelude_import");
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册