AST/HIR: Merge field access expressions for named and numeric fields

This commit is contained in:
Vadim Petrochenkov 2018-04-01 21:48:39 +03:00
parent 6c537493d0
commit 44acea4d88
43 changed files with 105 additions and 432 deletions

View file

@ -389,7 +389,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
hir::ExprType(ref e, _) |
hir::ExprUnary(_, ref e) |
hir::ExprField(ref e, _) |
hir::ExprTupField(ref e, _) |
hir::ExprYield(ref e) |
hir::ExprRepeat(ref e, _) => {
self.straightline(expr, pred, Some(&**e).into_iter())

View file

@ -1025,9 +1025,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_expr(subexpression);
visitor.visit_name(name.span, name.node);
}
ExprTupField(ref subexpression, _) => {
visitor.visit_expr(subexpression);
}
ExprIndex(ref main_expression, ref index_expression) => {
visitor.visit_expr(main_expression);
visitor.visit_expr(index_expression)

View file

@ -3095,7 +3095,6 @@ impl<'a> LoweringContext<'a> {
P(self.lower_expr(el)),
respan(ident.span, self.lower_ident(ident)),
),
ExprKind::TupField(ref el, ident) => hir::ExprTupField(P(self.lower_expr(el)), ident),
ExprKind::Index(ref el, ref er) => {
hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
}

View file

@ -1276,7 +1276,6 @@ impl Expr {
ExprAssign(..) => ExprPrecedence::Assign,
ExprAssignOp(..) => ExprPrecedence::AssignOp,
ExprField(..) => ExprPrecedence::Field,
ExprTupField(..) => ExprPrecedence::TupField,
ExprIndex(..) => ExprPrecedence::Index,
ExprPath(..) => ExprPrecedence::Path,
ExprAddrOf(..) => ExprPrecedence::AddrOf,
@ -1363,12 +1362,8 @@ pub enum Expr_ {
///
/// For example, `a += 1`.
ExprAssignOp(BinOp, P<Expr>, P<Expr>),
/// Access of a named struct field (`obj.foo`)
/// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct or tuple field
ExprField(P<Expr>, Spanned<Name>),
/// Access of an unnamed field of a struct or tuple-struct
///
/// For example, `foo.0`.
ExprTupField(P<Expr>, Spanned<usize>),
/// An indexing operation (`foo[2]`)
ExprIndex(P<Expr>, P<Expr>),

View file

@ -1201,8 +1201,7 @@ impl<'a> State<'a> {
fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) -> io::Result<()> {
let prec =
match func.node {
hir::ExprField(..) |
hir::ExprTupField(..) => parser::PREC_FORCE_PAREN,
hir::ExprField(..) => parser::PREC_FORCE_PAREN,
_ => parser::PREC_POSTFIX,
};
@ -1405,11 +1404,6 @@ impl<'a> State<'a> {
self.s.word(".")?;
self.print_name(name.node)?;
}
hir::ExprTupField(ref expr, id) => {
self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?;
self.s.word(".")?;
self.print_usize(id.node)?;
}
hir::ExprIndex(ref expr, ref index) => {
self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?;
self.s.word("[")?;
@ -2376,7 +2370,6 @@ fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
hir::ExprCast(ref x, _) |
hir::ExprType(ref x, _) |
hir::ExprField(ref x, _) |
hir::ExprTupField(ref x, _) |
hir::ExprIndex(ref x, _) => {
// &X { y: 1 }, X { y: 1 }.y
contains_exterior_struct_lit(&x)

View file

@ -569,7 +569,6 @@ impl_stable_hash_for!(enum hir::Expr_ {
ExprAssign(lhs, rhs),
ExprAssignOp(op, lhs, rhs),
ExprField(owner, field_name),
ExprTupField(owner, idx),
ExprIndex(lhs, rhs),
ExprPath(path),
ExprAddrOf(mutability, sub),

View file

@ -104,17 +104,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
ty::TyAdt(def, _) => {
self.insert_def_id(def.non_enum_variant().field_named(name).did);
}
_ => span_bug!(lhs.span, "named field access on non-ADT"),
}
}
fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
match self.tables.expr_ty_adjusted(lhs).sty {
ty::TyAdt(def, _) => {
self.insert_def_id(def.non_enum_variant().fields[idx].did);
}
ty::TyTuple(..) => {}
_ => span_bug!(lhs.span, "numeric field access on non-ADT"),
_ => span_bug!(lhs.span, "named field access on non-ADT"),
}
}
@ -245,9 +236,6 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
hir::ExprField(ref lhs, ref name) => {
self.handle_field_access(&lhs, name.node);
}
hir::ExprTupField(ref lhs, idx) => {
self.handle_tup_field_access(&lhs, idx.node);
}
hir::ExprStruct(_, ref fields, _) => {
if let ty::TypeVariants::TyAdt(ref def, _) = self.tables.expr_ty(expr).sty {
if def.is_union() {

View file

@ -404,10 +404,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
self.select_from_expr(&base);
}
hir::ExprTupField(ref base, _) => { // base.<n>
self.select_from_expr(&base);
}
hir::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
self.select_from_expr(&lhs);
self.consume_expr(&rhs);

View file

@ -476,7 +476,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
}
// otherwise, live nodes are not required:
hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
hir::ExprIndex(..) | hir::ExprField(..) |
hir::ExprArray(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(..) |
@ -912,10 +912,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&e, succ)
}
hir::ExprTupField(ref e, _) => {
self.propagate_through_expr(&e, succ)
}
hir::ExprClosure(.., blk_id, _, _) => {
debug!("{} is an ExprClosure", self.ir.tcx.hir.node_to_pretty_string(expr.id));
@ -1226,7 +1222,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
match expr.node {
hir::ExprPath(_) => succ,
hir::ExprField(ref e, _) => self.propagate_through_expr(&e, succ),
hir::ExprTupField(ref e, _) => self.propagate_through_expr(&e, succ),
_ => self.propagate_through_expr(expr, succ)
}
}
@ -1419,7 +1414,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
// no correctness conditions related to liveness
hir::ExprCall(..) | hir::ExprMethodCall(..) | hir::ExprIf(..) |
hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) |
hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
hir::ExprIndex(..) | hir::ExprField(..) |
hir::ExprArray(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |

View file

@ -62,7 +62,6 @@
pub use self::PointerKind::*;
pub use self::InteriorKind::*;
pub use self::FieldName::*;
pub use self::MutabilityCategory::*;
pub use self::AliasableReason::*;
pub use self::Note::*;
@ -81,7 +80,7 @@ use ty::fold::TypeFoldable;
use hir::{MutImmutable, MutMutable, PatKind};
use hir::pat_util::EnumerateAndAdjustIterator;
use hir;
use syntax::ast;
use syntax::ast::{self, Name};
use syntax_pos::Span;
use std::fmt;
@ -129,15 +128,13 @@ pub enum PointerKind<'tcx> {
// base without a pointer dereference", e.g. a field
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum InteriorKind {
InteriorField(FieldName),
InteriorField(FieldIndex),
InteriorElement(InteriorOffsetKind),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum FieldName {
NamedField(ast::Name),
PositionalField(usize)
}
// FIXME: Use actual index instead of `ast::Name` with questionable hygiene
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct FieldIndex(pub ast::Name);
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum InteriorOffsetKind {
@ -198,7 +195,7 @@ pub enum ImmutabilityBlame<'tcx> {
}
impl<'tcx> cmt_<'tcx> {
fn resolve_field(&self, field_name: FieldName) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)>
fn resolve_field(&self, field_name: Name) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)>
{
let adt_def = match self.ty.sty {
ty::TyAdt(def, _) => def,
@ -215,11 +212,7 @@ impl<'tcx> cmt_<'tcx> {
&adt_def.variants[0]
}
};
let field_def = match field_name {
NamedField(name) => variant_def.field_named(name),
PositionalField(idx) => &variant_def.fields[idx]
};
Some((adt_def, field_def))
Some((adt_def, variant_def.field_named(field_name)))
}
pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
@ -230,8 +223,8 @@ impl<'tcx> cmt_<'tcx> {
match base_cmt.cat {
Categorization::Local(node_id) =>
Some(ImmutabilityBlame::LocalDeref(node_id)),
Categorization::Interior(ref base_cmt, InteriorField(field_name)) => {
base_cmt.resolve_field(field_name).map(|(adt_def, field_def)| {
Categorization::Interior(ref base_cmt, InteriorField(field_index)) => {
base_cmt.resolve_field(field_index.0).map(|(adt_def, field_def)| {
ImmutabilityBlame::AdtFieldDeref(adt_def, field_def)
})
}
@ -649,11 +642,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty))
}
hir::ExprTupField(ref base, idx) => {
let base_cmt = self.cat_expr(&base)?;
Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
}
hir::ExprIndex(ref base, _) => {
if self.tables.is_method_call(expr) {
// If this is an index implemented by a method call, then it
@ -979,14 +967,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
pub fn cat_field<N:ast_node>(&self,
node: &N,
base_cmt: cmt<'tcx>,
f_name: ast::Name,
f_name: Name,
f_ty: Ty<'tcx>)
-> cmt<'tcx> {
let ret = Rc::new(cmt_ {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: Categorization::Interior(base_cmt, InteriorField(NamedField(f_name))),
cat: Categorization::Interior(base_cmt, InteriorField(FieldIndex(f_name))),
ty: f_ty,
note: NoteNone
});
@ -994,24 +982,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
ret
}
pub fn cat_tup_field<N:ast_node>(&self,
node: &N,
base_cmt: cmt<'tcx>,
f_idx: usize,
f_ty: Ty<'tcx>)
-> cmt<'tcx> {
let ret = Rc::new(cmt_ {
id: node.id(),
span: node.span(),
mutbl: base_cmt.mutbl.inherit(),
cat: Categorization::Interior(base_cmt, InteriorField(PositionalField(f_idx))),
ty: f_ty,
note: NoteNone
});
debug!("cat_tup_field ret {:?}", ret);
ret
}
fn cat_overloaded_place(&self,
expr: &hir::Expr,
base: &hir::Expr,
@ -1292,8 +1262,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i)));
let interior = InteriorField(FieldIndex(Name::intern(&i.to_string())));
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior);
self.cat_pattern_(subcmt, &subpat, op)?;
}
}
@ -1332,8 +1302,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i)));
let interior = InteriorField(FieldIndex(Name::intern(&i.to_string())));
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior);
self.cat_pattern_(subcmt, &subpat, op)?;
}
}
@ -1516,12 +1486,9 @@ impl<'tcx> cmt_<'tcx> {
}
}
}
Categorization::Interior(_, InteriorField(NamedField(_))) => {
Categorization::Interior(_, InteriorField(..)) => {
"field".to_string()
}
Categorization::Interior(_, InteriorField(PositionalField(_))) => {
"anonymous field".to_string()
}
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index)) => {
"indexed content".to_string()
}
@ -1554,8 +1521,7 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
impl fmt::Debug for InteriorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
InteriorField(NamedField(fld)) => write!(f, "{}", fld),
InteriorField(PositionalField(i)) => write!(f, "#{}", i),
InteriorField(FieldIndex(name)) => write!(f, "{}", name),
InteriorElement(..) => write!(f, "[]"),
}
}

View file

@ -1307,7 +1307,6 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
hir::ExprAddrOf(_, ref subexpr) |
hir::ExprUnary(hir::UnDeref, ref subexpr) |
hir::ExprField(ref subexpr, _) |
hir::ExprTupField(ref subexpr, _) |
hir::ExprIndex(ref subexpr, _) => {
expr = &subexpr;
}