From 4a7d5c8abd02bbba1322e52ffacc1d08af278a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 Jul 2026 08:17:24 +0000 Subject: [PATCH] On many bindings with move error, limit the number of `Span`s When a "can't move out of" error would point at too many places, limit the number of spans so that we don't span the terminal. ``` error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a shared reference --> $DIR/borrowck-move-error-many-places.rs:15:11 | LL | match *f { | ^^ LL | Foo::Foo1(num1, | ---- data moved here LL | num2) => (), | ---- ...and here LL | Foo::Foo2(num) => (), | --- ...and here LL | Foo::Foo3(num) => (), | --- ...and here LL | Foo::Foo4(num) => (), | --- ...and here | = note: ...and 4 other places = note: move occurs because these variables have types that don't implement the `Copy` trait help: consider removing the dereference here | LL - match *f { LL + match f { | ``` --- .../src/diagnostics/move_errors.rs | 3 ++ .../borrowck-move-error-many-places.rs | 28 +++++++++++++++++++ .../borrowck-move-error-many-places.stderr | 27 ++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/ui/borrowck/borrowck-move-error-many-places.rs create mode 100644 tests/ui/borrowck/borrowck-move-error-many-places.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 360df2e609a8a..ed4e25f009aed 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -1243,6 +1243,9 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { } } else if j == 0 { err.span_label(binding_span, "data moved here"); + } else if j == 5 && binds_to.len() > 6 && !self.infcx.tcx.sess.opts.verbose { + err.note(format!("...and {} other places", binds_to.len() - 5)); + break; } else { err.span_label(binding_span, "...and here"); } diff --git a/tests/ui/borrowck/borrowck-move-error-many-places.rs b/tests/ui/borrowck/borrowck-move-error-many-places.rs new file mode 100644 index 0000000000000..db504ea20c2d2 --- /dev/null +++ b/tests/ui/borrowck/borrowck-move-error-many-places.rs @@ -0,0 +1,28 @@ +#![allow(unused)] +enum Foo { + Foo1(Box, Box), + Foo2(Box), + Foo3(Box), + Foo4(Box), + Foo5(Box), + Foo6(Box), + Foo7(Box), + Foo8(Box), +} + +fn blah() { + let f = &Foo::Foo1(Box::new(1), Box::new(2)); + match *f { //~ ERROR cannot move out of + Foo::Foo1(num1, + num2) => (), + Foo::Foo2(num) => (), + Foo::Foo3(num) => (), + Foo::Foo4(num) => (), + Foo::Foo5(num) => (), + Foo::Foo6(num) => (), + Foo::Foo7(num) => (), + Foo::Foo8(num) => (), + } +} + +fn main() {} diff --git a/tests/ui/borrowck/borrowck-move-error-many-places.stderr b/tests/ui/borrowck/borrowck-move-error-many-places.stderr new file mode 100644 index 0000000000000..a35f5f7e410dc --- /dev/null +++ b/tests/ui/borrowck/borrowck-move-error-many-places.stderr @@ -0,0 +1,27 @@ +error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a shared reference + --> $DIR/borrowck-move-error-many-places.rs:15:11 + | +LL | match *f { + | ^^ +LL | Foo::Foo1(num1, + | ---- data moved here +LL | num2) => (), + | ---- ...and here +LL | Foo::Foo2(num) => (), + | --- ...and here +LL | Foo::Foo3(num) => (), + | --- ...and here +LL | Foo::Foo4(num) => (), + | --- ...and here + | + = note: ...and 4 other places + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider removing the dereference here + | +LL - match *f { +LL + match f { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`.