mirror of
https://github.com/rust-lang/rust
synced 2024-10-14 12:33:57 +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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
|
|||
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 @@ pub(crate) fn add_explanation_to_diagnostic(
|
|||
| 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 @@ fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'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 @@ fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'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 @@ fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
|||
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 @@ pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> boo
|
|||
|
||||
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 @@ pub fn can_have_side_effects(&self) -> bool {
|
|||
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 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
|||
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 @@ fn check_expr_kind(
|
|||
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 @@ fn check_expr_index(
|
|||
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 @@ fn check_expr_index(
|
|||
|
||||
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 @@ fn check_expr_index(
|
|||
&& 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 @@ pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
|
|||
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 @@ pub(crate) fn cat_expr_unadjusted(
|
|||
))
|
||||
}
|
||||
|
||||
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 @@ pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
|
|||
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 @@ fn is_builtin_index(
|
|||
// 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 @@ fn is_expr_delims_necessary(
|
|||
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 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
|||
(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 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'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 @@ fn parse_and_disallow_postfix_after_cast(
|
|||
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 @@ fn parse_expr_index(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>>
|
|||
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 @@ fn mk_binary(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
|
|||
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 @@ fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNod
|
|||
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 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
|
|||
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 @@ fn note_obligation_cause_code<T>(
|
|||
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 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|||
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 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
|||
|
||||
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 visit_expr(&mut self, ex: &'tcx Expr<'_>) {
|
|||
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 @@
|
|||
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 @@
|
|||
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx 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)`,
|
||||
// meaning `e` must be referenced.
|
||||
// no need to go further up since a method call is involved now.
|
||||
|
|
|
@ -695,7 +695,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
|
|||
}
|
||||
},
|
||||
// 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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|||
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
|||
);
|
||||
}
|
||||
},
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
|||
|
||||
// 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 @@ macro_rules! kind {
|
|||
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 @@ fn display_err(&self, cx: &LateContext<'_>) {
|
|||
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 @@ pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant<'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 visit_expr(&mut self, e: &'tcx Expr<'_>) {
|
|||
.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 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
|||
(&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 @@ pub fn hash_expr(&mut self, e: &Expr<'_>) {
|
|||
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 @@ fn visit_expr(&mut self, 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 @@ fn helper<'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 @@
|
|||
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 a new issue