Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give Names to positional fields and merge them with named fields #31937

Merged
merged 4 commits into from
Mar 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/librustc/front/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
Expand All @@ -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, _) => {
Expand Down
16 changes: 3 additions & 13 deletions src/librustc/front/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}}")
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
})
Expand Down
24 changes: 10 additions & 14 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/middle/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 7 additions & 9 deletions src/librustc_front/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}

Expand Down
42 changes: 9 additions & 33 deletions src/librustc_front/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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'
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc_front/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
29 changes: 12 additions & 17 deletions src/librustc_front/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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),
}
}

Expand Down Expand Up @@ -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,
Expand Down
32 changes: 11 additions & 21 deletions src/librustc_front/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_front/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
5 changes: 1 addition & 4 deletions src/librustc_lint/bad_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
_ => ()
Expand Down Expand Up @@ -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")
}
}
Expand Down
Loading