mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
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:
parent
fcf3006e01
commit
5706be1854
@ -1462,7 +1462,8 @@ pub enum ExprKind {
|
||||
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
|
||||
Field(P<Expr>, Ident),
|
||||
/// 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).
|
||||
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
|
||||
/// An underscore, used in destructuring assignment to ignore a value.
|
||||
|
@ -1400,7 +1400,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
fn_arg_span: _,
|
||||
fn_arg_span,
|
||||
}) => {
|
||||
vis.visit_closure_binder(binder);
|
||||
visit_constness(constness, vis);
|
||||
@ -1408,6 +1408,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
vis.visit_fn_decl(fn_decl);
|
||||
vis.visit_expr(body);
|
||||
vis.visit_span(fn_decl_span);
|
||||
vis.visit_span(fn_arg_span);
|
||||
}
|
||||
ExprKind::Block(blk, label) => {
|
||||
vis.visit_block(blk);
|
||||
@ -1420,9 +1421,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(await_kw_span);
|
||||
}
|
||||
ExprKind::Assign(el, er, _) => {
|
||||
ExprKind::Assign(el, er, span) => {
|
||||
vis.visit_expr(el);
|
||||
vis.visit_expr(er);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
ExprKind::AssignOp(_op, el, er) => {
|
||||
vis.visit_expr(el);
|
||||
@ -1432,9 +1434,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
vis.visit_expr(el);
|
||||
vis.visit_ident(ident);
|
||||
}
|
||||
ExprKind::Index(el, er) => {
|
||||
ExprKind::Index(el, er, brackets_span) => {
|
||||
vis.visit_expr(el);
|
||||
vis.visit_expr(er);
|
||||
vis.visit_span(brackets_span);
|
||||
}
|
||||
ExprKind::Range(e1, e2, _lim) => {
|
||||
visit_opt(e1, |e1| vis.visit_expr(e1));
|
||||
|
@ -390,7 +390,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
|
||||
| ast::ExprKind::Cast(x, _)
|
||||
| ast::ExprKind::Type(x, _)
|
||||
| ast::ExprKind::Field(x, _)
|
||||
| ast::ExprKind::Index(x, _) => {
|
||||
| ast::ExprKind::Index(x, _, _) => {
|
||||
// &X { y: 1 }, X { y: 1 }.y
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
@ -885,7 +885,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ident(*ident);
|
||||
}
|
||||
ExprKind::Index(main_expression, index_expression) => {
|
||||
ExprKind::Index(main_expression, index_expression, _) => {
|
||||
visitor.visit_expr(main_expression);
|
||||
visitor.visit_expr(index_expression)
|
||||
}
|
||||
|
@ -240,8 +240,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::Field(el, ident) => {
|
||||
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident))
|
||||
}
|
||||
ExprKind::Index(el, er) => {
|
||||
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
|
||||
ExprKind::Index(el, er, brackets_span) => {
|
||||
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
|
||||
}
|
||||
ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
|
||||
self.lower_expr_range_closed(e.span, e1, e2)
|
||||
|
@ -477,7 +477,7 @@ impl<'a> State<'a> {
|
||||
self.word(".");
|
||||
self.print_ident(*ident);
|
||||
}
|
||||
ast::ExprKind::Index(expr, index) => {
|
||||
ast::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
|
@ -79,7 +79,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, inner)
|
||||
| hir::ExprKind::Field(inner, _)
|
||||
| hir::ExprKind::MethodCall(_, inner, _, _)
|
||||
| hir::ExprKind::Index(inner, _) = &expr.kind
|
||||
| hir::ExprKind::Index(inner, _, _) = &expr.kind
|
||||
{
|
||||
expr = inner;
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
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)
|
||||
{
|
||||
// val[index] = rv;
|
||||
@ -620,7 +620,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
);
|
||||
self.suggested = true;
|
||||
} 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
|
||||
{
|
||||
// val[index].path(args..);
|
||||
|
@ -237,7 +237,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
||||
ExprKind::If(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(suffix);
|
||||
}
|
||||
|
@ -1754,7 +1754,7 @@ impl Expr<'_> {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1831,7 +1831,7 @@ impl Expr<'_> {
|
||||
ExprKind::Type(base, _)
|
||||
| ExprKind::Unary(_, base)
|
||||
| ExprKind::Field(base, _)
|
||||
| ExprKind::Index(base, _)
|
||||
| ExprKind::Index(base, _, _)
|
||||
| ExprKind::AddrOf(.., base)
|
||||
| ExprKind::Cast(base, _) => {
|
||||
// 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.
|
||||
Field(&'hir Expr<'hir>, Ident),
|
||||
/// 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(QPath<'hir>),
|
||||
|
@ -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_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(index_expression)
|
||||
}
|
||||
|
@ -1526,7 +1526,7 @@ impl<'a> State<'a> {
|
||||
self.word(".");
|
||||
self.print_ident(ident);
|
||||
}
|
||||
hir::ExprKind::Index(expr, index) => {
|
||||
hir::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
@ -2419,7 +2419,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
|
||||
| hir::ExprKind::Cast(x, _)
|
||||
| hir::ExprKind::Type(x, _)
|
||||
| hir::ExprKind::Field(x, _)
|
||||
| hir::ExprKind::Index(x, _) => {
|
||||
| hir::ExprKind::Index(x, _, _) => {
|
||||
// `&X { y: 1 }, X { y: 1 }.y`
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
@ -345,7 +345,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.check_expr_struct(expr, expected, qpath, fields, base_expr)
|
||||
}
|
||||
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),
|
||||
hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar),
|
||||
}
|
||||
@ -2840,6 +2842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base: &'tcx hir::Expr<'tcx>,
|
||||
idx: &'tcx hir::Expr<'tcx>,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
brackets_span: Span,
|
||||
) -> Ty<'tcx> {
|
||||
let base_t = self.check_expr(&base);
|
||||
let idx_t = self.check_expr(&idx);
|
||||
@ -2873,7 +2876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let mut err = type_error_struct!(
|
||||
self.tcx.sess,
|
||||
expr.span,
|
||||
brackets_span,
|
||||
base_t,
|
||||
E0608,
|
||||
"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
|
||||
&& 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(
|
||||
expr.span,
|
||||
"to access tuple elements, use",
|
||||
format!("{snip}.{i}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
needs_note = false;
|
||||
}
|
||||
|
||||
err.span_suggestion(
|
||||
brackets_span,
|
||||
"to access tuple elements, use",
|
||||
format!(".{i}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
needs_note = false;
|
||||
} else if let ExprKind::Path(..) = idx.peel_borrows().kind {
|
||||
err.span_label(idx.span, "cannot access tuple elements at a variable index");
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
self.select_from_expr(base);
|
||||
}
|
||||
|
||||
hir::ExprKind::Index(lhs, rhs) => {
|
||||
hir::ExprKind::Index(lhs, rhs, _) => {
|
||||
// lhs[rhs]
|
||||
self.select_from_expr(lhs);
|
||||
self.consume_expr(rhs);
|
||||
|
@ -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 this is an index implemented by a method call, then it
|
||||
// will include an implicit deref of the result.
|
||||
|
@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut exprs = vec![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
|
||||
{
|
||||
exprs.push(expr);
|
||||
|
@ -40,7 +40,7 @@ fn record_rvalue_scope_rec(
|
||||
hir::ExprKind::AddrOf(_, _, subexpr)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
|
||||
| hir::ExprKind::Field(subexpr, _)
|
||||
| hir::ExprKind::Index(subexpr, _) => {
|
||||
| hir::ExprKind::Index(subexpr, _, _) => {
|
||||
expr = subexpr;
|
||||
}
|
||||
_ => {
|
||||
|
@ -210,7 +210,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
// to use builtin indexing because the index type is known to be
|
||||
// usize-ish
|
||||
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.
|
||||
let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
|
||||
if base_ty.is_none() {
|
||||
|
@ -653,7 +653,7 @@ trait UnusedDelimLint {
|
||||
ExprKind::Call(fn_, _params) => fn_,
|
||||
ExprKind::Cast(expr, _ty) => expr,
|
||||
ExprKind::Type(expr, _ty) => expr,
|
||||
ExprKind::Index(base, _subscript) => base,
|
||||
ExprKind::Index(base, _subscript, _) => base,
|
||||
_ => break,
|
||||
};
|
||||
if !classify::expr_requires_semi_to_be_stmt(innermost) {
|
||||
@ -830,7 +830,7 @@ trait UnusedDelimLint {
|
||||
(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) => {
|
||||
(value, UnusedDelimsCtx::AssignedValue, false, None, None, false)
|
||||
|
@ -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) {
|
||||
let lhs = self.mirror_expr(lhs);
|
||||
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 {
|
||||
ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
|
||||
}
|
||||
|
@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
|
||||
let msg = format!(
|
||||
"cast cannot be followed by {}",
|
||||
match with_postfix.kind {
|
||||
ExprKind::Index(_, _) => "indexing",
|
||||
ExprKind::Index(..) => "indexing",
|
||||
ExprKind::Try(_) => "`?`",
|
||||
ExprKind::Field(_, _) => "a field access",
|
||||
ExprKind::MethodCall(_) => "a method call",
|
||||
@ -1304,7 +1304,10 @@ impl<'a> Parser<'a> {
|
||||
let index = self.parse_expr()?;
|
||||
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
|
||||
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.
|
||||
@ -3366,8 +3369,8 @@ impl<'a> Parser<'a> {
|
||||
ExprKind::Binary(binop, lhs, rhs)
|
||||
}
|
||||
|
||||
fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind {
|
||||
ExprKind::Index(expr, idx)
|
||||
fn mk_index(&self, expr: P<Expr>, idx: P<Expr>, brackets_span: Span) -> ExprKind {
|
||||
ExprKind::Index(expr, idx, brackets_span)
|
||||
}
|
||||
|
||||
fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {
|
||||
|
@ -1061,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
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);
|
||||
self.propagate_through_expr(&l, r_succ)
|
||||
}
|
||||
|
@ -4269,7 +4269,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
ExprKind::ConstBlock(ref ct) => {
|
||||
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.visit_expr(idx);
|
||||
}
|
||||
|
@ -2854,7 +2854,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
err.note("all local variables must have a statically known size");
|
||||
}
|
||||
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
|
||||
|
@ -800,7 +800,7 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
|
||||
&& parent.span.ctxt() == e.span.ctxt()
|
||||
{
|
||||
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,
|
||||
ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
|
||||
_ => false,
|
||||
|
@ -221,7 +221,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool {
|
||||
match e.kind {
|
||||
Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),
|
||||
Path(_) => true,
|
||||
Field(inner, _) | Index(inner, _) => is_mutated_static(inner),
|
||||
Field(inner, _) | Index(inner, _, _) => is_mutated_static(inner),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
|
||||
// Checking for slice indexing
|
||||
let parent_id = map.parent_id(expr.hir_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 Ok(index_value) = index_value.try_into();
|
||||
if index_value < max_suggested_slice;
|
||||
|
@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
|
||||
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 ty = cx.typeck_results().expr_ty(array).peel_refs();
|
||||
if let Some(range) = higher::Range::hir(index) {
|
||||
|
@ -60,8 +60,8 @@ pub(super) fn check<'tcx>(
|
||||
o.and_then(|(lhs, rhs)| {
|
||||
let rhs = fetch_cloned_expr(rhs);
|
||||
if_chain! {
|
||||
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_left, idx_left, _) = lhs.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 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);
|
||||
|
@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
||||
|
||||
if_chain! {
|
||||
// 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);
|
||||
then {
|
||||
return;
|
||||
|
@ -162,7 +162,7 @@ fn never_loop_expr<'tcx>(
|
||||
ExprKind::Binary(_, e1, e2)
|
||||
| ExprKind::Assign(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, _, _, _) => {
|
||||
// Break can come from the inner loop so remove them.
|
||||
absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id))
|
||||
|
@ -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
|
||||
// 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;
|
||||
fields.clear();
|
||||
e = base;
|
||||
|
@ -204,7 +204,7 @@ fn find_stripping<'tcx>(
|
||||
if_chain! {
|
||||
if is_ref_str(self.cx, 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 ExprKind::Path(path) = &indexed.kind;
|
||||
if self.cx.qpath_res(path, ex.hir_id) == self.target;
|
||||
|
@ -12,7 +12,7 @@ use super::MATCH_ON_VEC_ITEMS;
|
||||
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
|
||||
if_chain! {
|
||||
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 {
|
||||
// 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>> {
|
||||
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_full_range(cx, index);
|
||||
|
||||
|
@ -12,7 +12,7 @@ use super::FILTER_NEXT;
|
||||
fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
|
||||
match expr.kind {
|
||||
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::Path {
|
||||
|
@ -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() {
|
||||
// caller is a Slice
|
||||
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 })
|
||||
= higher::Range::hir(index_expr);
|
||||
if let hir::ExprKind::Lit(start_lit) = &start_expr.kind;
|
||||
|
@ -239,7 +239,7 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
|
||||
| ExprKind::MethodCall(..)
|
||||
| ExprKind::Call(_, _)
|
||||
| ExprKind::Assign(..)
|
||||
| ExprKind::Index(_, _)
|
||||
| ExprKind::Index(..)
|
||||
| ExprKind::Repeat(_, _)
|
||||
| ExprKind::Struct(_, _, _) => {
|
||||
walk_expr(vis, expr);
|
||||
|
@ -119,7 +119,7 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
|
||||
| ExprKind::Call(i, _)
|
||||
| ExprKind::Cast(i, _)
|
||||
| ExprKind::Type(i, _)
|
||||
| ExprKind::Index(i, _) = inner.kind
|
||||
| ExprKind::Index(i, _, _) = inner.kind
|
||||
{
|
||||
if matches!(
|
||||
i.kind,
|
||||
|
@ -160,7 +160,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
match peel_blocks(expr).kind {
|
||||
ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
|
||||
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::Repeat(inner, _)
|
||||
| ExprKind::Cast(inner, _)
|
||||
@ -263,7 +263,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
|
||||
return None;
|
||||
}
|
||||
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 => {
|
||||
Some(vec![a, b])
|
||||
},
|
||||
|
@ -438,7 +438,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
||||
|
||||
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)`,
|
||||
// meaning `e` must be referenced.
|
||||
// no need to go further up since a method call is involved now.
|
||||
|
@ -695,7 +695,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
|
||||
}
|
||||
},
|
||||
// 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(),
|
||||
|
@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
||||
if_chain! {
|
||||
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind;
|
||||
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);
|
||||
then {
|
||||
let (expr_ty, expr_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(expr));
|
||||
|
@ -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();
|
||||
if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) {
|
||||
span_lint(
|
||||
@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
|
||||
|
||||
// Find string::as_bytes
|
||||
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);
|
||||
if method_names.len() == 1;
|
||||
if expressions.len() == 1;
|
||||
|
@ -572,7 +572,7 @@ fn ident_difference_expr_with_base_location(
|
||||
| (AddrOf(_, _, _), AddrOf(_, _, _))
|
||||
| (Path(_, _), Path(_, _))
|
||||
| (Range(_, _, _), Range(_, _, _))
|
||||
| (Index(_, _), Index(_, _))
|
||||
| (Index(_, _, _), Index(_, _, _))
|
||||
| (Field(_, _), Field(_, _))
|
||||
| (AssignOp(_, _, _), AssignOp(_, _, _))
|
||||
| (Assign(_, _, _), Assign(_, _, _))
|
||||
|
@ -86,8 +86,8 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
if !can_mut_borrow_both(cx, e1, e2) {
|
||||
if let ExprKind::Index(lhs1, idx1) = e1.kind
|
||||
&& let ExprKind::Index(lhs2, idx2) = e2.kind
|
||||
if let ExprKind::Index(lhs1, idx1, _) = e1.kind
|
||||
&& let ExprKind::Index(lhs2, idx2, _) = e2.kind
|
||||
&& eq_expr_value(cx, lhs1, lhs2)
|
||||
&& e1.span.ctxt() == ctxt
|
||||
&& e2.span.ctxt() == ctxt
|
||||
|
@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Assign(target, ..) = &expr.kind {
|
||||
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;
|
||||
}
|
||||
if is_temporary(base) && !is_adjusted(cx, base) {
|
||||
|
@ -103,11 +103,11 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &
|
||||
// Fix #11100
|
||||
&& tys.iter().all_equal()
|
||||
&& let Some(locals) = (match first.kind {
|
||||
ExprKind::Index(_, _) => elements
|
||||
ExprKind::Index(..) => elements
|
||||
.iter()
|
||||
.enumerate()
|
||||
.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 LitKind::Int(val, _) = lit.node
|
||||
{
|
||||
|
@ -526,7 +526,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
self.ident(field_name);
|
||||
self.expr(object);
|
||||
},
|
||||
ExprKind::Index(object, index) => {
|
||||
ExprKind::Index(object, index, _) => {
|
||||
bind!(self, object, index);
|
||||
kind!("Index({object}, {index})");
|
||||
self.expr(object);
|
||||
|
@ -88,7 +88,7 @@ impl VecPushSearcher {
|
||||
let mut last_place = parent;
|
||||
while let Some(parent) = get_parent_expr(cx, last_place) {
|
||||
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;
|
||||
} else {
|
||||
|
@ -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),
|
||||
(Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
|
||||
(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),
|
||||
(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),
|
||||
|
@ -163,7 +163,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
|
||||
) => (Pat::Str("unsafe"), Pat::Str("}")),
|
||||
ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
|
||||
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::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
|
||||
ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
|
||||
|
@ -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::Field(local_expr, ref field) => {
|
||||
let result = self.expr(local_expr);
|
||||
|
@ -185,7 +185,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
||||
.type_dependent_def_id(e.hir_id)
|
||||
.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);
|
||||
if is_copy(self.cx, ty) && !ty.is_ref() {
|
||||
self.eagerness |= NoChange;
|
||||
|
@ -299,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
(&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)
|
||||
},
|
||||
(&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)) => {
|
||||
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_name(f.name);
|
||||
},
|
||||
ExprKind::Index(a, i) => {
|
||||
ExprKind::Index(a, i, _) => {
|
||||
self.hash_expr(a);
|
||||
self.hash_expr(i);
|
||||
},
|
||||
|
@ -735,7 +735,7 @@ fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'
|
||||
let mut result = vec![];
|
||||
let root = loop {
|
||||
match e.kind {
|
||||
ExprKind::Index(ep, _) | ExprKind::Field(ep, _) => {
|
||||
ExprKind::Index(ep, _, _) | ExprKind::Field(ep, _) => {
|
||||
result.push(e);
|
||||
e = ep;
|
||||
},
|
||||
@ -782,7 +782,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
|
||||
return true;
|
||||
}
|
||||
},
|
||||
(ExprKind::Index(_, i1), ExprKind::Index(_, i2)) => {
|
||||
(ExprKind::Index(_, i1, _), ExprKind::Index(_, i2, _)) => {
|
||||
if !eq_expr_value(cx, i1, i2) {
|
||||
return false;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
|
||||
let certainty = match &expr.kind {
|
||||
ExprKind::Unary(_, expr)
|
||||
| ExprKind::Field(expr, _)
|
||||
| ExprKind::Index(expr, _)
|
||||
| ExprKind::Index(expr, _, _)
|
||||
| ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr),
|
||||
|
||||
ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),
|
||||
|
@ -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() => {},
|
||||
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::Index(base, _)
|
||||
ExprKind::Index(base, _, _)
|
||||
if matches!(
|
||||
self.cx.typeck_results().expr_ty(base).peel_refs().kind(),
|
||||
ty::Slice(_) | ty::Array(..)
|
||||
@ -629,7 +629,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
||||
helper(typeck, true, arg, f)?;
|
||||
}
|
||||
},
|
||||
ExprKind::Index(borrowed, consumed)
|
||||
ExprKind::Index(borrowed, consumed, _)
|
||||
| ExprKind::Assign(borrowed, consumed, _)
|
||||
| ExprKind::AssignOp(_, borrowed, consumed) => {
|
||||
helper(typeck, false, borrowed, f)?;
|
||||
|
@ -256,7 +256,7 @@ pub(crate) fn format_expr(
|
||||
shape,
|
||||
SeparatorPlace::Back,
|
||||
),
|
||||
ast::ExprKind::Index(ref expr, ref index) => {
|
||||
ast::ExprKind::Index(ref expr, ref index, _) => {
|
||||
rewrite_index(&**expr, &**index, context, shape)
|
||||
}
|
||||
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::Try(ref 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) => {
|
||||
is_simple_expr(lhs) && is_simple_expr(&*rhs.value)
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
|
||||
ast::ExprKind::AddrOf(_, _, ref expr)
|
||||
| ast::ExprKind::Try(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),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ pub(crate) fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
|
||||
| ast::ExprKind::Assign(ref e, _, _)
|
||||
| ast::ExprKind::AssignOp(_, 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::Try(ref e) => left_most_sub_expr(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::Paren(ref expr)
|
||||
| ast::ExprKind::Binary(_, _, ref expr)
|
||||
| ast::ExprKind::Index(_, ref expr)
|
||||
| ast::ExprKind::Index(_, ref expr, _)
|
||||
| ast::ExprKind::Unary(_, ref expr)
|
||||
| ast::ExprKind::Try(ref expr)
|
||||
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
|
||||
|
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1893;
|
||||
const ROOT_ENTRY_LIMIT: usize = 873;
|
||||
const ROOT_ENTRY_LIMIT: usize = 866;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
@ -1,26 +1,26 @@
|
||||
error[E0608]: cannot index into a value of type `Foo`
|
||||
--> $DIR/slice-2.rs:7:6
|
||||
--> $DIR/slice-2.rs:7:7
|
||||
|
|
||||
LL | &x[..];
|
||||
| ^^^^^
|
||||
| ^^^^
|
||||
|
||||
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..];
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
||||
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];
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
||||
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];
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
|
||||
|
|
||||
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 later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $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;
|
||||
| ^^^^^^^^^
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
|
||||
|
|
||||
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 later used here
|
||||
|
|
||||
help: try adding a local storing this...
|
||||
--> $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;
|
||||
| ^^^^^^^^^
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -50,42 +50,42 @@ error[E0502]: cannot borrow `i` as immutable because it is also borrowed as muta
|
||||
|
|
||||
LL | i[i[3]] = 4;
|
||||
| --^----
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| |||
|
||||
| ||immutable borrow occurs here
|
||||
| |mutable borrow later used here
|
||||
| mutable borrow occurs here
|
||||
| mutable borrow later used here
|
||||
|
|
||||
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;
|
||||
| ^^^^
|
||||
| ^^^
|
||||
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;
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
|
||||
|
|
||||
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 later used here
|
||||
|
|
||||
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];
|
||||
| ^^^^
|
||||
| ^^^
|
||||
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];
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -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
|
||||
|
||||
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();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
note: impl defined here, but it is not `const`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0608]: cannot index into a value of type `u8`
|
||||
--> $DIR/E0608.rs:2:5
|
||||
--> $DIR/E0608.rs:2:8
|
||||
|
|
||||
LL | 0u8[2];
|
||||
| ^^^^^^
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0608]: cannot index into a value of type `!`
|
||||
--> $DIR/index-bot.rs:2:5
|
||||
--> $DIR/index-bot.rs:2:13
|
||||
|
|
||||
LL | (return)[0];
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,8 +1,8 @@
|
||||
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];
|
||||
| ^^^^ help: to access tuple elements, use: `z.0`
|
||||
| ^^^ help: to access tuple elements, use: `.0`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
27
tests/ui/indexing/indexing-spans-caller-location.rs
Normal file
27
tests/ui/indexing/indexing-spans-caller-location.rs
Normal 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);
|
||||
&()
|
||||
}
|
||||
}
|
@ -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 ``
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
@ -1,24 +1,24 @@
|
||||
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];
|
||||
| ^^^^^^ 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})`
|
||||
--> $DIR/issue-27842.rs:9:13
|
||||
--> $DIR/issue-27842.rs:9:16
|
||||
|
|
||||
LL | let _ = tup[i];
|
||||
| ^^^^-^
|
||||
| ^-^
|
||||
| |
|
||||
| cannot access tuple elements at a variable index
|
||||
|
|
||||
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
|
||||
|
||||
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];
|
||||
| ^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
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])];
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
|
||||
|
||||
|
@ -139,7 +139,7 @@ error: function cannot return without recursing
|
||||
LL | fn index(&self, x: usize) -> &Baz {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||
LL | &self[x]
|
||||
| ------- recursive call site
|
||||
| --- recursive call site
|
||||
|
|
||||
= help: a `loop` may express intention better if this is on purpose
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
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]);
|
||||
| ^^^^^^ help: to access tuple elements, use: `tup.0`
|
||||
| ^^^ help: to access tuple elements, use: `.0`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -38,10 +38,10 @@ LL | let _c = unsafe { _ptr2.offset_from(_ptr1) };
|
||||
| ++++++++ ~~~~~~~~~~~~~ +++
|
||||
|
||||
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];
|
||||
| ^^^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
help: consider using `wrapping_add` or `add` for indexing into raw pointer
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user