Auto merge of #31937 - petrochenkov:field, r=eddyb

The names are "0", "1", "2" etc, the same as used in field access.

This generally make things simpler and potentially allows to reuse braced struct machinery (struct patterns, struct expressions) for tuple structs.

I haven't touched the AST for stability reasons, but I intend to do it later.

r? @eddyb
This commit is contained in:
bors 2016-03-02 08:42:38 +00:00
commit 25e42ac106
26 changed files with 144 additions and 233 deletions

View File

@ -150,8 +150,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
for field in v.node.data.fields() {
self.create_def_with_parent(
Some(variant_def_index),
field.node.id,
DefPathData::Field(field.node.kind));
field.id,
DefPathData::Field(field.name));
}
}
}
@ -166,7 +166,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
for field in struct_def.fields() {
self.create_def(field.node.id, DefPathData::Field(field.node.kind));
self.create_def(field.id, DefPathData::Field(field.name));
}
}
ItemTrait(_, _, ref bounds, _) => {

View File

@ -11,7 +11,6 @@
use middle::cstore::LOCAL_CRATE;
use middle::def_id::{DefId, DefIndex};
use rustc_data_structures::fnv::FnvHashMap;
use rustc_front::hir;
use syntax::ast;
use syntax::parse::token::InternedString;
use util::nodemap::NodeMap;
@ -84,8 +83,7 @@ pub enum DefPathData {
TypeParam(ast::Name),
LifetimeDef(ast::Name),
EnumVariant(ast::Name),
PositionalField,
Field(hir::StructFieldKind),
Field(ast::Name),
StructCtor, // implicit ctor for a tuple-like struct
Initializer, // initializer for a const
Binding(ast::Name), // pattern binding
@ -186,19 +184,11 @@ impl DefPathData {
LifetimeDef(name) |
EnumVariant(name) |
DetachedCrate(name) |
Binding(name) => {
Binding(name) |
Field(name) => {
name.as_str()
}
Field(hir::StructFieldKind::NamedField(name, _)) => {
name.as_str()
}
PositionalField |
Field(hir::StructFieldKind::UnnamedField(_)) => {
InternedString::new("{{field}}")
}
// note that this does not show up in user printouts
CrateRoot => {
InternedString::new("{{root}}")

View File

@ -811,7 +811,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
}
fn visit_struct_field(&mut self, s: &hir::StructField) {
self.with_lint_attrs(&s.node.attrs, |cx| {
self.with_lint_attrs(&s.attrs, |cx| {
run_lints!(cx, check_struct_field, late_passes, s);
hir_visit::walk_struct_field(cx, s);
})

View File

@ -221,12 +221,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
let has_extern_repr = self.struct_has_extern_repr;
let inherited_pub_visibility = self.inherited_pub_visibility;
let live_fields = def.fields().iter().filter(|f| {
has_extern_repr || inherited_pub_visibility || match f.node.kind {
hir::NamedField(_, hir::Public) => true,
_ => false
}
has_extern_repr || inherited_pub_visibility || f.vis == hir::Public
});
self.live_symbols.extend(live_fields.map(|f| f.node.id));
self.live_symbols.extend(live_fields.map(|f| f.id));
intravisit::walk_struct_def(self, def);
}
@ -431,17 +428,16 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
should_warn && !self.symbol_is_live(item.id, ctor_id)
}
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);
fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
let field_type = self.tcx.node_id_to_type(field.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
&& !self.symbol_is_live(node.id, None)
!field.is_positional()
&& !self.symbol_is_live(field.id, None)
&& !is_marker_field
&& !has_allow_dead_code_or_lang_attr(&node.attrs)
&& !has_allow_dead_code_or_lang_attr(&field.attrs)
}
fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
@ -547,9 +543,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
}
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");
if self.should_warn_about_field(&field) {
self.warn_dead_code(field.id, field.span,
field.name, "struct field");
}
intravisit::walk_struct_field(self, field);

View File

@ -259,7 +259,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
}
fn visit_struct_field(&mut self, s: &StructField) {
self.annotate(s.node.id, &s.node.attrs, s.span, AnnotationKind::Required, |v| {
self.annotate(s.id, &s.attrs, s.span, AnnotationKind::Required, |v| {
intravisit::walk_struct_field(v, s);
});
}

View File

@ -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

View File

@ -700,15 +700,13 @@ pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> Poly
}
pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField {
let StructField {node: StructField_ {id, kind, ty, attrs}, span} = f;
Spanned {
node: StructField_ {
id: fld.new_id(id),
kind: kind,
ty: fld.fold_ty(ty),
attrs: fold_attrs(attrs, fld),
},
span: fld.new_span(span),
StructField {
span: fld.new_span(f.span),
id: fld.new_id(f.id),
name: f.name,
vis: f.vis,
ty: fld.fold_ty(f.ty),
attrs: fold_attrs(f.attrs, fld),
}
}

View File

@ -24,7 +24,6 @@ pub use self::Mutability::*;
pub use self::PathListItem_::*;
pub use self::PrimTy::*;
pub use self::Stmt_::*;
pub use self::StructFieldKind::*;
pub use self::TraitItem_::*;
pub use self::Ty_::*;
pub use self::TyParamBound::*;
@ -1242,43 +1241,20 @@ impl Visibility {
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct StructField_ {
pub kind: StructFieldKind,
pub struct StructField {
pub span: Span,
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'
}
}

View File

@ -669,9 +669,9 @@ 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_ty(&struct_field.node.ty);
walk_list!(visitor, visit_attribute, &struct_field.node.attrs);
visitor.visit_name(struct_field.span, struct_field.name);
visitor.visit_ty(&struct_field.ty);
walk_list!(visitor, visit_attribute, &struct_field.attrs);
}
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {

View File

@ -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,15 +609,17 @@ pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::Po
}
}
pub fn lower_struct_field(lctx: &LoweringContext, f: &StructField) -> hir::StructField {
Spanned {
node: hir::StructField_ {
id: f.node.id,
kind: lower_struct_field_kind(lctx, &f.node.kind),
ty: lower_ty(lctx, &f.node.ty),
attrs: lower_attrs(lctx, &f.node.attrs),
},
pub fn lower_struct_field(lctx: &LoweringContext,
(index, f): (usize, &StructField))
-> hir::StructField {
hir::StructField {
span: f.span,
id: f.node.id,
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),
}
}
@ -1589,15 +1593,6 @@ pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::Bindi
}
}
pub fn lower_struct_field_kind(lctx: &LoweringContext,
s: &StructFieldKind)
-> hir::StructFieldKind {
match *s {
NamedField(ident, vis) => hir::NamedField(ident.name, lower_visibility(lctx, vis)),
UnnamedField(vis) => hir::UnnamedField(lower_visibility(lctx, vis)),
}
}
pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource {
match u {
CompilerGenerated => hir::CompilerGenerated,

View File

@ -915,14 +915,9 @@ impl<'a> State<'a> {
if struct_def.is_tuple() {
try!(self.popen());
try!(self.commasep(Inconsistent, struct_def.fields(), |s, field| {
match field.node.kind {
hir::NamedField(..) => panic!("unexpected named field"),
hir::UnnamedField(vis) => {
try!(s.print_visibility(vis));
try!(s.maybe_print_comment(field.span.lo));
s.print_type(&field.node.ty)
}
}
try!(s.print_visibility(field.vis));
try!(s.maybe_print_comment(field.span.lo));
s.print_type(&field.ty)
}));
try!(self.pclose());
}
@ -939,19 +934,14 @@ impl<'a> State<'a> {
try!(self.hardbreak_if_not_bol());
for field in struct_def.fields() {
match field.node.kind {
hir::UnnamedField(..) => panic!("unexpected unnamed field"),
hir::NamedField(name, visibility) => {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(field.span.lo));
try!(self.print_outer_attributes(&field.node.attrs));
try!(self.print_visibility(visibility));
try!(self.print_name(name));
try!(self.word_nbsp(":"));
try!(self.print_type(&field.node.ty));
try!(word(&mut self.s, ","));
}
}
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(field.span.lo));
try!(self.print_outer_attributes(&field.attrs));
try!(self.print_visibility(field.vis));
try!(self.print_name(field.name));
try!(self.word_nbsp(":"));
try!(self.print_type(&field.ty));
try!(word(&mut self.s, ","));
}
self.bclose(span)

View File

@ -271,7 +271,7 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O>
}
fn visit_struct_field(&mut self, struct_field: &StructField) {
self.operation.visit_id(struct_field.node.id);
self.operation.visit_id(struct_field.id);
intravisit::walk_struct_field(self, struct_field)
}

View File

@ -283,10 +283,7 @@ impl LateLintPass for NonSnakeCase {
fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
_: ast::Name, _: &hir::Generics, _: ast::NodeId) {
for sf in s.fields() {
if let hir::StructField_ { kind: hir::NamedField(name, _), .. } = sf.node {
self.check_snake_case(cx, "structure field", &name.as_str(),
Some(sf.span));
}
self.check_snake_case(cx, "structure field", &sf.name.as_str(), Some(sf.span));
}
}
}

View File

@ -126,7 +126,7 @@ impl LateLintPass for BoxPointers {
hir::ItemStruct(ref struct_def, _) => {
for struct_field in struct_def.fields() {
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.id));
}
}
_ => ()
@ -428,12 +428,12 @@ impl LateLintPass for MissingDoc {
}
fn check_struct_field(&mut self, cx: &LateContext, sf: &hir::StructField) {
if let hir::NamedField(_, vis) = sf.node.kind {
if vis == hir::Public || self.in_variant {
if !sf.is_positional() {
if sf.vis == hir::Public || self.in_variant {
let cur_struct_def = *self.struct_def_stack.last()
.expect("empty struct_def_stack");
self.check_missing_docs_attrs(cx, Some(cur_struct_def),
&sf.node.attrs, sf.span,
&sf.attrs, sf.span,
"a struct field")
}
}

View File

@ -48,8 +48,7 @@ use rbml::reader;
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 @@ pub fn get_adt_def<'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 @@ pub fn get_adt_def<'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()
}

View File

@ -46,7 +46,6 @@ use syntax::codemap::BytePos;
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);
@ -1752,9 +1751,9 @@ fn encode_struct_field_attrs(ecx: &EncodeContext,
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'c, 'tcx> {
fn visit_struct_field(&mut self, field: &hir::StructField) {
self.rbml_w.start_tag(tag_struct_field);
let def_id = self.ecx.tcx.map.local_def_id(field.node.id);
let def_id = self.ecx.tcx.map.local_def_id(field.id);
encode_def_id(self.rbml_w, def_id);
encode_attributes(self.rbml_w, &field.node.attrs);
encode_attributes(self.rbml_w, &field.attrs);
self.rbml_w.end_tag();
}
}

View File

@ -147,7 +147,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ParentVisitor<'a, 'tcx> {
// While we have the id of the struct definition, go ahead and parent
// all the fields.
for field in s.fields() {
self.parents.insert(field.node.id, self.curparent);
self.parents.insert(field.id, self.curparent);
}
intravisit::walk_struct_def(self, s)
}
@ -262,7 +262,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
for variant in &def.variants {
let variant_level = self.update(variant.node.data.id(), item_level);
for field in variant.node.data.fields() {
self.update(field.node.id, variant_level);
self.update(field.id, variant_level);
}
}
}
@ -288,8 +288,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
self.update(def.id(), item_level);
}
for field in def.fields() {
if field.node.kind.visibility() == hir::Public {
self.update(field.node.id, item_level);
if field.vis == hir::Public {
self.update(field.id, item_level);
}
}
}
@ -347,7 +347,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
if item_level.is_some() {
self.reach().visit_generics(generics);
for field in struct_def.fields() {
if self.get(field.node.id).is_some() {
if self.get(field.id).is_some() {
self.reach().visit_struct_field(field);
}
}
@ -1178,7 +1178,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
hir::ItemEnum(ref def, _) => {
for variant in &def.variants {
for field in variant.node.data.fields() {
check_inherited(field.span, field.node.kind.visibility(),
check_inherited(field.span, field.vis,
"visibility qualifiers have no effect on variant fields");
}
}
@ -1514,10 +1514,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
}
fn visit_struct_field(&mut self, s: &hir::StructField) {
let vis = match s.node.kind {
hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
};
if vis == hir::Public || self.in_variant {
if s.vis == hir::Public || self.in_variant {
intravisit::walk_struct_field(self, s);
}
}
@ -1728,7 +1725,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
if item.vis == hir::Public {
check.visit_generics(generics);
for field in struct_def.fields() {
if field.node.kind.visibility() == hir::Public {
if field.vis == hir::Public {
check.visit_struct_field(field);
}
}

View File

@ -41,9 +41,7 @@ use rustc_front::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic};
use rustc_front::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
use rustc_front::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use rustc_front::hir::{NamedField, PathListIdent, PathListMod};
use rustc_front::hir::StmtDecl;
use rustc_front::hir::UnnamedField;
use rustc_front::hir::{PathListIdent, PathListMod, StmtDecl};
use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use rustc_front::hir::Visibility;
use rustc_front::intravisit::{self, Visitor};
@ -382,17 +380,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
// Record the def ID and fields of this struct.
let named_fields = struct_def.fields()
.iter()
.filter_map(|f| {
match f.node.kind {
NamedField(name, _) => Some(name),
UnnamedField(_) => None,
}
})
.collect();
let field_names = struct_def.fields()
.iter()
.map(|f| f.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
}

View File

@ -21,7 +21,6 @@ use util::nodemap::FnvHashSet;
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))

View File

@ -567,7 +567,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let fields =
struct_def.fields().iter()
.map(|field| {
let field_ty = fcx.tcx().node_id_to_type(field.node.id);
let field_ty = fcx.tcx().node_id_to_type(field.id);
let field_ty = fcx.instantiate_type_scheme(field.span,
&fcx.inh
.infcx

View File

@ -36,7 +36,6 @@ use middle::infer::{self, InferCtxt, TypeOrigin, new_infer_ctxt};
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 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
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;
}

View File

@ -574,20 +574,20 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
struct_generics: &ty::Generics<'tcx>,
struct_predicates: &ty::GenericPredicates<'tcx>,
v: &hir::StructField,
field: &hir::StructField,
ty_f: ty::FieldDefMaster<'tcx>)
{
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &v.node.ty);
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
ty_f.fulfill_ty(tt);
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
write_ty_to_tcx(ccx.tcx, field.id, tt);
/* add the field to the tcache */
ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(v.node.id),
ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(field.id),
ty::TypeScheme {
generics: struct_generics.clone(),
ty: tt
});
ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(v.node.id),
ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(field.id),
struct_predicates.clone());
}
@ -977,26 +977,19 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
def: &hir::VariantData) -> ty::VariantDefData<'tcx, '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);
match f.node.kind {
hir::NamedField(name, vis) => {
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, vis)
},
hir::UnnamedField(vis) => {
ty::FieldDefData::new(fid, special_idents::unnamed_field.name, vis)
}
let fid = tcx.map.local_def_id(f.id);
let dup_span = seen_fields.get(&f.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.name);
span_note!(&mut err, prev_span, "previously declared here");
err.emit();
} else {
seen_fields.insert(f.name, f.span);
}
ty::FieldDefData::new(fid, f.name, f.vis)
}).collect();
ty::VariantDefData {
did: did,

View File

@ -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),

View File

@ -1735,39 +1735,26 @@ 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)
};
Item {
name: name.clean(cx),
attrs: self.node.attrs.clean(cx),
name: Some(self.name).clean(cx),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: Some(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),
inner: StructFieldItem(TypedStructField(self.node.ty.clean(cx))),
visibility: Some(self.vis),
stability: get_stability(cx, cx.map.local_def_id(self.id)),
deprecation: get_deprecation(cx, cx.map.local_def_id(self.id)),
def_id: cx.map.local_def_id(self.id),
inner: StructFieldItem(TypedStructField(self.ty.clean(cx))),
}
}
}
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 {
(None, None)
} else {
(Some(self.name), Some(attr_map.get(&self.did).unwrap()))
};
let attr_map = cx.tcx().sess.cstore.crate_struct_field_attrs(self.did.krate);
Item {
name: name.clean(cx),
attrs: attrs.unwrap_or(&Vec::new()).clean(cx),
name: Some(self.name).clean(cx),
attrs: attr_map.get(&self.did).unwrap_or(&Vec::new()).clean(cx),
source: Span::empty(),
visibility: Some(self.vis),
stability: get_stability(cx, self.did),
@ -1884,7 +1871,6 @@ impl Clean<Item> for doctree::Variant {
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 => {
@ -1946,7 +1932,7 @@ fn struct_def_to_variant_kind(struct_def: &hir::VariantData, cx: &DocContext) ->
} else if struct_def.is_unit() {
CLikeVariant
} else {
TupleVariant(struct_def.fields().iter().map(|x| x.node.ty.clean(cx)).collect())
TupleVariant(struct_def.fields().iter().map(|x| x.ty.clean(cx)).collect())
}
}

View File

@ -542,7 +542,7 @@ declare_special_idents_and_keywords! {
// 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");
}

View File

@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct Foo;
#[derive(Copy, Clone)]
//~^ ERROR the trait `Copy` may not be implemented for this type; field `0` does not implement
struct Bar(Foo);
fn main() {}