From f74eee2fa6620ecb88070ed2eb2dfd7ba12e0b63 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Tue, 1 Aug 2023 16:57:43 -0700 Subject: [PATCH 01/11] [rustc_span][perf] Remove unnecessary string joins and allocs. Comparing vectors of string parts yields the same result but avoids unnecessary `join` and potential allocation for resulting `String`. This code is cold so it's unlikely to have any measurable impact, but considering but since it's also simpler, why not? :) --- compiler/rustc_span/src/edit_distance.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 259f4238654..0ce099387f4 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -247,9 +247,9 @@ fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option String { +fn sort_by_words(name: &str) -> Vec<&str> { let mut split_words: Vec<&str> = name.split('_').collect(); // We are sorting primitive &strs and can use unstable sort here. split_words.sort_unstable(); - split_words.join("_") + split_words } From 383b715163da1aedcf170b7de17a0b6ddc527acd Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 3 Aug 2023 16:05:26 +0300 Subject: [PATCH 02/11] bump parking_lot 0.11 to 0.12 --- Cargo.lock | 4 ++-- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_query_system/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f6df6e14c6..e6a3f252393 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3416,7 +3416,7 @@ dependencies = [ "libc", "measureme", "memmap2", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rustc-hash", "rustc-rayon", "rustc-rayon-core", @@ -4135,7 +4135,7 @@ dependencies = [ name = "rustc_query_system" version = "0.0.0" dependencies = [ - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rustc-rayon-core", "rustc_ast", "rustc_data_structures", diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index a5c3cb3f857..f77bd53e76c 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -35,7 +35,7 @@ elsa = "=1.7.1" itertools = "0.10.1" [dependencies.parking_lot] -version = "0.11" +version = "0.12" [target.'cfg(windows)'.dependencies.windows] version = "0.48.0" diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index e02cf38b671..584355df802 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [lib] [dependencies] -parking_lot = "0.11" +parking_lot = "0.12" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } From 3635b48973ee17951c81769e4a62b0a4891a2501 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 22 Jul 2023 10:13:49 +0800 Subject: [PATCH 03/11] Fix wrong span for trait selection failure error reporting --- .../src/traits/error_reporting/mod.rs | 8 ++++++ tests/ui/dst/issue-113447.fixed | 25 +++++++++++++++++++ tests/ui/dst/issue-113447.rs | 25 +++++++++++++++++++ tests/ui/dst/issue-113447.stderr | 25 +++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 tests/ui/dst/issue-113447.fixed create mode 100644 tests/ui/dst/issue-113447.rs create mode 100644 tests/ui/dst/issue-113447.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index eae13eb6302..4d85e2b6089 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2987,6 +2987,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { unsatisfied_const: bool, ) { let body_def_id = obligation.cause.body_id; + let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } = + obligation.cause.code() + { + *rhs_span + } else { + span + }; + // Try to report a help message if is_fn_trait && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( diff --git a/tests/ui/dst/issue-113447.fixed b/tests/ui/dst/issue-113447.fixed new file mode 100644 index 00000000000..536f680f697 --- /dev/null +++ b/tests/ui/dst/issue-113447.fixed @@ -0,0 +1,25 @@ +// run-rustfix + +pub struct Bytes; + +impl Bytes { + pub fn as_slice(&self) -> &[u8] { + todo!() + } +} + +impl PartialEq<[u8]> for Bytes { + fn eq(&self, other: &[u8]) -> bool { + self.as_slice() == other + } +} + +impl PartialEq for &[u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == **self + } +} + +fn main() { + let _ = &[0u8] == &[0xAA][..]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]` +} diff --git a/tests/ui/dst/issue-113447.rs b/tests/ui/dst/issue-113447.rs new file mode 100644 index 00000000000..c10a4f2ff8e --- /dev/null +++ b/tests/ui/dst/issue-113447.rs @@ -0,0 +1,25 @@ +// run-rustfix + +pub struct Bytes; + +impl Bytes { + pub fn as_slice(&self) -> &[u8] { + todo!() + } +} + +impl PartialEq<[u8]> for Bytes { + fn eq(&self, other: &[u8]) -> bool { + self.as_slice() == other + } +} + +impl PartialEq for &[u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == **self + } +} + +fn main() { + let _ = &[0u8] == [0xAA]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]` +} diff --git a/tests/ui/dst/issue-113447.stderr b/tests/ui/dst/issue-113447.stderr new file mode 100644 index 00000000000..240553a675b --- /dev/null +++ b/tests/ui/dst/issue-113447.stderr @@ -0,0 +1,25 @@ +error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]` + --> $DIR/issue-113447.rs:24:20 + | +LL | let _ = &[0u8] == [0xAA]; + | ^^ no implementation for `&[u8; 1] == [{integer}; 1]` + | + = help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]` + = help: the following other types implement trait `PartialEq`: + <[A; N] as PartialEq<[B; N]>> + <[A; N] as PartialEq<[B]>> + <[A; N] as PartialEq<&[B]>> + <[A; N] as PartialEq<&mut [B]>> + <[T] as PartialEq>> + <[A] as PartialEq<[B]>> + <[B] as PartialEq<[A; N]>> + <&[u8] as PartialEq> + and 4 others +help: convert the array to a `&[u8]` slice instead + | +LL | let _ = &[0u8] == &[0xAA][..]; + | + ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From cde8f06503d06d254aa4191438588ba9b2a36b77 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Aug 2023 00:14:13 +0800 Subject: [PATCH 04/11] enable suggest convert to slice for binary operation --- .../src/traits/error_reporting/suggestions.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 46c31c77613..bde72c691dc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3953,9 +3953,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { candidate_impls: &[ImplCandidate<'tcx>], span: Span, ) { - // We can only suggest the slice coersion for function arguments since the suggestion - // would make no sense in turbofish or call - let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else { + // We can only suggest the slice coersion for function and binary operation arguments, + // since the suggestion would make no sense in turbofish or call + let (ObligationCauseCode::BinOp { .. } + | ObligationCauseCode::FunctionArgumentObligation { .. }) = obligation.cause.code() + else { return; }; From 5706be1854db74d0aafcc4658423884689f139e9 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:43:17 +0200 Subject: [PATCH 05/11] 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. --- compiler/rustc_ast/src/ast.rs | 3 +- compiler/rustc_ast/src/mut_visit.rs | 9 ++++-- compiler/rustc_ast/src/util/parser.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 4 +-- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- .../src/diagnostics/explain_borrow.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 4 +-- .../src/assert/context.rs | 2 +- compiler/rustc_hir/src/hir.rs | 8 ++++-- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 4 +-- compiler/rustc_hir_typeck/src/expr.rs | 25 +++++++++-------- .../rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- .../src/mem_categorization.rs | 2 +- compiler/rustc_hir_typeck/src/place_op.rs | 2 +- .../rustc_hir_typeck/src/rvalue_scopes.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- compiler/rustc_lint/src/unused.rs | 4 +-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 10 +++++-- compiler/rustc_parse/src/parser/expr.rs | 11 +++++--- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../clippy/clippy_lints/src/dereference.rs | 2 +- .../clippy_lints/src/functions/must_use.rs | 2 +- .../clippy_lints/src/index_refutable_slice.rs | 2 +- .../clippy_lints/src/indexing_slicing.rs | 2 +- .../clippy_lints/src/loops/manual_memcpy.rs | 4 +-- .../src/loops/needless_range_loop.rs | 2 +- .../clippy_lints/src/loops/never_loop.rs | 2 +- .../src/loops/while_let_on_iterator.rs | 2 +- .../clippy/clippy_lints/src/manual_strip.rs | 2 +- .../src/matches/match_on_vec_items.rs | 4 +-- .../clippy_lints/src/methods/filter_next.rs | 2 +- .../src/methods/iter_next_slice.rs | 2 +- .../src/mixed_read_write_in_expression.rs | 2 +- .../clippy/clippy_lints/src/needless_bool.rs | 2 +- .../clippy/clippy_lints/src/no_effect.rs | 4 +-- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- src/tools/clippy/clippy_lints/src/ptr.rs | 2 +- .../clippy_lints/src/redundant_slicing.rs | 2 +- src/tools/clippy/clippy_lints/src/strings.rs | 4 +-- .../src/suspicious_operation_groupings.rs | 2 +- src/tools/clippy/clippy_lints/src/swap.rs | 4 +-- .../clippy_lints/src/temporary_assignment.rs | 2 +- .../src/tuple_array_conversions.rs | 4 +-- .../clippy/clippy_lints/src/utils/author.rs | 2 +- .../clippy_lints/src/vec_init_then_push.rs | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 2 +- .../clippy_utils/src/check_proc_macro.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- .../clippy/clippy_utils/src/eager_or_lazy.rs | 2 +- .../clippy/clippy_utils/src/hir_utils.rs | 4 +-- src/tools/clippy/clippy_utils/src/lib.rs | 4 +-- .../clippy_utils/src/ty/type_certainty/mod.rs | 2 +- src/tools/clippy/clippy_utils/src/visitors.rs | 4 +-- src/tools/rustfmt/src/expr.rs | 4 +-- src/tools/rustfmt/src/matches.rs | 2 +- src/tools/rustfmt/src/utils.rs | 4 +-- src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/array-slice-vec/slice-2.stderr | 16 +++++------ .../suggest-local-var-for-vector.stderr | 10 +++---- ...uggest-storing-local-var-for-vector.stderr | 10 +++---- .../two-phase-nonrecv-autoref.base.stderr | 28 +++++++++---------- tests/ui/consts/issue-94675.stderr | 4 +-- tests/ui/error-codes/E0608.stderr | 4 +-- tests/ui/{ => indexing}/index-bot.rs | 0 tests/ui/{ => indexing}/index-bot.stderr | 4 +-- tests/ui/{ => indexing}/index-help.rs | 0 tests/ui/{ => indexing}/index-help.stderr | 0 tests/ui/{ => indexing}/index_message.rs | 0 tests/ui/{ => indexing}/index_message.stderr | 4 +-- .../indexing-requires-a-uint.rs | 0 .../indexing-requires-a-uint.stderr | 0 .../indexing-spans-caller-location.rs | 27 ++++++++++++++++++ ...const-eval-select-backtrace-std.run.stderr | 2 +- tests/ui/issues/issue-27842.stderr | 12 ++++---- tests/ui/issues/issue-40861.stderr | 4 +-- .../lint/lint-unconditional-recursion.stderr | 2 +- tests/ui/span/suggestion-non-ascii.stderr | 4 +-- .../issue-112252-ptr-arithmetics-help.stderr | 4 +-- 82 files changed, 192 insertions(+), 149 deletions(-) rename tests/ui/{ => indexing}/index-bot.rs (100%) rename tests/ui/{ => indexing}/index-bot.stderr (78%) rename tests/ui/{ => indexing}/index-help.rs (100%) rename tests/ui/{ => indexing}/index-help.stderr (100%) rename tests/ui/{ => indexing}/index_message.rs (100%) rename tests/ui/{ => indexing}/index_message.stderr (67%) rename tests/ui/{ => indexing}/indexing-requires-a-uint.rs (100%) rename tests/ui/{ => indexing}/indexing-requires-a-uint.stderr (100%) create mode 100644 tests/ui/indexing/indexing-spans-caller-location.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 2a268c2da85..f2e90fd8eed 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -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, Ident), /// An indexing operation (e.g., `foo[2]`). - Index(P, P), + /// The span represents the span of the `[2]`, including brackets. + Index(P, P, Span), /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment). Range(Option>, Option>, RangeLimits), /// An underscore, used in destructuring assignment to ignore a value. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 84b56efd325..bae3979fbf9 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1400,7 +1400,7 @@ pub fn noop_visit_expr( 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( 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( 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( 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)); diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 096077e09bf..d3e43e20235 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -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) } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index aed24e11c4e..6d474de2d15 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -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) } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0954cf03da9..8c35266110e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -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) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 8767bbcb210..39741a03930 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -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); diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index c92f32071f4..c66a2447356 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -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; } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 3c32121a51a..d62541daf07 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -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..); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index cbf115127cf..bda473120ed 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -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); } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 6b76e16825f..bc05565fed4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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>), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index a8a94e6a476..9d1d899eef0 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -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) } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2d8b956771b..fda46798708 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -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) } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 80d7cc57edb..2af8648455b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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"); } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index a59061cbf67..840910732d8 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -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); diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 0700e2e0554..20b3e470f73 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -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. diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 1eb84eb1637..406434e09e6 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -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); diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs index 091e88abe97..04d84102336 100644 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs @@ -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; } _ => { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6f47623ec43..603681bbc99 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -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() { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index a3c5ca4cda1..3db6b302790 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -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) diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index ff4620948fa..4701b64d22a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -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) } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index dc3b131e7f2..1b45a01f8b3 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -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, idx: P) -> ExprKind { - ExprKind::Index(expr, idx) + fn mk_index(&self, expr: P, idx: P, brackets_span: Span) -> ExprKind { + ExprKind::Index(expr, idx, brackets_span) } fn mk_call(&self, f: P, args: ThinVec>) -> ExprKind { diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 15757a0f1ad..0c0b8b6d094 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -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) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0e9d74480a9..7b590d16d8c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 46c31c77613..85bbd495dd8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index a5ec979ccd9..137bd9c9451 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -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, diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 83445c7a0ca..57df5683c9d 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -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, } } diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 01a7c497cbe..f507f45d5bb 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index 22c14d9b04d..4f4f571773f 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -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) { diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs index 7d1f8ef29c8..d3fd0e8639e 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 2c20e9e8693..c4af46b8fd3 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index 7da9121fbb3..dd77c69ef88 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -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)) diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs index 8019f906aca..5153070cfe6 100644 --- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs @@ -113,7 +113,7 @@ fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option { + ExprKind::Index(base, idx, _) if !idx.can_have_side_effects() => { can_move = false; fields.clear(); e = base; diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index 2b9def1a688..201bb56efcd 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs b/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs index 89dcac4d849..bd53ebd48c8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs index ce7f9997b5a..ac7bc9bcca4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs @@ -12,7 +12,7 @@ use super::FILTER_NEXT; fn path_to_local(expr: &hir::Expr<'_>) -> Option { 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 { diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs index e2029da8081..8f885e9f729 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index 57ec3a1f1e6..367cd6bd413 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs index 46457400abc..f6b87b071b9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_bool.rs +++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs @@ -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, diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index e6d3e72d1e6..5f2a324b05f 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -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 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]) }, diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index a70692d8ff8..243192385c2 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -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. diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 42299d8d42f..8009b00b4b9 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -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(), diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 8277ce724d4..4abfa0fc35c 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -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)); diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 4d45091f4b5..76f463fff7d 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index e2cdc48b583..23d6e2a845f 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -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(_, _, _)) diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs index 98158ed0aee..548fabb8b73 100644 --- a/src/tools/clippy/clippy_lints/src/swap.rs +++ b/src/tools/clippy/clippy_lints/src/swap.rs @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs index 3766b8f8ed1..b6b653f6610 100644 --- a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs +++ b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs @@ -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) { diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs index 7eec6982092..78ad52d8a87 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -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 { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 6b51974d739..f02c33cc674 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs index 1d4fc24eb6c..3fa51216c77 100644 --- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs +++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs @@ -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 { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 7e42924603a..2d0d6f559ad 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -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), diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 89f8a65c5ae..60fab1ec41a 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -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")), diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index f19e09a18ec..d38e3f1ae76 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -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); diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 3c969572b8e..0bcefba75a7 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -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; diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 85b3b005f93..fdc35cd4ddf 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -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); }, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index cf30930b76e..4cd8a8c3325 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -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; } diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index 45b5483e323..0669ea72eb3 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -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))), diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 09f447b27eb..f83988a6e32 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -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)?; diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 739afb4e0ac..c3c07f310bf 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -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) } diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs index aac5e59b860..4c37116f120 100644 --- a/src/tools/rustfmt/src/matches.rs +++ b/src/tools/rustfmt/src/matches.rs @@ -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, } diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index 890a05b8c82..4fc5a9b6896 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -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), diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 44c7c07d3a0..930b7408390 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -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 diff --git a/tests/ui/array-slice-vec/slice-2.stderr b/tests/ui/array-slice-vec/slice-2.stderr index 561feb90f0a..b122b46914c 100644 --- a/tests/ui/array-slice-vec/slice-2.stderr +++ b/tests/ui/array-slice-vec/slice-2.stderr @@ -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 diff --git a/tests/ui/borrowck/suggest-local-var-for-vector.stderr b/tests/ui/borrowck/suggest-local-var-for-vector.stderr index ea92d76b4ec..c8d00f7b222 100644 --- a/tests/ui/borrowck/suggest-local-var-for-vector.stderr +++ b/tests/ui/borrowck/suggest-local-var-for-vector.stderr @@ -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 diff --git a/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr b/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr index 6007beb7753..368d728101c 100644 --- a/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr +++ b/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr @@ -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 diff --git a/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr b/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr index efd63a08aae..e122977b9f2 100644 --- a/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr +++ b/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr @@ -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 diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index cee4dfda2c9..f51f305ac38 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -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 diff --git a/tests/ui/error-codes/E0608.stderr b/tests/ui/error-codes/E0608.stderr index 3aec509934b..f23f9977ba0 100644 --- a/tests/ui/error-codes/E0608.stderr +++ b/tests/ui/error-codes/E0608.stderr @@ -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 diff --git a/tests/ui/index-bot.rs b/tests/ui/indexing/index-bot.rs similarity index 100% rename from tests/ui/index-bot.rs rename to tests/ui/indexing/index-bot.rs diff --git a/tests/ui/index-bot.stderr b/tests/ui/indexing/index-bot.stderr similarity index 78% rename from tests/ui/index-bot.stderr rename to tests/ui/indexing/index-bot.stderr index b5d78297505..bf231c92cad 100644 --- a/tests/ui/index-bot.stderr +++ b/tests/ui/indexing/index-bot.stderr @@ -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 diff --git a/tests/ui/index-help.rs b/tests/ui/indexing/index-help.rs similarity index 100% rename from tests/ui/index-help.rs rename to tests/ui/indexing/index-help.rs diff --git a/tests/ui/index-help.stderr b/tests/ui/indexing/index-help.stderr similarity index 100% rename from tests/ui/index-help.stderr rename to tests/ui/indexing/index-help.stderr diff --git a/tests/ui/index_message.rs b/tests/ui/indexing/index_message.rs similarity index 100% rename from tests/ui/index_message.rs rename to tests/ui/indexing/index_message.rs diff --git a/tests/ui/index_message.stderr b/tests/ui/indexing/index_message.stderr similarity index 67% rename from tests/ui/index_message.stderr rename to tests/ui/indexing/index_message.stderr index 56d1d70809d..80f2bd52314 100644 --- a/tests/ui/index_message.stderr +++ b/tests/ui/indexing/index_message.stderr @@ -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 diff --git a/tests/ui/indexing-requires-a-uint.rs b/tests/ui/indexing/indexing-requires-a-uint.rs similarity index 100% rename from tests/ui/indexing-requires-a-uint.rs rename to tests/ui/indexing/indexing-requires-a-uint.rs diff --git a/tests/ui/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr similarity index 100% rename from tests/ui/indexing-requires-a-uint.stderr rename to tests/ui/indexing/indexing-requires-a-uint.stderr diff --git a/tests/ui/indexing/indexing-spans-caller-location.rs b/tests/ui/indexing/indexing-spans-caller-location.rs new file mode 100644 index 00000000000..2652f00211d --- /dev/null +++ b/tests/ui/indexing/indexing-spans-caller-location.rs @@ -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 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); + &() + } +} diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr index 69c7491b2af..a0024c0920f 100644 --- a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr +++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr @@ -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 diff --git a/tests/ui/issues/issue-27842.stderr b/tests/ui/issues/issue-27842.stderr index 83333aa0c47..b18fe1512b5 100644 --- a/tests/ui/issues/issue-27842.stderr +++ b/tests/ui/issues/issue-27842.stderr @@ -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`) diff --git a/tests/ui/issues/issue-40861.stderr b/tests/ui/issues/issue-40861.stderr index 84e38b9bb05..9b6469d05e9 100644 --- a/tests/ui/issues/issue-40861.stderr +++ b/tests/ui/issues/issue-40861.stderr @@ -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`) diff --git a/tests/ui/lint/lint-unconditional-recursion.stderr b/tests/ui/lint/lint-unconditional-recursion.stderr index 9d200a7898e..d75754bf9f9 100644 --- a/tests/ui/lint/lint-unconditional-recursion.stderr +++ b/tests/ui/lint/lint-unconditional-recursion.stderr @@ -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 diff --git a/tests/ui/span/suggestion-non-ascii.stderr b/tests/ui/span/suggestion-non-ascii.stderr index b14632d4e1b..21f8bb62a0c 100644 --- a/tests/ui/span/suggestion-non-ascii.stderr +++ b/tests/ui/span/suggestion-non-ascii.stderr @@ -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 diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr index c55930da225..f81736245f3 100644 --- a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr @@ -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 | From 97aa4ba171bc78ccbb96b72bd2eef056ad2ece73 Mon Sep 17 00:00:00 2001 From: Sebastian Toh Date: Fri, 4 Aug 2023 20:12:20 +0800 Subject: [PATCH 06/11] Fix unwrap on None --- .../src/fn_ctxt/suggestions.rs | 3 +- tests/ui/typeck/issue-114423.rs | 15 ++++++ tests/ui/typeck/issue-114423.stderr | 52 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/ui/typeck/issue-114423.rs create mode 100644 tests/ui/typeck/issue-114423.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d4edd08d302..89bbb4c2203 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1620,8 +1620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .enumerate() .filter(|x| x.1.hir_id == *hir_id) - .map(|(i, _)| init_tup.get(i).unwrap()) - .next() + .find_map(|(i, _)| init_tup.get(i)) { self.note_type_is_not_clone_inner_expr(init) } else { diff --git a/tests/ui/typeck/issue-114423.rs b/tests/ui/typeck/issue-114423.rs new file mode 100644 index 00000000000..da2dae1c46b --- /dev/null +++ b/tests/ui/typeck/issue-114423.rs @@ -0,0 +1,15 @@ +struct RGB { + g: f64, + b: f64, +} + +fn main() { + let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + //~^ ERROR cannot find value `e` in this scope + //~| ERROR cannot find value `e` in this scope + //~| ERROR mismatched types + let _ = RGB { r, g, b }; + //~^ ERROR cannot find value `g` in this scope + //~| ERROR struct `RGB` has no field named `r` + //~| ERROR mismatched types +} diff --git a/tests/ui/typeck/issue-114423.stderr b/tests/ui/typeck/issue-114423.stderr new file mode 100644 index 00000000000..c20a4391297 --- /dev/null +++ b/tests/ui/typeck/issue-114423.stderr @@ -0,0 +1,52 @@ +error[E0425]: cannot find value `e` in this scope + --> $DIR/issue-114423.rs:7:51 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | ^ not found in this scope + +error[E0425]: cannot find value `e` in this scope + --> $DIR/issue-114423.rs:7:62 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | ^ not found in this scope + +error[E0425]: cannot find value `g` in this scope + --> $DIR/issue-114423.rs:11:22 + | +LL | let _ = RGB { r, g, b }; + | ^ help: a local variable with a similar name exists: `b` + +error[E0308]: mismatched types + --> $DIR/issue-114423.rs:7:50 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | --------------- ^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements + | | + | expected due to this + | + = note: expected tuple `(f32, f32, f32)` + found tuple `(f32, f32)` + +error[E0560]: struct `RGB` has no field named `r` + --> $DIR/issue-114423.rs:11:19 + | +LL | let _ = RGB { r, g, b }; + | ^ `RGB` does not have this field + | + = note: all struct fields are already assigned + +error[E0308]: mismatched types + --> $DIR/issue-114423.rs:11:25 + | +LL | let _ = RGB { r, g, b }; + | ^ expected `f64`, found `f32` + | +help: you can convert an `f32` to an `f64` + | +LL | let _ = RGB { r, g, b: b.into() }; + | ++ +++++++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0425, E0560. +For more information about an error, try `rustc --explain E0308`. From 3345077b42ec15a4c85b9f5a4c364ccb599a1d0f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 4 Aug 2023 15:00:57 +0200 Subject: [PATCH 07/11] interpret: add mplace_to_ref helper method --- compiler/rustc_const_eval/src/interpret/place.rs | 15 +++++++++++++-- .../rustc_const_eval/src/interpret/terminator.rs | 5 +---- .../src/borrow_tracker/stacked_borrows/mod.rs | 5 ++--- .../miri/src/borrow_tracker/tree_borrows/mod.rs | 5 ++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 5f4f5434b18..2dc856528f5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -157,7 +157,6 @@ impl MemPlace { } /// Turn a mplace into a (thin or wide) pointer, as a reference, pointing to the same space. - /// This is the inverse of `ref_to_mplace`. #[inline(always)] pub fn to_ref(self, cx: &impl HasDataLayout) -> Immediate { match self.meta { @@ -415,7 +414,7 @@ where } /// Take a value, which represents a (thin or wide) reference, and make it a place. - /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`. + /// Alignment is just based on the type. This is the inverse of `mplace_to_ref()`. /// /// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not /// want to ever use the place for memory access! @@ -438,6 +437,18 @@ where Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.to_pointer(self)?, layout, meta)) } + /// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space. + /// `align` information is lost! + /// This is the inverse of `ref_to_mplace`. + pub fn mplace_to_ref( + &self, + mplace: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { + let imm = mplace.to_ref(self); + let layout = self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, mplace.layout.ty))?; + Ok(ImmTy::from_immediate(imm, layout)) + } + /// Take an operand, representing a pointer, and dereference it to a place. /// Corresponds to the `*` operator in Rust. #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index bf33c5cca10..1bd21473182 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -852,10 +852,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let instance = ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?; - let arg = ImmTy::from_immediate( - place.to_ref(self), - self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, place.layout.ty))?, - ); + let arg = self.mplace_to_ref(&place)?; let ret = MPlaceTy::fake_alloc_zst(self.layout_of(self.tcx.types.unit)?); self.eval_fn_call( diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index e929091b396..75e4b5f8466 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Mutability, RetagKind}; use rustc_middle::ty::{ self, - layout::{HasParamEnv, LayoutOf}, + layout::HasParamEnv, Ty, }; use rustc_target::abi::{Abi, Align, Size}; @@ -993,8 +993,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We have to turn the place into a pointer to use the usual retagging logic. // (The pointer type does not matter, so we use a raw pointer.) - let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?; - let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout); + let ptr = this.mplace_to_ref(place)?; // Reborrow it. With protection! That is the entire point. let new_perm = NewPermission::Uniform { perm: Permission::Unique, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index b2dbe8a70f0..d30745b3b61 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -7,7 +7,7 @@ use rustc_middle::{ mir::{Mutability, RetagKind}, ty::{ self, - layout::{HasParamEnv, LayoutOf}, + layout::HasParamEnv, Ty, }, }; @@ -488,8 +488,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We have to turn the place into a pointer to use the usual retagging logic. // (The pointer type does not matter, so we use a raw pointer.) - let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?; - let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout); + let ptr = this.mplace_to_ref(place)?; // Reborrow it. With protection! That is the entire point. let new_perm = NewPermission { initial_state: Permission::new_active(), From e3700953c14bb941e465a2a5b37fe553cd4adb7e Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 3 Aug 2023 16:54:16 +0300 Subject: [PATCH 08/11] replace few explicit use of parking_lot with rustc_data_structures::sync onces --- .../rustc_query_system/src/dep_graph/graph.rs | 3 +-- compiler/rustc_query_system/src/query/job.rs | 23 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index b87757a3e1a..3803f7eca0a 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1,4 +1,3 @@ -use parking_lot::Mutex; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef}; @@ -88,7 +87,7 @@ pub struct DepGraphData { colors: DepNodeColorMap, - processed_side_effects: Mutex>, + processed_side_effects: Lock>, /// When we load, there may be `.o` files, cached MIR, or other such /// things available to us. If we find that they are not dirty, we diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index d2140161f1d..bfc51da170d 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -21,12 +21,11 @@ use { parking_lot::{Condvar, Mutex}, rayon_core, rustc_data_structures::fx::FxHashSet, - rustc_data_structures::sync::Lock, - rustc_data_structures::sync::Lrc, rustc_data_structures::{defer, jobserver}, rustc_span::DUMMY_SP, std::iter, std::process, + std::sync::Arc, }; /// Represents a span and a query key. @@ -191,7 +190,7 @@ struct QueryWaiter { query: Option, condvar: Condvar, span: Span, - cycle: Lock>>, + cycle: Mutex>>, } #[cfg(parallel_compiler)] @@ -205,20 +204,20 @@ impl QueryWaiter { #[cfg(parallel_compiler)] struct QueryLatchInfo { complete: bool, - waiters: Vec>>, + waiters: Vec>>, } #[cfg(parallel_compiler)] #[derive(Clone)] pub(super) struct QueryLatch { - info: Lrc>>, + info: Arc>>, } #[cfg(parallel_compiler)] impl QueryLatch { fn new() -> Self { QueryLatch { - info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })), + info: Arc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })), } } @@ -229,11 +228,11 @@ impl QueryLatch { span: Span, ) -> Result<(), CycleError> { let waiter = - Lrc::new(QueryWaiter { query, span, cycle: Lock::new(None), condvar: Condvar::new() }); + Arc::new(QueryWaiter { query, span, cycle: Mutex::new(None), condvar: Condvar::new() }); self.wait_on_inner(&waiter); // FIXME: Get rid of this lock. We have ownership of the QueryWaiter - // although another thread may still have a Lrc reference so we cannot - // use Lrc::get_mut + // although another thread may still have a Arc reference so we cannot + // use Arc::get_mut let mut cycle = waiter.cycle.lock(); match cycle.take() { None => Ok(()), @@ -242,7 +241,7 @@ impl QueryLatch { } /// Awaits the caller on this latch by blocking the current thread. - fn wait_on_inner(&self, waiter: &Lrc>) { + fn wait_on_inner(&self, waiter: &Arc>) { let mut info = self.info.lock(); if !info.complete { // We push the waiter on to the `waiters` list. It can be accessed inside @@ -276,7 +275,7 @@ impl QueryLatch { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter(&self, waiter: usize) -> Lrc> { + fn extract_waiter(&self, waiter: usize) -> Arc> { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -428,7 +427,7 @@ where fn remove_cycle( query_map: &QueryMap, jobs: &mut Vec, - wakelist: &mut Vec>>, + wakelist: &mut Vec>>, ) -> bool { let mut visited = FxHashSet::default(); let mut stack = Vec::new(); From 553508c22e85b1d5deb90da751e13fa6ff207a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 4 Aug 2023 16:46:08 +0000 Subject: [PATCH 09/11] Reword confusable idents lint Fix #76140. --- compiler/rustc_lint/messages.ftl | 5 +++-- compiler/rustc_lint/src/lints.rs | 4 +++- compiler/rustc_lint/src/non_ascii_idents.rs | 1 + .../lint-confusable-idents.rs | 4 ++-- .../lint-confusable-idents.stderr | 12 ++++++------ 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 16e17fc9d6a..0afd7713dea 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -166,8 +166,9 @@ lint_check_name_warning = {$msg} lint_command_line_source = `forbid` lint level was set on command line -lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}` - .label = this is where the previous identifier occurred +lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike + .current_use = this identifier can be confused with `{$existing_sym}` + .other_use = other identifier used here lint_cstring_ptr = getting the inner pointer of a temporary `CString` .as_ptr_label = this pointer will be invalid diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 968172693a9..3c1059debc4 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1056,8 +1056,10 @@ pub struct IdentifierUncommonCodepoints; pub struct ConfusableIdentifierPair { pub existing_sym: Symbol, pub sym: Symbol, - #[label] + #[label(lint_other_use)] pub label: Span, + #[label(lint_current_use)] + pub main_label: Span, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 4af879b4e91..62bb8c2c67d 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -222,6 +222,7 @@ impl EarlyLintPass for NonAsciiIdents { existing_sym: *existing_symbol, sym: symbol, label: *existing_span, + main_label: sp, }, ); } diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs index e7da825ae36..b2d8a28d3c4 100644 --- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs +++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs @@ -5,8 +5,8 @@ const s: usize = 42; const s_s: usize = 42; fn main() { - let s = "rust"; //~ ERROR identifier pair considered confusable - let s_s = "rust2"; //~ ERROR identifier pair considered confusable + let s = "rust"; //~ ERROR found both + let s_s = "rust2"; //~ ERROR found both not_affected(); } diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr index e9906c83d12..d1920f215e2 100644 --- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr +++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr @@ -1,11 +1,11 @@ -error: identifier pair considered confusable between `s` and `s` +error: found both `s` and `s` as identifiers, which look alike --> $DIR/lint-confusable-idents.rs:8:9 | LL | const s: usize = 42; - | -- this is where the previous identifier occurred + | -- other identifier used here ... LL | let s = "rust"; - | ^ + | ^ this identifier can be confused with `s` | note: the lint level is defined here --> $DIR/lint-confusable-idents.rs:1:9 @@ -13,14 +13,14 @@ note: the lint level is defined here LL | #![deny(confusable_idents)] | ^^^^^^^^^^^^^^^^^ -error: identifier pair considered confusable between `s_s` and `s_s` +error: found both `s_s` and `s_s` as identifiers, which look alike --> $DIR/lint-confusable-idents.rs:9:9 | LL | const s_s: usize = 42; - | --- this is where the previous identifier occurred + | --- other identifier used here ... LL | let s_s = "rust2"; - | ^^^^^ + | ^^^^^ this identifier can be confused with `s_s` error: aborting due to 2 previous errors From 3d25b5c7e8653a4ce0513cf8d7bcbd796ed81c4b Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Aug 2023 13:28:04 +0800 Subject: [PATCH 10/11] Fix ICE failed to get layout for ReferencesError --- .../rustc_codegen_cranelift/src/common.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 2 +- .../invalid/issue-114435-layout-type-err.rs | 44 +++++++++++++++++++ .../issue-114435-layout-type-err.stderr | 8 ++++ 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 tests/ui/invalid/issue-114435-layout-type-err.rs create mode 100644 tests/ui/invalid/issue-114435-layout-type-err.stderr diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 67ea20112fe..3081dcfa2b7 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -477,7 +477,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let layout::LayoutError::SizeOverflow(_) = err { + if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.0.sess.span_fatal(span, err.to_string()) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 08507e19652..88dcafa7370 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -476,7 +476,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) = err { + if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.sess().emit_fatal(respan(span, err.into_diagnostic())) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index cb093996d1d..3577fb2d951 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -985,7 +985,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) = err { + if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() }) } else { span_bug!(span, "failed to get layout for `{ty}`: {err:?}") diff --git a/tests/ui/invalid/issue-114435-layout-type-err.rs b/tests/ui/invalid/issue-114435-layout-type-err.rs new file mode 100644 index 00000000000..a2d40593687 --- /dev/null +++ b/tests/ui/invalid/issue-114435-layout-type-err.rs @@ -0,0 +1,44 @@ +// build-fail +// compile-flags: --crate-type lib -Cdebuginfo=2 +// error-pattern: the type has an unknown layout + +#![recursion_limit = "10"] +macro_rules! link { + ($outer:ident, $inner:ident) => { + struct $outer($inner); + impl $outer { + fn new() -> $outer { + $outer($inner::new()) + } + } + impl std::ops::Deref for $outer { + type Target = $inner; + fn deref(&self) -> &$inner { + &self.0 + } + } + }; +} + +struct Bottom; + +impl Bottom { + fn new() -> Bottom { + Bottom + } +} + + +link!(A, B); +link!(B, C); +link!(C, D); +link!(D, E); +link!(E, F); +link!(F, G); +link!(G, H); +link!(H, I); +link!(I, J); +link!(J, K); +link!(K, Bottom); + +fn main() { } diff --git a/tests/ui/invalid/issue-114435-layout-type-err.stderr b/tests/ui/invalid/issue-114435-layout-type-err.stderr new file mode 100644 index 00000000000..a2db74ff8bd --- /dev/null +++ b/tests/ui/invalid/issue-114435-layout-type-err.stderr @@ -0,0 +1,8 @@ +error: reached the recursion limit finding the struct tail for `Bottom` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` + +error: the type has an unknown layout + +error: aborting due to 2 previous errors + From edc3e2677335f930450f3e9f006e87869fe31d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 4 Aug 2023 17:50:12 +0000 Subject: [PATCH 11/11] Account for `Rc` and `Arc` when suggesting to clone When suggesting to clone a reference-counted value, be less uncertain. --- .../src/diagnostics/conflict_errors.rs | 12 +++++++++++- .../use_of_moved_value_clone_suggestions.stderr | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 03b90f4ab18..4cb6b028e55 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -751,9 +751,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) .must_apply_modulo_regions() { + let msg = if let ty::Adt(def, _) = ty.kind() + && [ + tcx.get_diagnostic_item(sym::Arc), + tcx.get_diagnostic_item(sym::Rc), + ].contains(&Some(def.did())) + { + "clone the value to increment its reference count" + } else { + "consider cloning the value if the performance cost is acceptable" + }; err.span_suggestion_verbose( span.shrink_to_hi(), - "consider cloning the value if the performance cost is acceptable", + msg, suggestion, Applicability::MachineApplicable, ); diff --git a/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr b/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr index 22e7951dbe3..0bb486a8893 100644 --- a/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr +++ b/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr @@ -8,7 +8,7 @@ LL | (t, t) | | | value moved here | -help: consider cloning the value if the performance cost is acceptable +help: clone the value to increment its reference count | LL | (t.clone(), t) | ++++++++