1
Fork 0

Improve spans for indexing expressions

Indexing is similar to method calls in having an arbitrary
left-hand-side and then something on the right, which is the main part
of the expression. Method calls already have a span for that right part,
but indexing does not. This means that long method chains that use
indexing have really bad spans, especially when the indexing panics and
that span in coverted into a panic location.

This does the same thing as method calls for the AST and HIR, storing an
extra span which is then put into the `fn_span` field in THIR.
This commit is contained in:
Nilstrieb 2023-08-03 21:43:17 +02:00
parent fcf3006e01
commit 5706be1854
82 changed files with 192 additions and 149 deletions

View file

@ -1462,7 +1462,8 @@ pub enum ExprKind {
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field. /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
Field(P<Expr>, Ident), Field(P<Expr>, Ident),
/// An indexing operation (e.g., `foo[2]`). /// An indexing operation (e.g., `foo[2]`).
Index(P<Expr>, P<Expr>), /// The span represents the span of the `[2]`, including brackets.
Index(P<Expr>, P<Expr>, Span),
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment). /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits), Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
/// An underscore, used in destructuring assignment to ignore a value. /// An underscore, used in destructuring assignment to ignore a value.

View file

@ -1400,7 +1400,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
fn_decl, fn_decl,
body, body,
fn_decl_span, fn_decl_span,
fn_arg_span: _, fn_arg_span,
}) => { }) => {
vis.visit_closure_binder(binder); vis.visit_closure_binder(binder);
visit_constness(constness, vis); visit_constness(constness, vis);
@ -1408,6 +1408,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_fn_decl(fn_decl); vis.visit_fn_decl(fn_decl);
vis.visit_expr(body); vis.visit_expr(body);
vis.visit_span(fn_decl_span); vis.visit_span(fn_decl_span);
vis.visit_span(fn_arg_span);
} }
ExprKind::Block(blk, label) => { ExprKind::Block(blk, label) => {
vis.visit_block(blk); vis.visit_block(blk);
@ -1420,9 +1421,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(expr); vis.visit_expr(expr);
vis.visit_span(await_kw_span); vis.visit_span(await_kw_span);
} }
ExprKind::Assign(el, er, _) => { ExprKind::Assign(el, er, span) => {
vis.visit_expr(el); vis.visit_expr(el);
vis.visit_expr(er); vis.visit_expr(er);
vis.visit_span(span);
} }
ExprKind::AssignOp(_op, el, er) => { ExprKind::AssignOp(_op, el, er) => {
vis.visit_expr(el); vis.visit_expr(el);
@ -1432,9 +1434,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(el); vis.visit_expr(el);
vis.visit_ident(ident); vis.visit_ident(ident);
} }
ExprKind::Index(el, er) => { ExprKind::Index(el, er, brackets_span) => {
vis.visit_expr(el); vis.visit_expr(el);
vis.visit_expr(er); vis.visit_expr(er);
vis.visit_span(brackets_span);
} }
ExprKind::Range(e1, e2, _lim) => { ExprKind::Range(e1, e2, _lim) => {
visit_opt(e1, |e1| vis.visit_expr(e1)); visit_opt(e1, |e1| vis.visit_expr(e1));

View file

@ -390,7 +390,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
| ast::ExprKind::Cast(x, _) | ast::ExprKind::Cast(x, _)
| ast::ExprKind::Type(x, _) | ast::ExprKind::Type(x, _)
| ast::ExprKind::Field(x, _) | ast::ExprKind::Field(x, _)
| ast::ExprKind::Index(x, _) => { | ast::ExprKind::Index(x, _, _) => {
// &X { y: 1 }, X { y: 1 }.y // &X { y: 1 }, X { y: 1 }.y
contains_exterior_struct_lit(x) contains_exterior_struct_lit(x)
} }

View file

@ -885,7 +885,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
visitor.visit_ident(*ident); visitor.visit_ident(*ident);
} }
ExprKind::Index(main_expression, index_expression) => { ExprKind::Index(main_expression, index_expression, _) => {
visitor.visit_expr(main_expression); visitor.visit_expr(main_expression);
visitor.visit_expr(index_expression) visitor.visit_expr(index_expression)
} }

View file

@ -240,8 +240,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Field(el, ident) => { ExprKind::Field(el, ident) => {
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident)) hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident))
} }
ExprKind::Index(el, er) => { ExprKind::Index(el, er, brackets_span) => {
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er)) hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
} }
ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => { ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
self.lower_expr_range_closed(e.span, e1, e2) self.lower_expr_range_closed(e.span, e1, e2)

View file

@ -477,7 +477,7 @@ impl<'a> State<'a> {
self.word("."); self.word(".");
self.print_ident(*ident); self.print_ident(*ident);
} }
ast::ExprKind::Index(expr, index) => { ast::ExprKind::Index(expr, index, _) => {
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.word("["); self.word("[");
self.print_expr(index); self.print_expr(index);

View file

@ -79,7 +79,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
| hir::ExprKind::Unary(hir::UnOp::Deref, inner) | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
| hir::ExprKind::Field(inner, _) | hir::ExprKind::Field(inner, _)
| hir::ExprKind::MethodCall(_, inner, _, _) | hir::ExprKind::MethodCall(_, inner, _, _)
| hir::ExprKind::Index(inner, _) = &expr.kind | hir::ExprKind::Index(inner, _, _) = &expr.kind
{ {
expr = inner; expr = inner;
} }

View file

@ -567,7 +567,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
}; };
if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
&& let hir::ExprKind::Index(val, index) = place.kind && let hir::ExprKind::Index(val, index, _) = place.kind
&& (expr.span == self.assign_span || place.span == self.assign_span) && (expr.span == self.assign_span || place.span == self.assign_span)
{ {
// val[index] = rv; // val[index] = rv;
@ -620,7 +620,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
); );
self.suggested = true; self.suggested = true;
} else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind } else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
&& let hir::ExprKind::Index(val, index) = receiver.kind && let hir::ExprKind::Index(val, index, _) = receiver.kind
&& expr.span == self.assign_span && expr.span == self.assign_span
{ {
// val[index].path(args..); // val[index].path(args..);

View file

@ -237,7 +237,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
ExprKind::If(local_expr, _, _) => { ExprKind::If(local_expr, _, _) => {
self.manage_cond_expr(local_expr); self.manage_cond_expr(local_expr);
} }
ExprKind::Index(prefix, suffix) => { ExprKind::Index(prefix, suffix, _) => {
self.manage_cond_expr(prefix); self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix); self.manage_cond_expr(suffix);
} }

View file

@ -1754,7 +1754,7 @@ impl Expr<'_> {
ExprKind::Unary(UnOp::Deref, _) => true, ExprKind::Unary(UnOp::Deref, _) => true,
ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _) => { ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
allow_projections_from(base) || base.is_place_expr(allow_projections_from) allow_projections_from(base) || base.is_place_expr(allow_projections_from)
} }
@ -1831,7 +1831,7 @@ impl Expr<'_> {
ExprKind::Type(base, _) ExprKind::Type(base, _)
| ExprKind::Unary(_, base) | ExprKind::Unary(_, base)
| ExprKind::Field(base, _) | ExprKind::Field(base, _)
| ExprKind::Index(base, _) | ExprKind::Index(base, _, _)
| ExprKind::AddrOf(.., base) | ExprKind::AddrOf(.., base)
| ExprKind::Cast(base, _) => { | ExprKind::Cast(base, _) => {
// This isn't exactly true for `Index` and all `Unary`, but we are using this // This isn't exactly true for `Index` and all `Unary`, but we are using this
@ -2015,7 +2015,9 @@ pub enum ExprKind<'hir> {
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field. /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
Field(&'hir Expr<'hir>, Ident), Field(&'hir Expr<'hir>, Ident),
/// An indexing operation (`foo[2]`). /// An indexing operation (`foo[2]`).
Index(&'hir Expr<'hir>, &'hir Expr<'hir>), /// Similar to [`ExprKind::MethodCall`], the final `Span` represents the span of the brackets
/// and index.
Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
/// Path to a definition, possibly containing lifetime or type parameters. /// Path to a definition, possibly containing lifetime or type parameters.
Path(QPath<'hir>), Path(QPath<'hir>),

View file

@ -780,7 +780,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
visitor.visit_ident(ident); visitor.visit_ident(ident);
} }
ExprKind::Index(ref main_expression, ref index_expression) => { ExprKind::Index(ref main_expression, ref index_expression, _) => {
visitor.visit_expr(main_expression); visitor.visit_expr(main_expression);
visitor.visit_expr(index_expression) visitor.visit_expr(index_expression)
} }

View file

@ -1526,7 +1526,7 @@ impl<'a> State<'a> {
self.word("."); self.word(".");
self.print_ident(ident); self.print_ident(ident);
} }
hir::ExprKind::Index(expr, index) => { hir::ExprKind::Index(expr, index, _) => {
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.word("["); self.word("[");
self.print_expr(index); self.print_expr(index);
@ -2419,7 +2419,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
| hir::ExprKind::Cast(x, _) | hir::ExprKind::Cast(x, _)
| hir::ExprKind::Type(x, _) | hir::ExprKind::Type(x, _)
| hir::ExprKind::Field(x, _) | hir::ExprKind::Field(x, _)
| hir::ExprKind::Index(x, _) => { | hir::ExprKind::Index(x, _, _) => {
// `&X { y: 1 }, X { y: 1 }.y` // `&X { y: 1 }, X { y: 1 }.y`
contains_exterior_struct_lit(x) contains_exterior_struct_lit(x)
} }

View file

@ -345,7 +345,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.check_expr_struct(expr, expected, qpath, fields, base_expr) self.check_expr_struct(expr, expected, qpath, fields, base_expr)
} }
ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected), ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected),
ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr), ExprKind::Index(base, idx, brackets_span) => {
self.check_expr_index(base, idx, expr, brackets_span)
}
ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src), ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src),
hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar), hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar),
} }
@ -2840,6 +2842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base: &'tcx hir::Expr<'tcx>, base: &'tcx hir::Expr<'tcx>,
idx: &'tcx hir::Expr<'tcx>, idx: &'tcx hir::Expr<'tcx>,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
brackets_span: Span,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let base_t = self.check_expr(&base); let base_t = self.check_expr(&base);
let idx_t = self.check_expr(&idx); let idx_t = self.check_expr(&idx);
@ -2873,7 +2876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = type_error_struct!( let mut err = type_error_struct!(
self.tcx.sess, self.tcx.sess,
expr.span, brackets_span,
base_t, base_t,
E0608, E0608,
"cannot index into a value of type `{base_t}`", "cannot index into a value of type `{base_t}`",
@ -2887,16 +2890,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node && let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
&& i < types.len().try_into().expect("expected tuple index to be < usize length") && i < types.len().try_into().expect("expected tuple index to be < usize length")
{ {
let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
if let Ok(snip) = snip {
err.span_suggestion( err.span_suggestion(
expr.span, brackets_span,
"to access tuple elements, use", "to access tuple elements, use",
format!("{snip}.{i}"), format!(".{i}"),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
needs_note = false; needs_note = false;
}
} else if let ExprKind::Path(..) = idx.peel_borrows().kind { } else if let ExprKind::Path(..) = idx.peel_borrows().kind {
err.span_label(idx.span, "cannot access tuple elements at a variable index"); err.span_label(idx.span, "cannot access tuple elements at a variable index");
} }

View file

@ -211,7 +211,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.select_from_expr(base); self.select_from_expr(base);
} }
hir::ExprKind::Index(lhs, rhs) => { hir::ExprKind::Index(lhs, rhs, _) => {
// lhs[rhs] // lhs[rhs]
self.select_from_expr(lhs); self.select_from_expr(lhs);
self.consume_expr(rhs); self.consume_expr(rhs);

View file

@ -336,7 +336,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
)) ))
} }
hir::ExprKind::Index(ref base, _) => { hir::ExprKind::Index(ref base, _, _) => {
if self.typeck_results.is_method_call(expr) { if self.typeck_results.is_method_call(expr) {
// If this is an index implemented by a method call, then it // If this is an index implemented by a method call, then it
// will include an implicit deref of the result. // will include an implicit deref of the result.

View file

@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut exprs = vec![expr]; let mut exprs = vec![expr];
while let hir::ExprKind::Field(ref expr, _) while let hir::ExprKind::Field(ref expr, _)
| hir::ExprKind::Index(ref expr, _) | hir::ExprKind::Index(ref expr, _, _)
| hir::ExprKind::Unary(hir::UnOp::Deref, ref expr) = exprs.last().unwrap().kind | hir::ExprKind::Unary(hir::UnOp::Deref, ref expr) = exprs.last().unwrap().kind
{ {
exprs.push(expr); exprs.push(expr);

View file

@ -40,7 +40,7 @@ fn record_rvalue_scope_rec(
hir::ExprKind::AddrOf(_, _, subexpr) hir::ExprKind::AddrOf(_, _, subexpr)
| hir::ExprKind::Unary(hir::UnOp::Deref, subexpr) | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
| hir::ExprKind::Field(subexpr, _) | hir::ExprKind::Field(subexpr, _)
| hir::ExprKind::Index(subexpr, _) => { | hir::ExprKind::Index(subexpr, _, _) => {
expr = subexpr; expr = subexpr;
} }
_ => { _ => {

View file

@ -210,7 +210,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// to use builtin indexing because the index type is known to be // to use builtin indexing because the index type is known to be
// usize-ish // usize-ish
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) { fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
if let hir::ExprKind::Index(ref base, ref index) = e.kind { if let hir::ExprKind::Index(ref base, ref index, _) = e.kind {
// All valid indexing looks like this; might encounter non-valid indexes at this point. // All valid indexing looks like this; might encounter non-valid indexes at this point.
let base_ty = self.typeck_results.expr_ty_adjusted_opt(base); let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
if base_ty.is_none() { if base_ty.is_none() {

View file

@ -653,7 +653,7 @@ trait UnusedDelimLint {
ExprKind::Call(fn_, _params) => fn_, ExprKind::Call(fn_, _params) => fn_,
ExprKind::Cast(expr, _ty) => expr, ExprKind::Cast(expr, _ty) => expr,
ExprKind::Type(expr, _ty) => expr, ExprKind::Type(expr, _ty) => expr,
ExprKind::Index(base, _subscript) => base, ExprKind::Index(base, _subscript, _) => base,
_ => break, _ => break,
}; };
if !classify::expr_requires_semi_to_be_stmt(innermost) { if !classify::expr_requires_semi_to_be_stmt(innermost) {
@ -830,7 +830,7 @@ trait UnusedDelimLint {
(value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true) (value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true)
} }
Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false), Index(_, ref value, _) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
Assign(_, ref value, _) | AssignOp(.., ref value) => { Assign(_, ref value, _) | AssignOp(.., ref value) => {
(value, UnusedDelimsCtx::AssignedValue, false, None, None, false) (value, UnusedDelimsCtx::AssignedValue, false, None, None, false)

View file

@ -469,11 +469,17 @@ impl<'tcx> Cx<'tcx> {
} }
} }
hir::ExprKind::Index(ref lhs, ref index) => { hir::ExprKind::Index(ref lhs, ref index, brackets_span) => {
if self.typeck_results().is_method_call(expr) { if self.typeck_results().is_method_call(expr) {
let lhs = self.mirror_expr(lhs); let lhs = self.mirror_expr(lhs);
let index = self.mirror_expr(index); let index = self.mirror_expr(index);
self.overloaded_place(expr, expr_ty, None, Box::new([lhs, index]), expr.span) self.overloaded_place(
expr,
expr_ty,
None,
Box::new([lhs, index]),
brackets_span,
)
} else { } else {
ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) } ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
} }

View file

@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
let msg = format!( let msg = format!(
"cast cannot be followed by {}", "cast cannot be followed by {}",
match with_postfix.kind { match with_postfix.kind {
ExprKind::Index(_, _) => "indexing", ExprKind::Index(..) => "indexing",
ExprKind::Try(_) => "`?`", ExprKind::Try(_) => "`?`",
ExprKind::Field(_, _) => "a field access", ExprKind::Field(_, _) => "a field access",
ExprKind::MethodCall(_) => "a method call", ExprKind::MethodCall(_) => "a method call",
@ -1304,7 +1304,10 @@ impl<'a> Parser<'a> {
let index = self.parse_expr()?; let index = self.parse_expr()?;
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?; self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
self.expect(&token::CloseDelim(Delimiter::Bracket))?; self.expect(&token::CloseDelim(Delimiter::Bracket))?;
Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index))) Ok(self.mk_expr(
lo.to(self.prev_token.span),
self.mk_index(base, index, open_delim_span.to(self.prev_token.span)),
))
} }
/// Assuming we have just parsed `.`, continue parsing into an expression. /// Assuming we have just parsed `.`, continue parsing into an expression.
@ -3366,8 +3369,8 @@ impl<'a> Parser<'a> {
ExprKind::Binary(binop, lhs, rhs) ExprKind::Binary(binop, lhs, rhs)
} }
fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind { fn mk_index(&self, expr: P<Expr>, idx: P<Expr>, brackets_span: Span) -> ExprKind {
ExprKind::Index(expr, idx) ExprKind::Index(expr, idx, brackets_span)
} }
fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind { fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {

View file

@ -1061,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&l, ln) self.propagate_through_expr(&l, ln)
} }
hir::ExprKind::Index(ref l, ref r) | hir::ExprKind::Binary(_, ref l, ref r) => { hir::ExprKind::Index(ref l, ref r, _) | hir::ExprKind::Binary(_, ref l, ref r) => {
let r_succ = self.propagate_through_expr(&r, succ); let r_succ = self.propagate_through_expr(&r, succ);
self.propagate_through_expr(&l, r_succ) self.propagate_through_expr(&l, r_succ)
} }

View file

@ -4269,7 +4269,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ExprKind::ConstBlock(ref ct) => { ExprKind::ConstBlock(ref ct) => {
self.resolve_anon_const(ct, AnonConstKind::InlineConst); self.resolve_anon_const(ct, AnonConstKind::InlineConst);
} }
ExprKind::Index(ref elem, ref idx) => { ExprKind::Index(ref elem, ref idx, _) => {
self.resolve_expr(elem, Some(expr)); self.resolve_expr(elem, Some(expr));
self.visit_expr(idx); self.visit_expr(idx);
} }

View file

@ -2854,7 +2854,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.note("all local variables must have a statically known size"); err.note("all local variables must have a statically known size");
} }
Some(Node::Local(hir::Local { Some(Node::Local(hir::Local {
init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }), init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
.. ..
})) => { })) => {
// When encountering an assignment of an unsized trait, like // When encountering an assignment of an unsized trait, like

View file

@ -800,7 +800,7 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
&& parent.span.ctxt() == e.span.ctxt() && parent.span.ctxt() == e.span.ctxt()
{ {
match parent.kind { match parent.kind {
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _) ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
if child.hir_id == e.hir_id => true, if child.hir_id == e.hir_id => true,
ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true, ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
_ => false, _ => false,

View file

@ -221,7 +221,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool {
match e.kind { match e.kind {
Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)), Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),
Path(_) => true, Path(_) => true,
Field(inner, _) | Index(inner, _) => is_mutated_static(inner), Field(inner, _) | Index(inner, _, _) => is_mutated_static(inner),
_ => false, _ => false,
} }
} }

View file

@ -254,7 +254,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
// Checking for slice indexing // Checking for slice indexing
let parent_id = map.parent_id(expr.hir_id); let parent_id = map.parent_id(expr.hir_id);
if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id); if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id);
if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind; if let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind;
if let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr); if let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr);
if let Ok(index_value) = index_value.try_into(); if let Ok(index_value) = index_value.try_into();
if index_value < max_suggested_slice; if index_value < max_suggested_slice;

View file

@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
return; return;
} }
if let ExprKind::Index(array, index) = &expr.kind { if let ExprKind::Index(array, index, _) = &expr.kind {
let note = "the suggestion might not be applicable in constant blocks"; let note = "the suggestion might not be applicable in constant blocks";
let ty = cx.typeck_results().expr_ty(array).peel_refs(); let ty = cx.typeck_results().expr_ty(array).peel_refs();
if let Some(range) = higher::Range::hir(index) { if let Some(range) = higher::Range::hir(index) {

View file

@ -60,8 +60,8 @@ pub(super) fn check<'tcx>(
o.and_then(|(lhs, rhs)| { o.and_then(|(lhs, rhs)| {
let rhs = fetch_cloned_expr(rhs); let rhs = fetch_cloned_expr(rhs);
if_chain! { if_chain! {
if let ExprKind::Index(base_left, idx_left) = lhs.kind; if let ExprKind::Index(base_left, idx_left, _) = lhs.kind;
if let ExprKind::Index(base_right, idx_right) = rhs.kind; if let ExprKind::Index(base_right, idx_right, _) = rhs.kind;
if let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left)); if let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left));
if get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some(); if get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some();
if let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts); if let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts);

View file

@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
if_chain! { if_chain! {
// an index op // an index op
if let ExprKind::Index(seqexpr, idx) = expr.kind; if let ExprKind::Index(seqexpr, idx, _) = expr.kind;
if !self.check(idx, seqexpr, expr); if !self.check(idx, seqexpr, expr);
then { then {
return; return;

View file

@ -162,7 +162,7 @@ fn never_loop_expr<'tcx>(
ExprKind::Binary(_, e1, e2) ExprKind::Binary(_, e1, e2)
| ExprKind::Assign(e1, e2, _) | ExprKind::Assign(e1, e2, _)
| ExprKind::AssignOp(_, e1, e2) | ExprKind::AssignOp(_, e1, e2)
| ExprKind::Index(e1, e2) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id), | ExprKind::Index(e1, e2, _) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
ExprKind::Loop(b, _, _, _) => { ExprKind::Loop(b, _, _, _) => {
// Break can come from the inner loop so remove them. // Break can come from the inner loop so remove them.
absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id)) absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id))

View file

@ -113,7 +113,7 @@ fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExp
// Shouldn't have side effects, but there's no way to trace which field is used. So forget which fields have // Shouldn't have side effects, but there's no way to trace which field is used. So forget which fields have
// already been seen. // already been seen.
ExprKind::Index(base, idx) if !idx.can_have_side_effects() => { ExprKind::Index(base, idx, _) if !idx.can_have_side_effects() => {
can_move = false; can_move = false;
fields.clear(); fields.clear();
e = base; e = base;

View file

@ -204,7 +204,7 @@ fn find_stripping<'tcx>(
if_chain! { if_chain! {
if is_ref_str(self.cx, ex); if is_ref_str(self.cx, ex);
let unref = peel_ref(ex); let unref = peel_ref(ex);
if let ExprKind::Index(indexed, index) = &unref.kind; if let ExprKind::Index(indexed, index, _) = &unref.kind;
if let Some(higher::Range { start, end, .. }) = higher::Range::hir(index); if let Some(higher::Range { start, end, .. }) = higher::Range::hir(index);
if let ExprKind::Path(path) = &indexed.kind; if let ExprKind::Path(path) = &indexed.kind;
if self.cx.qpath_res(path, ex.hir_id) == self.target; if self.cx.qpath_res(path, ex.hir_id) == self.target;

View file

@ -12,7 +12,7 @@ use super::MATCH_ON_VEC_ITEMS;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
if_chain! { if_chain! {
if let Some(idx_expr) = is_vec_indexing(cx, scrutinee); if let Some(idx_expr) = is_vec_indexing(cx, scrutinee);
if let ExprKind::Index(vec, idx) = idx_expr.kind; if let ExprKind::Index(vec, idx, _) = idx_expr.kind;
then { then {
// FIXME: could be improved to suggest surrounding every pattern with Some(_), // FIXME: could be improved to suggest surrounding every pattern with Some(_),
@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
if_chain! { if_chain! {
if let ExprKind::Index(array, index) = expr.kind; if let ExprKind::Index(array, index, _) = expr.kind;
if is_vector(cx, array); if is_vector(cx, array);
if !is_full_range(cx, index); if !is_full_range(cx, index);

View file

@ -12,7 +12,7 @@ use super::FILTER_NEXT;
fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> { fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
match expr.kind { match expr.kind {
hir::ExprKind::Field(f, _) => path_to_local(f), hir::ExprKind::Field(f, _) => path_to_local(f),
hir::ExprKind::Index(recv, _) => path_to_local(recv), hir::ExprKind::Index(recv, _, _) => path_to_local(recv),
hir::ExprKind::Path(hir::QPath::Resolved( hir::ExprKind::Path(hir::QPath::Resolved(
_, _,
hir::Path { hir::Path {

View file

@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, cal
if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() { if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
// caller is a Slice // caller is a Slice
if_chain! { if_chain! {
if let hir::ExprKind::Index(caller_var, index_expr) = &caller_expr.kind; if let hir::ExprKind::Index(caller_var, index_expr, _) = &caller_expr.kind;
if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen }) if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
= higher::Range::hir(index_expr); = higher::Range::hir(index_expr);
if let hir::ExprKind::Lit(start_lit) = &start_expr.kind; if let hir::ExprKind::Lit(start_lit) = &start_expr.kind;

View file

@ -239,7 +239,7 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
| ExprKind::MethodCall(..) | ExprKind::MethodCall(..)
| ExprKind::Call(_, _) | ExprKind::Call(_, _)
| ExprKind::Assign(..) | ExprKind::Assign(..)
| ExprKind::Index(_, _) | ExprKind::Index(..)
| ExprKind::Repeat(_, _) | ExprKind::Repeat(_, _)
| ExprKind::Struct(_, _, _) => { | ExprKind::Struct(_, _, _) => {
walk_expr(vis, expr); walk_expr(vis, expr);

View file

@ -119,7 +119,7 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
| ExprKind::Call(i, _) | ExprKind::Call(i, _)
| ExprKind::Cast(i, _) | ExprKind::Cast(i, _)
| ExprKind::Type(i, _) | ExprKind::Type(i, _)
| ExprKind::Index(i, _) = inner.kind | ExprKind::Index(i, _, _) = inner.kind
{ {
if matches!( if matches!(
i.kind, i.kind,

View file

@ -160,7 +160,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
match peel_blocks(expr).kind { match peel_blocks(expr).kind {
ExprKind::Lit(..) | ExprKind::Closure { .. } => true, ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)), ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)),
ExprKind::Index(a, b) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b), ExprKind::Index(a, b, _) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)), ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)),
ExprKind::Repeat(inner, _) ExprKind::Repeat(inner, _)
| ExprKind::Cast(inner, _) | ExprKind::Cast(inner, _)
@ -263,7 +263,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
return None; return None;
} }
match expr.kind { match expr.kind {
ExprKind::Index(a, b) => Some(vec![a, b]), ExprKind::Index(a, b, _) => Some(vec![a, b]),
ExprKind::Binary(ref binop, a, b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => { ExprKind::Binary(ref binop, a, b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {
Some(vec![a, b]) Some(vec![a, b])
}, },

View file

@ -438,7 +438,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
dereferenced_expr = parent_expr; dereferenced_expr = parent_expr;
}, },
ExprKind::Index(e, _) if ptr::eq(&**e, cur_expr) => { ExprKind::Index(e, _, _) if ptr::eq(&**e, cur_expr) => {
// `e[i]` => desugared to `*Index::index(&e, i)`, // `e[i]` => desugared to `*Index::index(&e, i)`,
// meaning `e` must be referenced. // meaning `e` must be referenced.
// no need to go further up since a method call is involved now. // no need to go further up since a method call is involved now.

View file

@ -695,7 +695,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
} }
}, },
// Indexing is fine for currently supported types. // Indexing is fine for currently supported types.
ExprKind::Index(e, _) if e.hir_id == child_id => (), ExprKind::Index(e, _, _) if e.hir_id == child_id => (),
_ => set_skip_flag(), _ => set_skip_flag(),
}, },
_ => set_skip_flag(), _ => set_skip_flag(),

View file

@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
if_chain! { if_chain! {
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind; if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind;
if addressee.span.ctxt() == ctxt; if addressee.span.ctxt() == ctxt;
if let ExprKind::Index(indexed, range) = addressee.kind; if let ExprKind::Index(indexed, range, _) = addressee.kind;
if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull); if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
then { then {
let (expr_ty, expr_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(expr)); let (expr_ty, expr_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(expr));

View file

@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
); );
} }
}, },
ExprKind::Index(target, _idx) => { ExprKind::Index(target, _idx, _) => {
let e_ty = cx.typeck_results().expr_ty(target).peel_refs(); let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) { if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) {
span_lint( span_lint(
@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
// Find string::as_bytes // Find string::as_bytes
if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind; if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind;
if let ExprKind::Index(left, right) = args.kind; if let ExprKind::Index(left, right, _) = args.kind;
let (method_names, expressions, _) = method_calls(left, 1); let (method_names, expressions, _) = method_calls(left, 1);
if method_names.len() == 1; if method_names.len() == 1;
if expressions.len() == 1; if expressions.len() == 1;

View file

@ -572,7 +572,7 @@ fn ident_difference_expr_with_base_location(
| (AddrOf(_, _, _), AddrOf(_, _, _)) | (AddrOf(_, _, _), AddrOf(_, _, _))
| (Path(_, _), Path(_, _)) | (Path(_, _), Path(_, _))
| (Range(_, _, _), Range(_, _, _)) | (Range(_, _, _), Range(_, _, _))
| (Index(_, _), Index(_, _)) | (Index(_, _, _), Index(_, _, _))
| (Field(_, _), Field(_, _)) | (Field(_, _), Field(_, _))
| (AssignOp(_, _, _), AssignOp(_, _, _)) | (AssignOp(_, _, _), AssignOp(_, _, _))
| (Assign(_, _, _), Assign(_, _, _)) | (Assign(_, _, _), Assign(_, _, _))

View file

@ -86,8 +86,8 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
if !can_mut_borrow_both(cx, e1, e2) { if !can_mut_borrow_both(cx, e1, e2) {
if let ExprKind::Index(lhs1, idx1) = e1.kind if let ExprKind::Index(lhs1, idx1, _) = e1.kind
&& let ExprKind::Index(lhs2, idx2) = e2.kind && let ExprKind::Index(lhs2, idx2, _) = e2.kind
&& eq_expr_value(cx, lhs1, lhs2) && eq_expr_value(cx, lhs1, lhs2)
&& e1.span.ctxt() == ctxt && e1.span.ctxt() == ctxt
&& e2.span.ctxt() == ctxt && e2.span.ctxt() == ctxt

View file

@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Assign(target, ..) = &expr.kind { if let ExprKind::Assign(target, ..) = &expr.kind {
let mut base = target; let mut base = target;
while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind { while let ExprKind::Field(f, _) | ExprKind::Index(f, _, _) = &base.kind {
base = f; base = f;
} }
if is_temporary(base) && !is_adjusted(cx, base) { if is_temporary(base) && !is_adjusted(cx, base) {

View file

@ -103,11 +103,11 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &
// Fix #11100 // Fix #11100
&& tys.iter().all_equal() && tys.iter().all_equal()
&& let Some(locals) = (match first.kind { && let Some(locals) = (match first.kind {
ExprKind::Index(_, _) => elements ExprKind::Index(..) => elements
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, i_expr)| -> Option<&'tcx Expr<'tcx>> { .map(|(i, i_expr)| -> Option<&'tcx Expr<'tcx>> {
if let ExprKind::Index(lhs, index) = i_expr.kind if let ExprKind::Index(lhs, index, _) = i_expr.kind
&& let ExprKind::Lit(lit) = index.kind && let ExprKind::Lit(lit) = index.kind
&& let LitKind::Int(val, _) = lit.node && let LitKind::Int(val, _) = lit.node
{ {

View file

@ -526,7 +526,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
self.ident(field_name); self.ident(field_name);
self.expr(object); self.expr(object);
}, },
ExprKind::Index(object, index) => { ExprKind::Index(object, index, _) => {
bind!(self, object, index); bind!(self, object, index);
kind!("Index({object}, {index})"); kind!("Index({object}, {index})");
self.expr(object); self.expr(object);

View file

@ -88,7 +88,7 @@ impl VecPushSearcher {
let mut last_place = parent; let mut last_place = parent;
while let Some(parent) = get_parent_expr(cx, last_place) { while let Some(parent) = get_parent_expr(cx, last_place) {
if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..)) if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..))
|| matches!(parent.kind, ExprKind::Index(e, _) if e.hir_id == last_place.hir_id) || matches!(parent.kind, ExprKind::Index(e, _, _) if e.hir_id == last_place.hir_id)
{ {
last_place = parent; last_place = parent;
} else { } else {

View file

@ -178,7 +178,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r), (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
(Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re), (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
(Continue(ll), Continue(rl)) => eq_label(ll, rl), (Continue(ll), Continue(rl)) => eq_label(ll, rl),
(Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2), Index(r1, r2)) => eq_expr(l1, r1) && eq_expr(l2, r2), (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => eq_expr(l1, r1) && eq_expr(l2, r2),
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv), (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp), (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm), (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),

View file

@ -163,7 +163,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
) => (Pat::Str("unsafe"), Pat::Str("}")), ) => (Pat::Str("unsafe"), Pat::Str("}")),
ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")), ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)), ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)),
ExprKind::Index(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")), ExprKind::Index(e, _, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
ExprKind::Path(ref path) => qpath_search_pat(path), ExprKind::Path(ref path) => qpath_search_pat(path),
ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1), ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")), ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),

View file

@ -394,7 +394,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
} }
} }
}, },
ExprKind::Index(arr, index) => self.index(arr, index), ExprKind::Index(arr, index, _) => self.index(arr, index),
ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))), ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))),
ExprKind::Field(local_expr, ref field) => { ExprKind::Field(local_expr, ref field) => {
let result = self.expr(local_expr); let result = self.expr(local_expr);

View file

@ -185,7 +185,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
.type_dependent_def_id(e.hir_id) .type_dependent_def_id(e.hir_id)
.map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true)); .map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));
}, },
ExprKind::Index(_, e) => { ExprKind::Index(_, e, _) => {
let ty = self.cx.typeck_results().expr_ty_adjusted(e); let ty = self.cx.typeck_results().expr_ty_adjusted(e);
if is_copy(self.cx, ty) && !ty.is_ref() { if is_copy(self.cx, ty) && !ty.is_ref() {
self.eagerness |= NoChange; self.eagerness |= NoChange;

View file

@ -299,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
(&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => { (&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => {
l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp) l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp)
}, },
(&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri), (&ExprKind::Index(la, li, _), &ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
(&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => { (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r)) self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
}, },
@ -730,7 +730,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
self.hash_expr(e); self.hash_expr(e);
self.hash_name(f.name); self.hash_name(f.name);
}, },
ExprKind::Index(a, i) => { ExprKind::Index(a, i, _) => {
self.hash_expr(a); self.hash_expr(a);
self.hash_expr(i); self.hash_expr(i);
}, },

View file

@ -735,7 +735,7 @@ fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'
let mut result = vec![]; let mut result = vec![];
let root = loop { let root = loop {
match e.kind { match e.kind {
ExprKind::Index(ep, _) | ExprKind::Field(ep, _) => { ExprKind::Index(ep, _, _) | ExprKind::Field(ep, _) => {
result.push(e); result.push(e);
e = ep; e = ep;
}, },
@ -782,7 +782,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
return true; return true;
} }
}, },
(ExprKind::Index(_, i1), ExprKind::Index(_, i2)) => { (ExprKind::Index(_, i1, _), ExprKind::Index(_, i2, _)) => {
if !eq_expr_value(cx, i1, i2) { if !eq_expr_value(cx, i1, i2) {
return false; return false;
} }

View file

@ -31,7 +31,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
let certainty = match &expr.kind { let certainty = match &expr.kind {
ExprKind::Unary(_, expr) ExprKind::Unary(_, expr)
| ExprKind::Field(expr, _) | ExprKind::Field(expr, _)
| ExprKind::Index(expr, _) | ExprKind::Index(expr, _, _)
| ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr), | ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr),
ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))), ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),

View file

@ -329,7 +329,7 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
&& self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {}, && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (), ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (),
ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (), ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),
ExprKind::Index(base, _) ExprKind::Index(base, _, _)
if matches!( if matches!(
self.cx.typeck_results().expr_ty(base).peel_refs().kind(), self.cx.typeck_results().expr_ty(base).peel_refs().kind(),
ty::Slice(_) | ty::Array(..) ty::Slice(_) | ty::Array(..)
@ -629,7 +629,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
helper(typeck, true, arg, f)?; helper(typeck, true, arg, f)?;
} }
}, },
ExprKind::Index(borrowed, consumed) ExprKind::Index(borrowed, consumed, _)
| ExprKind::Assign(borrowed, consumed, _) | ExprKind::Assign(borrowed, consumed, _)
| ExprKind::AssignOp(_, borrowed, consumed) => { | ExprKind::AssignOp(_, borrowed, consumed) => {
helper(typeck, false, borrowed, f)?; helper(typeck, false, borrowed, f)?;

View file

@ -256,7 +256,7 @@ pub(crate) fn format_expr(
shape, shape,
SeparatorPlace::Back, SeparatorPlace::Back,
), ),
ast::ExprKind::Index(ref expr, ref index) => { ast::ExprKind::Index(ref expr, ref index, _) => {
rewrite_index(&**expr, &**index, context, shape) rewrite_index(&**expr, &**index, context, shape)
} }
ast::ExprKind::Repeat(ref expr, ref repeats) => rewrite_pair( ast::ExprKind::Repeat(ref expr, ref repeats) => rewrite_pair(
@ -1342,7 +1342,7 @@ pub(crate) fn is_simple_expr(expr: &ast::Expr) -> bool {
| ast::ExprKind::Field(ref expr, _) | ast::ExprKind::Field(ref expr, _)
| ast::ExprKind::Try(ref expr) | ast::ExprKind::Try(ref expr)
| ast::ExprKind::Unary(_, ref expr) => is_simple_expr(expr), | ast::ExprKind::Unary(_, ref expr) => is_simple_expr(expr),
ast::ExprKind::Index(ref lhs, ref rhs) => is_simple_expr(lhs) && is_simple_expr(rhs), ast::ExprKind::Index(ref lhs, ref rhs, _) => is_simple_expr(lhs) && is_simple_expr(rhs),
ast::ExprKind::Repeat(ref lhs, ref rhs) => { ast::ExprKind::Repeat(ref lhs, ref rhs) => {
is_simple_expr(lhs) && is_simple_expr(&*rhs.value) is_simple_expr(lhs) && is_simple_expr(&*rhs.value)
} }

View file

@ -594,7 +594,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
ast::ExprKind::AddrOf(_, _, ref expr) ast::ExprKind::AddrOf(_, _, ref expr)
| ast::ExprKind::Try(ref expr) | ast::ExprKind::Try(ref expr)
| ast::ExprKind::Unary(_, ref expr) | ast::ExprKind::Unary(_, ref expr)
| ast::ExprKind::Index(ref expr, _) | ast::ExprKind::Index(ref expr, _, _)
| ast::ExprKind::Cast(ref expr, _) => can_flatten_block_around_this(expr), | ast::ExprKind::Cast(ref expr, _) => can_flatten_block_around_this(expr),
_ => false, _ => false,
} }

View file

@ -441,7 +441,7 @@ pub(crate) fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
| ast::ExprKind::Assign(ref e, _, _) | ast::ExprKind::Assign(ref e, _, _)
| ast::ExprKind::AssignOp(_, ref e, _) | ast::ExprKind::AssignOp(_, ref e, _)
| ast::ExprKind::Field(ref e, _) | ast::ExprKind::Field(ref e, _)
| ast::ExprKind::Index(ref e, _) | ast::ExprKind::Index(ref e, _, _)
| ast::ExprKind::Range(Some(ref e), _, _) | ast::ExprKind::Range(Some(ref e), _, _)
| ast::ExprKind::Try(ref e) => left_most_sub_expr(e), | ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
_ => e, _ => e,
@ -479,7 +479,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
| ast::ExprKind::Match(..) => repr.contains('\n'), | ast::ExprKind::Match(..) => repr.contains('\n'),
ast::ExprKind::Paren(ref expr) ast::ExprKind::Paren(ref expr)
| ast::ExprKind::Binary(_, _, ref expr) | ast::ExprKind::Binary(_, _, ref expr)
| ast::ExprKind::Index(_, ref expr) | ast::ExprKind::Index(_, ref expr, _)
| ast::ExprKind::Unary(_, ref expr) | ast::ExprKind::Unary(_, ref expr)
| ast::ExprKind::Try(ref expr) | ast::ExprKind::Try(ref expr)
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr), | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),

View file

@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
const ENTRY_LIMIT: usize = 900; const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually. // FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1893; const ISSUES_ENTRY_LIMIT: usize = 1893;
const ROOT_ENTRY_LIMIT: usize = 873; const ROOT_ENTRY_LIMIT: usize = 866;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files "rs", // test source files

View file

@ -1,26 +1,26 @@
error[E0608]: cannot index into a value of type `Foo` error[E0608]: cannot index into a value of type `Foo`
--> $DIR/slice-2.rs:7:6 --> $DIR/slice-2.rs:7:7
| |
LL | &x[..]; LL | &x[..];
| ^^^^^ | ^^^^
error[E0608]: cannot index into a value of type `Foo` error[E0608]: cannot index into a value of type `Foo`
--> $DIR/slice-2.rs:8:6 --> $DIR/slice-2.rs:8:7
| |
LL | &x[Foo..]; LL | &x[Foo..];
| ^^^^^^^^ | ^^^^^^^
error[E0608]: cannot index into a value of type `Foo` error[E0608]: cannot index into a value of type `Foo`
--> $DIR/slice-2.rs:9:6 --> $DIR/slice-2.rs:9:7
| |
LL | &x[..Foo]; LL | &x[..Foo];
| ^^^^^^^^ | ^^^^^^^
error[E0608]: cannot index into a value of type `Foo` error[E0608]: cannot index into a value of type `Foo`
--> $DIR/slice-2.rs:10:6 --> $DIR/slice-2.rs:10:7
| |
LL | &x[Foo..Foo]; LL | &x[Foo..Foo];
| ^^^^^^^^^^^ | ^^^^^^^^^^
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
| |
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ----^^^----------- | ----^^^-----------
| | | | | ||
| | immutable borrow occurs here | | |immutable borrow occurs here
| | mutable borrow later used here
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here
| |
help: try adding a local storing this... help: try adding a local storing this...
--> $DIR/suggest-local-var-for-vector.rs:3:9 --> $DIR/suggest-local-var-for-vector.rs:3:9
@ -14,10 +14,10 @@ help: try adding a local storing this...
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^ | ^^^^^^^^^
help: ...and then using that local here help: ...and then using that local here
--> $DIR/suggest-local-var-for-vector.rs:3:5 --> $DIR/suggest-local-var-for-vector.rs:3:8
| |
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
| |
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ----^^^----------- | ----^^^-----------
| | | | | ||
| | immutable borrow occurs here | | |immutable borrow occurs here
| | mutable borrow later used here
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here
| |
help: try adding a local storing this... help: try adding a local storing this...
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9 --> $DIR/suggest-storing-local-var-for-vector.rs:3:9
@ -14,10 +14,10 @@ help: try adding a local storing this...
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^ | ^^^^^^^^^
help: ...and then using that local here help: ...and then using that local here
--> $DIR/suggest-storing-local-var-for-vector.rs:3:5 --> $DIR/suggest-storing-local-var-for-vector.rs:3:8
| |
LL | vec[vec.len() - 1] = 123; LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -50,42 +50,42 @@ error[E0502]: cannot borrow `i` as immutable because it is also borrowed as muta
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| --^---- | --^----
| | | | |||
| | immutable borrow occurs here | ||immutable borrow occurs here
| |mutable borrow later used here
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here
| |
help: try adding a local storing this... help: try adding a local storing this...
--> $DIR/two-phase-nonrecv-autoref.rs:132:7 --> $DIR/two-phase-nonrecv-autoref.rs:132:8
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| ^^^^ | ^^^
help: ...and then using that local here help: ...and then using that local here
--> $DIR/two-phase-nonrecv-autoref.rs:132:5 --> $DIR/two-phase-nonrecv-autoref.rs:132:6
| |
LL | i[i[3]] = 4; LL | i[i[3]] = 4;
| ^^^^^^^ | ^^^^^^
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:138:7 --> $DIR/two-phase-nonrecv-autoref.rs:138:7
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| --^---- | --^----
| | | | |||
| | immutable borrow occurs here | ||immutable borrow occurs here
| |mutable borrow later used here
| mutable borrow occurs here | mutable borrow occurs here
| mutable borrow later used here
| |
help: try adding a local storing this... help: try adding a local storing this...
--> $DIR/two-phase-nonrecv-autoref.rs:138:7 --> $DIR/two-phase-nonrecv-autoref.rs:138:8
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| ^^^^ | ^^^
help: ...and then using that local here help: ...and then using that local here
--> $DIR/two-phase-nonrecv-autoref.rs:138:5 --> $DIR/two-phase-nonrecv-autoref.rs:138:6
| |
LL | i[i[3]] = i[4]; LL | i[i[3]] = i[4];
| ^^^^^^^ | ^^^^^^
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -7,10 +7,10 @@ LL | self.bar[0] = baz.len();
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const operator in constant functions error[E0015]: cannot call non-const operator in constant functions
--> $DIR/issue-94675.rs:11:9 --> $DIR/issue-94675.rs:11:17
| |
LL | self.bar[0] = baz.len(); LL | self.bar[0] = baz.len();
| ^^^^^^^^^^^ | ^^^
| |
note: impl defined here, but it is not `const` note: impl defined here, but it is not `const`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL

View file

@ -1,8 +1,8 @@
error[E0608]: cannot index into a value of type `u8` error[E0608]: cannot index into a value of type `u8`
--> $DIR/E0608.rs:2:5 --> $DIR/E0608.rs:2:8
| |
LL | 0u8[2]; LL | 0u8[2];
| ^^^^^^ | ^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,8 +1,8 @@
error[E0608]: cannot index into a value of type `!` error[E0608]: cannot index into a value of type `!`
--> $DIR/index-bot.rs:2:5 --> $DIR/index-bot.rs:2:13
| |
LL | (return)[0]; LL | (return)[0];
| ^^^^^^^^^^^ | ^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,8 +1,8 @@
error[E0608]: cannot index into a value of type `({integer},)` error[E0608]: cannot index into a value of type `({integer},)`
--> $DIR/index_message.rs:3:13 --> $DIR/index_message.rs:3:14
| |
LL | let _ = z[0]; LL | let _ = z[0];
| ^^^^ help: to access tuple elements, use: `z.0` | ^^^ help: to access tuple elements, use: `.0`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,27 @@
// run-pass
// Regression test for https://github.com/rust-lang/rust/issues/114388
#[track_caller]
fn caller_line() -> u32 {
std::panic::Location::caller().line()
}
fn main() {
let prev_line = caller_line(); // first line
(A { prev_line }) // second line
[0]; // third line
}
struct A {
prev_line: u32,
}
impl std::ops::Index<usize> for A {
type Output = ();
fn index(&self, _idx: usize) -> &() {
// Use the relative number to make it resistent to header changes.
assert_eq!(caller_line(), self.prev_line + 2);
&()
}
}

View file

@ -1,3 +1,3 @@
thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:6: thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
byte index 1 is out of bounds of `` byte index 1 is out of bounds of ``
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

View file

@ -1,24 +1,24 @@
error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
--> $DIR/issue-27842.rs:4:13 --> $DIR/issue-27842.rs:4:16
| |
LL | let _ = tup[0]; LL | let _ = tup[0];
| ^^^^^^ help: to access tuple elements, use: `tup.0` | ^^^ help: to access tuple elements, use: `.0`
error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
--> $DIR/issue-27842.rs:9:13 --> $DIR/issue-27842.rs:9:16
| |
LL | let _ = tup[i]; LL | let _ = tup[i];
| ^^^^-^ | ^-^
| | | |
| cannot access tuple elements at a variable index | cannot access tuple elements at a variable index
| |
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
error[E0608]: cannot index into a value of type `({integer},)` error[E0608]: cannot index into a value of type `({integer},)`
--> $DIR/issue-27842.rs:14:13 --> $DIR/issue-27842.rs:14:16
| |
LL | let _ = tup[3]; LL | let _ = tup[3];
| ^^^^^^ | ^^^
| |
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)

View file

@ -1,8 +1,8 @@
error[E0608]: cannot index into a value of type `()` error[E0608]: cannot index into a value of type `()`
--> $DIR/issue-40861.rs:4:5 --> $DIR/issue-40861.rs:4:7
| |
LL | ()[f(&[1.0])]; LL | ()[f(&[1.0])];
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)

View file

@ -139,7 +139,7 @@ error: function cannot return without recursing
LL | fn index(&self, x: usize) -> &Baz { LL | fn index(&self, x: usize) -> &Baz {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL | &self[x] LL | &self[x]
| ------- recursive call site | --- recursive call site
| |
= help: a `loop` may express intention better if this is on purpose = help: a `loop` may express intention better if this is on purpose

View file

@ -1,8 +1,8 @@
error[E0608]: cannot index into a value of type `({integer},)` error[E0608]: cannot index into a value of type `({integer},)`
--> $DIR/suggestion-non-ascii.rs:3:21 --> $DIR/suggestion-non-ascii.rs:3:24
| |
LL | println!("☃{}", tup[0]); LL | println!("☃{}", tup[0]);
| ^^^^^^ help: to access tuple elements, use: `tup.0` | ^^^ help: to access tuple elements, use: `.0`
error: aborting due to previous error error: aborting due to previous error

View file

@ -38,10 +38,10 @@ LL | let _c = unsafe { _ptr2.offset_from(_ptr1) };
| ++++++++ ~~~~~~~~~~~~~ +++ | ++++++++ ~~~~~~~~~~~~~ +++
error[E0608]: cannot index into a value of type `*const u32` error[E0608]: cannot index into a value of type `*const u32`
--> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14 --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:19
| |
LL | let _d = _ptr1[5]; LL | let _d = _ptr1[5];
| ^^^^^^^^ | ^^^
| |
help: consider using `wrapping_add` or `add` for indexing into raw pointer help: consider using `wrapping_add` or `add` for indexing into raw pointer
| |