Skip to content

Commit

Permalink
Rollup merge of rust-lang#32682 - petrochenkov:field3, r=Manishearth
Browse files Browse the repository at this point in the history
 The AST part of rust-lang#31937

Unlike HIR, AST still uses `Option` for field names because parser can't know field indexes reliably due to constructions like
```
struct S(#[cfg(false)] u8, u8); // The index of the second field changes from 1 during parsing to 0 after expansion.
```
and I wouldn't like to put the burden of renaming fields on expansion passes and syntax extensions.

plugin-[breaking-change] cc rust-lang#31645
r? @Manishearth
  • Loading branch information
Manishearth committed Apr 6, 2016
2 parents 772c600 + 8fe4290 commit af7b00b
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 164 deletions.
2 changes: 1 addition & 1 deletion src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
}

fn visit_struct_field(&mut self, s: &ast::StructField) {
self.with_lint_attrs(&s.node.attrs, |cx| {
self.with_lint_attrs(&s.attrs, |cx| {
run_lints!(cx, check_struct_field, early_passes, s);
ast_visit::walk_struct_field(cx, s);
})
Expand Down
11 changes: 5 additions & 6 deletions src/librustc_front/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,11 @@ pub fn lower_struct_field(lctx: &LoweringContext,
-> 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),
id: f.id,
name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())),
vis: lower_visibility(lctx, &f.vis),
ty: lower_ty(lctx, &f.ty),
attrs: lower_attrs(lctx, &f.attrs),
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ where D: Dump
// fields
for field in def.fields() {
self.process_struct_field_def(field, item.id);
self.visit_ty(&field.node.ty);
self.visit_ty(&field.ty);
}

self.process_generic_params(ty_params, item.span, &qualname, item.id);
Expand Down Expand Up @@ -624,7 +624,7 @@ where D: Dump

for field in variant.node.data.fields() {
self.process_struct_field_def(field, variant.node.data.id());
self.visit_ty(&field.node.ty);
self.visit_ty(&field.ty);
}
}
self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
Expand Down
33 changes: 16 additions & 17 deletions src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,23 +246,22 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {

pub fn get_field_data(&self, field: &ast::StructField,
scope: NodeId) -> Option<VariableData> {
match field.node.kind {
ast::NamedField(ident, _) => {
let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident);
let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string();
let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
filter!(self.span_utils, sub_span, field.span, None);
Some(VariableData {
id: field.node.id,
name: ident.to_string(),
qualname: qualname,
span: sub_span.unwrap(),
scope: scope,
value: "".to_owned(),
type_value: typ,
})
}
_ => None,
if let Some(ident) = field.ident {
let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident);
let typ = self.tcx.node_types().get(&field.id).unwrap().to_string();
let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
filter!(self.span_utils, sub_span, field.span, None);
Some(VariableData {
id: field.id,
name: ident.to_string(),
qualname: qualname,
span: sub_span.unwrap(),
scope: scope,
value: "".to_owned(),
type_value: typ,
})
} else {
None
}
}

Expand Down
40 changes: 4 additions & 36 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

// The Rust abstract syntax tree.

pub use self::StructFieldKind::*;
pub use self::TyParamBound::*;
pub use self::UnsafeSource::*;
pub use self::ViewPath_::*;
Expand Down Expand Up @@ -1877,46 +1876,15 @@ pub enum Visibility {
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct StructField_ {
pub kind: StructFieldKind,
pub struct StructField {
pub span: Span,
pub ident: Option<Ident>,
pub vis: Visibility,
pub id: NodeId,
pub ty: P<Ty>,
pub attrs: Vec<Attribute>,
}

impl StructField_ {
pub fn ident(&self) -> Option<Ident> {
match self.kind {
NamedField(ref ident, _) => Some(ident.clone()),
UnnamedField(_) => None
}
}
}

pub type StructField = Spanned<StructField_>;

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum StructFieldKind {
NamedField(Ident, 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(_, ref vis) | UnnamedField(ref vis) => vis
}
}
}

/// Fields and Ids of enum variants and structs
///
/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
Expand Down
8 changes: 1 addition & 7 deletions src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident
token::gensym_ident(&pretty[..])
}

pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
match field.node.kind {
ast::NamedField(_, v) | ast::UnnamedField(v) => v
}
}

// ______________________________________________________________________
// Enumerating the IDs which appear in an AST

Expand Down Expand Up @@ -269,7 +263,7 @@ impl<'a, 'v, O: 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);
visit::walk_struct_field(self, struct_field)
}

Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,12 @@ fn fold_struct<F>(cx: &mut Context<F>, vdata: ast::VariantData) -> ast::VariantD
match vdata {
ast::VariantData::Struct(fields, id) => {
ast::VariantData::Struct(fields.into_iter().filter(|m| {
(cx.in_cfg)(&m.node.attrs)
(cx.in_cfg)(&m.attrs)
}).collect(), id)
}
ast::VariantData::Tuple(fields, id) => {
ast::VariantData::Tuple(fields.into_iter().filter(|m| {
(cx.in_cfg)(&m.node.attrs)
(cx.in_cfg)(&m.attrs)
}).collect(), id)
}
ast::VariantData::Unit(id) => ast::VariantData::Unit(id)
Expand Down Expand Up @@ -434,7 +434,7 @@ impl<'v, 'a, 'b> visit::Visitor<'v> for StmtExprAttrFeatureVisitor<'a, 'b> {
}

fn visit_struct_field(&mut self, s: &'v ast::StructField) {
if node_survives_cfg(&s.node.attrs, self.config) {
if node_survives_cfg(&s.attrs, self.config) {
visit::walk_struct_field(self, s);
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,12 +1007,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {

fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
let fields: Vec<_> = tys.into_iter().map(|ty| {
Spanned { span: ty.span, node: ast::StructField_ {
ast::StructField {
span: ty.span,
ty: ty,
kind: ast::UnnamedField(ast::Visibility::Inherited),
ident: None,
vis: ast::Visibility::Inherited,
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
}}
}
}).collect();

let vdata = if fields.is_empty() {
Expand Down
16 changes: 7 additions & 9 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,15 +847,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),
ident: f.ident.map(|ident| fld.fold_ident(ident)),
vis: f.vis,
ty: fld.fold_ty(f.ty),
attrs: fold_attrs(f.attrs, fld),
}
}

Expand Down
23 changes: 13 additions & 10 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use ast::Local;
use ast::MacStmtStyle;
use ast::Mac_;
use ast::{MutTy, Mutability};
use ast::NamedField;
use ast::{Pat, PatKind};
use ast::{PolyTraitRef, QSelf};
use ast::{Stmt, StmtKind};
Expand All @@ -38,7 +37,6 @@ use ast::StrStyle;
use ast::SelfKind;
use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
use ast::UnnamedField;
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause};
use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
Expand Down Expand Up @@ -3847,12 +3845,14 @@ impl<'a> Parser<'a> {
let name = self.parse_ident()?;
self.expect(&token::Colon)?;
let ty = self.parse_ty_sum()?;
Ok(spanned(lo, self.last_span.hi, ast::StructField_ {
kind: NamedField(name, pr),
Ok(StructField {
span: mk_sp(lo, self.last_span.hi),
ident: Some(name),
vis: pr,
id: ast::DUMMY_NODE_ID,
ty: ty,
attrs: attrs,
}))
})
}

/// Emit an expected item after attributes error.
Expand Down Expand Up @@ -5246,13 +5246,16 @@ impl<'a> Parser<'a> {
|p| {
let attrs = p.parse_outer_attributes()?;
let lo = p.span.lo;
let struct_field_ = ast::StructField_ {
kind: UnnamedField(p.parse_visibility()?),
let vis = p.parse_visibility()?;
let ty = p.parse_ty_sum()?;
Ok(StructField {
span: mk_sp(lo, p.span.hi),
vis: vis,
ident: None,
id: ast::DUMMY_NODE_ID,
ty: p.parse_ty_sum()?,
ty: ty,
attrs: attrs,
};
Ok(spanned(lo, p.span.hi, struct_field_))
})
})?;

Ok(fields)
Expand Down
32 changes: 11 additions & 21 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,14 +1407,9 @@ impl<'a> State<'a> {
self.commasep(
Inconsistent, struct_def.fields(),
|s, field| {
match field.node.kind {
ast::NamedField(..) => panic!("unexpected named field"),
ast::UnnamedField(ref vis) => {
s.print_visibility(vis)?;
s.maybe_print_comment(field.span.lo)?;
s.print_type(&field.node.ty)
}
}
s.print_visibility(&field.vis)?;
s.maybe_print_comment(field.span.lo)?;
s.print_type(&field.ty)
}
)?;
self.pclose()?;
Expand All @@ -1432,19 +1427,14 @@ impl<'a> State<'a> {
self.hardbreak_if_not_bol()?;

for field in struct_def.fields() {
match field.node.kind {
ast::UnnamedField(..) => panic!("unexpected unnamed field"),
ast::NamedField(ident, ref visibility) => {
self.hardbreak_if_not_bol()?;
self.maybe_print_comment(field.span.lo)?;
self.print_outer_attributes(&field.node.attrs)?;
self.print_visibility(visibility)?;
self.print_ident(ident)?;
self.word_nbsp(":")?;
self.print_type(&field.node.ty)?;
word(&mut self.s, ",")?;
}
}
self.hardbreak_if_not_bol()?;
self.maybe_print_comment(field.span.lo)?;
self.print_outer_attributes(&field.attrs)?;
self.print_visibility(&field.vis)?;
self.print_ident(field.ident.unwrap())?;
self.word_nbsp(":")?;
self.print_type(&field.ty)?;
word(&mut self.s, ",")?;
}

self.bclose(span)
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,9 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,

pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
struct_field: &'v StructField) {
walk_opt_ident(visitor, struct_field.span, struct_field.node.ident());
visitor.visit_ty(&struct_field.node.ty);
walk_list!(visitor, visit_attribute, &struct_field.node.attrs);
walk_opt_ident(visitor, struct_field.span, struct_field.ident);
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
Loading

0 comments on commit af7b00b

Please sign in to comment.