AST/HIR: Merge field access expressions for named and numeric fields
This commit is contained in:
parent
6c537493d0
commit
44acea4d88
43 changed files with 105 additions and 432 deletions
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>),
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(_) |
|
||||
|
|
|
|||
|
|
@ -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, "[]"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue