AST/HIR: Merge field access expressions for named and numeric fields
This commit is contained in:
parent
6c537493d0
commit
44acea4d88
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
|||
RestrictionResult::Safe => RestrictionResult::Safe,
|
||||
RestrictionResult::SafeIf(base_lp, mut base_vec) => {
|
||||
for field in &adt_def.non_enum_variant().fields {
|
||||
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
|
||||
let field = InteriorKind::InteriorField(mc::FieldIndex(field.name));
|
||||
let field_ty = if field == interior {
|
||||
cmt.ty
|
||||
} else {
|
||||
|
|
|
@ -370,7 +370,7 @@ const DOWNCAST_PRINTED_OPERATOR: &'static str = " as ";
|
|||
// is tracked is irrelevant here.)
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum InteriorKind {
|
||||
InteriorField(mc::FieldName),
|
||||
InteriorField(mc::FieldIndex),
|
||||
InteriorElement,
|
||||
}
|
||||
|
||||
|
@ -1336,18 +1336,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||
out.push(')');
|
||||
}
|
||||
|
||||
LpExtend(ref lp_base, _, LpInterior(_, InteriorField(fname))) => {
|
||||
LpExtend(ref lp_base, _, LpInterior(_, InteriorField(mc::FieldIndex(fname)))) => {
|
||||
self.append_autoderefd_loan_path_to_string(&lp_base, out);
|
||||
match fname {
|
||||
mc::NamedField(fname) => {
|
||||
out.push('.');
|
||||
out.push_str(&fname.as_str());
|
||||
}
|
||||
mc::PositionalField(idx) => {
|
||||
out.push('.');
|
||||
out.push_str(&idx.to_string());
|
||||
}
|
||||
}
|
||||
out.push('.');
|
||||
out.push_str(&fname.as_str());
|
||||
}
|
||||
|
||||
LpExtend(ref lp_base, _, LpInterior(_, InteriorElement)) => {
|
||||
|
@ -1422,8 +1414,7 @@ impl DataFlowOperator for LoanDataFlowOperator {
|
|||
impl<'tcx> fmt::Debug for InteriorKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
InteriorField(mc::NamedField(fld)) => write!(f, "{}", fld),
|
||||
InteriorField(mc::PositionalField(i)) => write!(f, "#{}", i),
|
||||
InteriorField(mc::FieldIndex(name)) => write!(f, "{}", name),
|
||||
InteriorElement => write!(f, "[]"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ use rustc::middle::dataflow::DataFlowOperator;
|
|||
use rustc::middle::dataflow::KillFrom;
|
||||
use rustc::middle::expr_use_visitor as euv;
|
||||
use rustc::middle::expr_use_visitor::MutateMode;
|
||||
use rustc::middle::mem_categorization as mc;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
|
||||
|
@ -344,7 +343,7 @@ impl<'a, 'tcx> MoveData<'tcx> {
|
|||
= (&base_lp.ty.sty, lp_elem) {
|
||||
if adt_def.is_union() {
|
||||
for field in &adt_def.non_enum_variant().fields {
|
||||
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
|
||||
let field = InteriorKind::InteriorField(mc::FieldIndex(field.name));
|
||||
if field != interior {
|
||||
let sibling_lp_kind =
|
||||
LpExtend(base_lp.clone(), mutbl, LpInterior(opt_variant_id, field));
|
||||
|
@ -396,7 +395,7 @@ impl<'a, 'tcx> MoveData<'tcx> {
|
|||
if let ty::TyAdt(adt_def, _) = base_lp.ty.sty {
|
||||
if adt_def.is_union() {
|
||||
for field in &adt_def.non_enum_variant().fields {
|
||||
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
|
||||
let field = InteriorKind::InteriorField(mc::FieldIndex(field.name));
|
||||
let field_ty = if field == interior {
|
||||
lp.ty
|
||||
} else {
|
||||
|
|
|
@ -584,6 +584,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
hir::ExprField(ref source, name) => {
|
||||
let index = match cx.tables().expr_ty_adjusted(source).sty {
|
||||
ty::TyAdt(adt_def, _) => adt_def.variants[0].index_of_field_named(name.node),
|
||||
ty::TyTuple(..) => name.node.as_str().parse::<usize>().ok(),
|
||||
ref ty => span_bug!(expr.span, "field of non-ADT: {:?}", ty),
|
||||
};
|
||||
let index =
|
||||
|
@ -595,12 +596,6 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
name: Field::new(index),
|
||||
}
|
||||
}
|
||||
hir::ExprTupField(ref source, index) => {
|
||||
ExprKind::Field {
|
||||
lhs: source.to_ref(),
|
||||
name: Field::new(index.node as usize),
|
||||
}
|
||||
}
|
||||
hir::ExprCast(ref source, _) => {
|
||||
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
||||
// using a coercion (or is a no-op).
|
||||
|
|
|
@ -407,7 +407,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
|||
hir::ExprBlock(_) |
|
||||
hir::ExprIndex(..) |
|
||||
hir::ExprField(..) |
|
||||
hir::ExprTupField(..) |
|
||||
hir::ExprArray(_) |
|
||||
hir::ExprType(..) |
|
||||
hir::ExprTup(..) => {}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
use rustc::hir::def::Def as HirDef;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map::Node;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
|
@ -1638,52 +1637,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::ExprKind::TupField(ref sub_ex, idx) => {
|
||||
self.visit_expr(&sub_ex);
|
||||
|
||||
let hir_node = match self.save_ctxt.tcx.hir.find(sub_ex.id) {
|
||||
Some(Node::NodeExpr(expr)) => expr,
|
||||
_ => {
|
||||
debug!(
|
||||
"Missing or weird node for sub-expression {} in {:?}",
|
||||
sub_ex.id,
|
||||
ex
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let ty = match self.save_ctxt.tables.expr_ty_adjusted_opt(&hir_node) {
|
||||
Some(ty) => &ty.sty,
|
||||
None => {
|
||||
visit::walk_expr(self, ex);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match *ty {
|
||||
ty::TyAdt(def, _) => {
|
||||
let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);
|
||||
if !self.span.filter_generated(sub_span, ex.span) {
|
||||
let span =
|
||||
self.span_from_span(sub_span.expect("No span found for var ref"));
|
||||
if let Some(field) = def.non_enum_variant().fields.get(idx.node) {
|
||||
let ref_id = ::id_from_def_id(field.did);
|
||||
self.dumper.dump_ref(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
ref_id,
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::TyTuple(..) => {}
|
||||
_ => {
|
||||
debug!("Expected struct or tuple type, found {:?}", ty);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Closure(_, _, ref decl, ref body, _fn_decl_span) => {
|
||||
let mut id = String::from("$");
|
||||
id.push_str(&ex.id.to_string());
|
||||
|
|
|
@ -563,6 +563,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
ref_id: id_from_def_id(f.did),
|
||||
}));
|
||||
}
|
||||
ty::TyTuple(..) => None,
|
||||
_ => {
|
||||
debug!("Expected struct or union type, found {:?}", ty);
|
||||
None
|
||||
|
|
|
@ -202,10 +202,6 @@ impl<'a> SpanUtils<'a> {
|
|||
self.sub_span_after(span, |t| t.is_keyword(keyword))
|
||||
}
|
||||
|
||||
pub fn sub_span_after_token(&self, span: Span, tok: Token) -> Option<Span> {
|
||||
self.sub_span_after(span, |t| t == tok)
|
||||
}
|
||||
|
||||
fn sub_span_after<F: Fn(Token) -> bool>(&self, span: Span, f: F) -> Option<Span> {
|
||||
let mut toks = self.retokenise_span(span);
|
||||
loop {
|
||||
|
|
|
@ -433,7 +433,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
let last = exprs[exprs.len() - 1];
|
||||
match last.node {
|
||||
hir::ExprField(ref expr, _) |
|
||||
hir::ExprTupField(ref expr, _) |
|
||||
hir::ExprIndex(ref expr, _) |
|
||||
hir::ExprUnary(hir::UnDeref, ref expr) => exprs.push(&expr),
|
||||
_ => break,
|
||||
|
|
|
@ -85,7 +85,7 @@ use self::method::MethodCallee;
|
|||
use self::TupleArgumentsFlag::*;
|
||||
|
||||
use astconv::AstConv;
|
||||
use hir::def::{Def, CtorKind};
|
||||
use hir::def::Def;
|
||||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use std::slice;
|
||||
use namespace::Namespace;
|
||||
|
@ -121,7 +121,7 @@ use std::ops::{self, Deref};
|
|||
use syntax::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{self, original_sp, Spanned};
|
||||
use syntax::codemap::{original_sp, Spanned};
|
||||
use syntax::feature_gate::{GateIssue, emit_feature_err};
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::{Symbol, InternedString, keywords};
|
||||
|
@ -2266,7 +2266,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
hir::ExprUnary(hir::UnDeref, _) |
|
||||
hir::ExprField(..) |
|
||||
hir::ExprTupField(..) |
|
||||
hir::ExprIndex(..) => {
|
||||
true
|
||||
}
|
||||
|
@ -3084,6 +3083,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
private_candidate = Some((base_def.did, field_ty));
|
||||
}
|
||||
}
|
||||
ty::TyTuple(ref tys) => {
|
||||
let fstr = field.node.as_str();
|
||||
if let Ok(index) = fstr.parse::<usize>() {
|
||||
if fstr == index.to_string() {
|
||||
if let Some(field_ty) = tys.get(index) {
|
||||
let adjustments = autoderef.adjust_steps(needs);
|
||||
self.apply_adjustments(base, adjustments);
|
||||
autoderef.finalize();
|
||||
|
||||
return field_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -3189,78 +3202,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
display
|
||||
}
|
||||
|
||||
// Check tuple index expressions
|
||||
fn check_tup_field(&self,
|
||||
expr: &'gcx hir::Expr,
|
||||
needs: Needs,
|
||||
base: &'gcx hir::Expr,
|
||||
idx: codemap::Spanned<usize>) -> Ty<'tcx> {
|
||||
let expr_t = self.check_expr_with_needs(base, needs);
|
||||
let expr_t = self.structurally_resolved_type(expr.span,
|
||||
expr_t);
|
||||
let mut private_candidate = None;
|
||||
let mut tuple_like = false;
|
||||
let mut autoderef = self.autoderef(expr.span, expr_t);
|
||||
while let Some((base_t, _)) = autoderef.next() {
|
||||
let field = match base_t.sty {
|
||||
ty::TyAdt(base_def, substs) if base_def.is_struct() => {
|
||||
tuple_like = base_def.non_enum_variant().ctor_kind == CtorKind::Fn;
|
||||
if !tuple_like { continue }
|
||||
|
||||
debug!("tuple struct named {:?}", base_t);
|
||||
let ident =
|
||||
ast::Ident::new(Symbol::intern(&idx.node.to_string()), idx.span.modern());
|
||||
let (ident, def_scope) =
|
||||
self.tcx.adjust_ident(ident, base_def.did, self.body_id);
|
||||
let fields = &base_def.non_enum_variant().fields;
|
||||
if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
|
||||
let field_ty = self.field_ty(expr.span, field, substs);
|
||||
if field.vis.is_accessible_from(def_scope, self.tcx) {
|
||||
self.tcx.check_stability(field.did, Some(expr.id), expr.span);
|
||||
Some(field_ty)
|
||||
} else {
|
||||
private_candidate = Some((base_def.did, field_ty));
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ty::TyTuple(ref v) => {
|
||||
tuple_like = true;
|
||||
v.get(idx.node).cloned()
|
||||
}
|
||||
_ => continue
|
||||
};
|
||||
|
||||
if let Some(field_ty) = field {
|
||||
let adjustments = autoderef.adjust_steps(needs);
|
||||
self.apply_adjustments(base, adjustments);
|
||||
autoderef.finalize();
|
||||
return field_ty;
|
||||
}
|
||||
}
|
||||
autoderef.unambiguous_final_ty();
|
||||
|
||||
if let Some((did, field_ty)) = private_candidate {
|
||||
let struct_path = self.tcx().item_path_str(did);
|
||||
struct_span_err!(self.tcx().sess, expr.span, E0611,
|
||||
"field `{}` of tuple-struct `{}` is private",
|
||||
idx.node, struct_path).emit();
|
||||
return field_ty;
|
||||
}
|
||||
|
||||
if tuple_like {
|
||||
type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
|
||||
"attempted out-of-bounds tuple index `{}` on type `{}`",
|
||||
idx.node, expr_t).emit();
|
||||
} else {
|
||||
self.no_such_field_err(expr.span, idx.node, expr_t).emit();
|
||||
}
|
||||
|
||||
self.tcx().types.err
|
||||
}
|
||||
|
||||
fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
|
||||
-> DiagnosticBuilder {
|
||||
type_error_struct!(self.tcx().sess, span, expr_t, E0609,
|
||||
|
@ -4121,9 +4062,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
hir::ExprField(ref base, ref field) => {
|
||||
self.check_field(expr, needs, &base, field)
|
||||
}
|
||||
hir::ExprTupField(ref base, idx) => {
|
||||
self.check_tup_field(expr, needs, &base, idx)
|
||||
}
|
||||
hir::ExprIndex(ref base, ref idx) => {
|
||||
let base_t = self.check_expr_with_needs(&base, needs);
|
||||
let idx_t = self.check_expr(&idx);
|
||||
|
|
|
@ -4138,86 +4138,6 @@ https://doc.rust-lang.org/book/first-edition/primitive-types.html
|
|||
https://doc.rust-lang.org/book/first-edition/structs.html
|
||||
"##,
|
||||
|
||||
E0611: r##"
|
||||
Attempted to access a private field on a tuple-struct.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0611
|
||||
mod some_module {
|
||||
pub struct Foo(u32);
|
||||
|
||||
impl Foo {
|
||||
pub fn new() -> Foo { Foo(0) }
|
||||
}
|
||||
}
|
||||
|
||||
let y = some_module::Foo::new();
|
||||
println!("{}", y.0); // error: field `0` of tuple-struct `some_module::Foo`
|
||||
// is private
|
||||
```
|
||||
|
||||
Since the field is private, you have two solutions:
|
||||
|
||||
1) Make the field public:
|
||||
|
||||
```
|
||||
mod some_module {
|
||||
pub struct Foo(pub u32); // The field is now public.
|
||||
|
||||
impl Foo {
|
||||
pub fn new() -> Foo { Foo(0) }
|
||||
}
|
||||
}
|
||||
|
||||
let y = some_module::Foo::new();
|
||||
println!("{}", y.0); // So we can access it directly.
|
||||
```
|
||||
|
||||
2) Add a getter function to keep the field private but allow for accessing its
|
||||
value:
|
||||
|
||||
```
|
||||
mod some_module {
|
||||
pub struct Foo(u32);
|
||||
|
||||
impl Foo {
|
||||
pub fn new() -> Foo { Foo(0) }
|
||||
|
||||
// We add the getter function.
|
||||
pub fn get(&self) -> &u32 { &self.0 }
|
||||
}
|
||||
}
|
||||
|
||||
let y = some_module::Foo::new();
|
||||
println!("{}", y.get()); // So we can get the value through the function.
|
||||
```
|
||||
"##,
|
||||
|
||||
E0612: r##"
|
||||
Attempted out-of-bounds tuple index.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0612
|
||||
struct Foo(u32);
|
||||
|
||||
let y = Foo(0);
|
||||
println!("{}", y.1); // error: attempted out-of-bounds tuple index `1`
|
||||
// on type `Foo`
|
||||
```
|
||||
|
||||
If a tuple/tuple-struct type has n fields, you can only try to access these n
|
||||
fields from 0 to (n - 1). So in this case, you can only index `0`. Example:
|
||||
|
||||
```
|
||||
struct Foo(u32);
|
||||
|
||||
let y = Foo(0);
|
||||
println!("{}", y.0); // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0614: r##"
|
||||
Attempted to dereference a variable which cannot be dereferenced.
|
||||
|
||||
|
@ -4839,6 +4759,8 @@ register_diagnostics! {
|
|||
E0587, // type has conflicting packed and align representation hints
|
||||
E0588, // packed type cannot transitively contain a `[repr(align)]` type
|
||||
E0592, // duplicate definitions with name `{}`
|
||||
// E0611, // merged into E0616
|
||||
// E0612, // merged into E0609
|
||||
// E0613, // Removed (merged with E0609)
|
||||
E0640, // infer outlives
|
||||
E0627, // yield statement outside of generator literal
|
||||
|
|
|
@ -1018,7 +1018,6 @@ impl Expr {
|
|||
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
||||
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
||||
ExprKind::Field(..) => ExprPrecedence::Field,
|
||||
ExprKind::TupField(..) => ExprPrecedence::TupField,
|
||||
ExprKind::Index(..) => ExprPrecedence::Index,
|
||||
ExprKind::Range(..) => ExprPrecedence::Range,
|
||||
ExprKind::Path(..) => ExprPrecedence::Path,
|
||||
|
@ -1133,12 +1132,8 @@ pub enum ExprKind {
|
|||
///
|
||||
/// For example, `a += 1`.
|
||||
AssignOp(BinOp, P<Expr>, P<Expr>),
|
||||
/// Access of a named struct field (`obj.foo`)
|
||||
/// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct field
|
||||
Field(P<Expr>, Ident),
|
||||
/// Access of an unnamed field of a struct or tuple-struct
|
||||
///
|
||||
/// For example, `foo.0`.
|
||||
TupField(P<Expr>, Spanned<usize>),
|
||||
/// An indexing operation (`foo[2]`)
|
||||
Index(P<Expr>, P<Expr>),
|
||||
/// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
|
||||
|
|
|
@ -636,8 +636,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp)))
|
||||
}
|
||||
fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> {
|
||||
let id = Spanned { node: idx, span: sp };
|
||||
self.expr(sp, ast::ExprKind::TupField(expr, id))
|
||||
let id = Spanned { node: Ident::from_str(&idx.to_string()), span: sp };
|
||||
self.expr(sp, ast::ExprKind::Field(expr, id))
|
||||
}
|
||||
fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
|
||||
self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Immutable, e))
|
||||
|
|
|
@ -1267,11 +1267,6 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
|
|||
ExprKind::Field(el, ident) => {
|
||||
ExprKind::Field(folder.fold_expr(el), folder.fold_ident(ident))
|
||||
}
|
||||
ExprKind::TupField(el, index) => {
|
||||
ExprKind::TupField(folder.fold_expr(el),
|
||||
respan(folder.new_span(index.span),
|
||||
folder.fold_usize(index.node)))
|
||||
}
|
||||
ExprKind::Index(el, er) => {
|
||||
ExprKind::Index(folder.fold_expr(el), folder.fold_expr(er))
|
||||
}
|
||||
|
|
|
@ -2144,10 +2144,6 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mk_tup_field(&mut self, expr: P<Expr>, idx: codemap::Spanned<usize>) -> ast::ExprKind {
|
||||
ExprKind::TupField(expr, idx)
|
||||
}
|
||||
|
||||
pub fn mk_assign_op(&mut self, binop: ast::BinOp,
|
||||
lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
|
||||
ExprKind::AssignOp(binop, lhs, rhs)
|
||||
|
@ -2605,35 +2601,12 @@ impl<'a> Parser<'a> {
|
|||
token::Ident(..) => {
|
||||
e = self.parse_dot_suffix(e, lo)?;
|
||||
}
|
||||
token::Literal(token::Integer(index_ident), suf) => {
|
||||
let sp = self.span;
|
||||
|
||||
// A tuple index may not have a suffix
|
||||
self.expect_no_suffix(sp, "tuple index", suf);
|
||||
|
||||
let idx_span = self.span;
|
||||
token::Literal(token::Integer(name), _) => {
|
||||
let span = self.span;
|
||||
self.bump();
|
||||
|
||||
let invalid_msg = "invalid tuple or struct index";
|
||||
|
||||
let index = index_ident.as_str().parse::<usize>().ok();
|
||||
match index {
|
||||
Some(n) => {
|
||||
if n.to_string() != index_ident.as_str() {
|
||||
let mut err = self.struct_span_err(self.prev_span, invalid_msg);
|
||||
err.span_suggestion(self.prev_span,
|
||||
"try simplifying the index",
|
||||
n.to_string());
|
||||
err.emit();
|
||||
}
|
||||
let field = self.mk_tup_field(e, respan(idx_span, n));
|
||||
e = self.mk_expr(lo.to(idx_span), field, ThinVec::new());
|
||||
}
|
||||
None => {
|
||||
let prev_span = self.prev_span;
|
||||
self.span_err(prev_span, invalid_msg);
|
||||
}
|
||||
}
|
||||
let ident = Ident { name, ctxt: span.ctxt() };
|
||||
let field = ExprKind::Field(e, respan(span, ident));
|
||||
e = self.mk_expr(lo.to(span), field, ThinVec::new());
|
||||
}
|
||||
token::Literal(token::Float(n), _suf) => {
|
||||
self.bump();
|
||||
|
|
|
@ -1966,8 +1966,7 @@ impl<'a> State<'a> {
|
|||
args: &[P<ast::Expr>]) -> io::Result<()> {
|
||||
let prec =
|
||||
match func.node {
|
||||
ast::ExprKind::Field(..) |
|
||||
ast::ExprKind::TupField(..) => parser::PREC_FORCE_PAREN,
|
||||
ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
|
||||
_ => parser::PREC_POSTFIX,
|
||||
};
|
||||
|
||||
|
@ -2203,11 +2202,6 @@ impl<'a> State<'a> {
|
|||
self.s.word(".")?;
|
||||
self.print_ident(ident)?;
|
||||
}
|
||||
ast::ExprKind::TupField(ref expr, id) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
||||
self.s.word(".")?;
|
||||
self.print_usize(id.node)?;
|
||||
}
|
||||
ast::ExprKind::Index(ref expr, ref index) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
|
||||
self.s.word("[")?;
|
||||
|
|
|
@ -251,7 +251,6 @@ pub enum ExprPrecedence {
|
|||
Call,
|
||||
MethodCall,
|
||||
Field,
|
||||
TupField,
|
||||
Index,
|
||||
Try,
|
||||
InlineAsm,
|
||||
|
@ -320,7 +319,6 @@ impl ExprPrecedence {
|
|||
ExprPrecedence::Call |
|
||||
ExprPrecedence::MethodCall |
|
||||
ExprPrecedence::Field |
|
||||
ExprPrecedence::TupField |
|
||||
ExprPrecedence::Index |
|
||||
ExprPrecedence::Try |
|
||||
ExprPrecedence::InlineAsm |
|
||||
|
@ -365,7 +363,6 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
|
|||
ast::ExprKind::Cast(ref x, _) |
|
||||
ast::ExprKind::Type(ref x, _) |
|
||||
ast::ExprKind::Field(ref x, _) |
|
||||
ast::ExprKind::TupField(ref x, _) |
|
||||
ast::ExprKind::Index(ref x, _) => {
|
||||
// &X { y: 1 }, X { y: 1 }.y
|
||||
contains_exterior_struct_lit(&x)
|
||||
|
|
|
@ -749,9 +749,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
|||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ident(ident);
|
||||
}
|
||||
ExprKind::TupField(ref subexpression, _) => {
|
||||
visitor.visit_expr(subexpression);
|
||||
}
|
||||
ExprKind::Index(ref main_expression, ref index_expression) => {
|
||||
visitor.visit_expr(main_expression);
|
||||
visitor.visit_expr(index_expression)
|
||||
|
|
|
@ -12,5 +12,5 @@ const TUP: (usize,) = (42,);
|
|||
|
||||
fn main() {
|
||||
let a: [isize; TUP.1];
|
||||
//~^ ERROR attempted out-of-bounds tuple index
|
||||
//~^ ERROR no field `1` on type `(usize,)`
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B, z: inner::Z) {
|
|||
e.b; //~ ERROR: field `b` of struct `xc::B` is private
|
||||
|
||||
z.0;
|
||||
z.1; //~ ERROR: field `1` of tuple-struct `inner::Z` is private
|
||||
z.1; //~ ERROR: field `1` of struct `inner::Z` is private
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -15,10 +15,10 @@ fn main() {
|
|||
origin.0;
|
||||
origin.1;
|
||||
origin.2;
|
||||
//~^ ERROR attempted out-of-bounds tuple index `2` on type `Point`
|
||||
//~^ ERROR no field `2` on type `Point`
|
||||
let tuple = (0, 0);
|
||||
tuple.0;
|
||||
tuple.1;
|
||||
tuple.2;
|
||||
//~^ ERROR attempted out-of-bounds tuple index `2` on type `({integer}, {integer})`
|
||||
//~^ ERROR no field `2` on type `({integer}, {integer})`
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ LL | let _ = x.foo; //~ ERROR E0609
|
|||
= note: available fields are: `x`
|
||||
|
||||
error[E0609]: no field `1` on type `Bar`
|
||||
--> $DIR/E0609.rs:21:5
|
||||
--> $DIR/E0609.rs:21:7
|
||||
|
|
||||
LL | y.1; //~ ERROR E0609
|
||||
| ^^^
|
||||
| ^ unknown field
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
error[E0611]: field `0` of tuple-struct `a::Foo` is private
|
||||
--> $DIR/E0611.rs:21:4
|
||||
|
|
||||
LL | y.0; //~ ERROR E0611
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0611`.
|
|
@ -1,9 +0,0 @@
|
|||
error[E0612]: attempted out-of-bounds tuple index `1` on type `Foo`
|
||||
--> $DIR/E0612.rs:15:4
|
||||
|
|
||||
LL | y.1; //~ ERROR E0612
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0612`.
|
|
@ -18,5 +18,5 @@ mod a {
|
|||
|
||||
fn main() {
|
||||
let y = a::Foo::new();
|
||||
y.0; //~ ERROR E0611
|
||||
y.0; //~ ERROR field `0` of struct `a::Foo` is private
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
error[E0616]: field `0` of struct `a::Foo` is private
|
||||
--> $DIR/ex-E0611.rs:21:4
|
||||
|
|
||||
LL | y.0; //~ ERROR field `0` of struct `a::Foo` is private
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0616`.
|
|
@ -12,5 +12,5 @@ struct Foo(u32);
|
|||
|
||||
fn main() {
|
||||
let y = Foo(0);
|
||||
y.1; //~ ERROR E0612
|
||||
y.1; //~ ERROR no field `1` on type `Foo`
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
error[E0609]: no field `1` on type `Foo`
|
||||
--> $DIR/ex-E0612.rs:15:6
|
||||
|
|
||||
LL | y.1; //~ ERROR no field `1` on type `Foo`
|
||||
| ^ did you mean `0`?
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
|
@ -16,7 +16,7 @@ struct Verdict(Guilty, Option<FineDollars>);
|
|||
fn main() {
|
||||
let justice = Verdict(true, Some(2718));
|
||||
let _condemned = justice.00;
|
||||
//~^ ERROR invalid tuple or struct index
|
||||
//~^ ERROR no field `00` on type `Verdict`
|
||||
let _punishment = justice.001;
|
||||
//~^ ERROR invalid tuple or struct index
|
||||
//~^ ERROR no field `001` on type `Verdict`
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
error: invalid tuple or struct index
|
||||
error[E0609]: no field `00` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:18:30
|
||||
|
|
||||
LL | let _condemned = justice.00;
|
||||
| ^^ help: try simplifying the index: `0`
|
||||
| ^^ did you mean `0`?
|
||||
|
||||
error: invalid tuple or struct index
|
||||
error[E0609]: no field `001` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:20:31
|
||||
|
|
||||
LL | let _punishment = justice.001;
|
||||
| ^^^ help: try simplifying the index: `1`
|
||||
| ^^^ unknown field
|
||||
|
|
||||
= note: available fields are: `0`, `1`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
||||
|
|
|
@ -24,7 +24,7 @@ macro_rules! fake_field_stmt {
|
|||
|
||||
macro_rules! fake_anon_field_stmt {
|
||||
() => {
|
||||
(1).0 //~ ERROR no field
|
||||
(1).0 //~ ERROR doesn't have fields
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ macro_rules! fake_field_expr {
|
|||
|
||||
macro_rules! fake_anon_field_expr {
|
||||
() => {
|
||||
(1).0 //~ ERROR no field
|
||||
(1).0 //~ ERROR doesn't have fields
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ LL | 1.fake //~ ERROR doesn't have fields
|
|||
LL | fake_field_stmt!();
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
error[E0609]: no field `0` on type `{integer}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:27:11
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:27:15
|
||||
|
|
||||
LL | (1).0 //~ ERROR no field
|
||||
| ^^^^^
|
||||
LL | (1).0 //~ ERROR doesn't have fields
|
||||
| ^
|
||||
...
|
||||
LL | fake_anon_field_stmt!();
|
||||
| ------------------------ in this macro invocation
|
||||
|
@ -56,11 +56,11 @@ LL | 1.fake //~ ERROR doesn't have fields
|
|||
LL | let _ = fake_field_expr!();
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
error[E0609]: no field `0` on type `{integer}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:45:11
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:45:15
|
||||
|
|
||||
LL | (1).0 //~ ERROR no field
|
||||
| ^^^^^
|
||||
LL | (1).0 //~ ERROR doesn't have fields
|
||||
| ^
|
||||
...
|
||||
LL | let _ = fake_anon_field_expr!();
|
||||
| ----------------------- in this macro invocation
|
||||
|
@ -80,5 +80,5 @@ LL | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous n
|
|||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors occurred: E0599, E0609, E0610, E0689.
|
||||
Some errors occurred: E0599, E0610, E0689.
|
||||
For more information about an error, try `rustc --explain E0599`.
|
||||
|
|
Loading…
Reference in New Issue