diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index ada20e5c614f8..c00e6dde91965 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -92,6 +92,9 @@ borrowck_lifetime_constraints_error = borrowck_limitations_implies_static = due to current limitations in the borrow checker, this implies a `'static` lifetime +borrowck_long_type_consider_verbose = consider using `--verbose` to print the full type name to the console +borrowck_long_type_full_path = the full type name has been written to '{$path}' + borrowck_move_closure_suggestion = consider adding 'move' keyword before the nested closure diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index d020244bf55e4..07dcbba019ade 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -289,6 +289,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { None => "value".to_owned(), }; if needs_note { + let mut path = None; + let ty = self.infcx.tcx.short_ty_string(ty, &mut path); if let Some(local) = place.as_local() { let span = self.body.local_decls[local].source_info.span; err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { @@ -304,6 +306,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { place: ¬e_msg, }); }; + if let Some(path) = path { + err.subdiagnostic(crate::session_diagnostics::LongTypePath { + path: path.display().to_string(), + }); + } } if let UseSpans::FnSelfUse { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index beacbdbd3fa7b..14a900f38e922 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -596,12 +596,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, None); } + let mut path = None; + let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty: place_ty, + ty, place: &place_desc, span, }); + if let Some(path) = path { + err.subdiagnostic(crate::session_diagnostics::LongTypePath { + path: path.display().to_string(), + }); + } } else { binds_to.sort(); binds_to.dedup(); @@ -628,12 +635,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, Some(use_spans)); } + let mut path = None; + let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty: place_ty, + ty, place: &place_desc, span: use_span, }); + if let Some(path) = path { + err.subdiagnostic(crate::session_diagnostics::LongTypePath { + path: path.display().to_string(), + }); + } use_spans.args_subdiag(err, |args_span| { crate::session_diagnostics::CaptureArgLabel::MoveOutPlace { @@ -831,12 +845,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, bind_to.ty, expr, None); } + let mut path = None; + let ty = self.infcx.tcx.short_ty_string(bind_to.ty, &mut path); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty: bind_to.ty, + ty, place: place_desc, span: binding_span, }); + if let Some(path) = path { + err.subdiagnostic(crate::session_diagnostics::LongTypePath { + path: path.display().to_string(), + }); + } } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 4be5d0dbf4284..2c37d2bc12362 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -459,17 +459,24 @@ pub(crate) enum OnClosureNote<'a> { } #[derive(Subdiagnostic)] -pub(crate) enum TypeNoCopy<'a, 'tcx> { +#[note(borrowck_long_type_full_path)] +#[note(borrowck_long_type_consider_verbose)] +pub(crate) struct LongTypePath { + pub(crate) path: String, +} + +#[derive(Subdiagnostic)] +pub(crate) enum TypeNoCopy<'a> { #[label(borrowck_ty_no_impl_copy)] Label { is_partial_move: bool, - ty: Ty<'tcx>, + ty: String, place: &'a str, #[primary_span] span: Span, }, #[note(borrowck_ty_no_impl_copy)] - Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, + Note { is_partial_move: bool, ty: String, place: &'a str }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index ffdb721fb18b4..053775b493789 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -25,6 +25,8 @@ mir_build_borrow_of_moved_value = borrow of moved value .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait .value_borrowed_label = value borrowed here after move .suggestion = borrow this binding in the pattern to avoid moving the value + .full_type_name = the full type name has been written to '{$path}' + .consider_verbose = consider using `--verbose` to print the full type name to the console mir_build_call_to_deprecated_safe_fn_requires_unsafe = call to deprecated safe function `{$function}` is unsafe and requires unsafe block diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 83aec9ccdefc6..c3bf5868eecde 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -790,7 +790,7 @@ pub(crate) struct IrrefutableLetPatternsWhileLet { #[derive(Diagnostic)] #[diag(mir_build_borrow_of_moved_value)] -pub(crate) struct BorrowOfMovedValue<'tcx> { +pub(crate) struct BorrowOfMovedValue { #[primary_span] #[label] #[label(mir_build_occurs_because_label)] @@ -798,9 +798,13 @@ pub(crate) struct BorrowOfMovedValue<'tcx> { #[label(mir_build_value_borrowed_label)] pub(crate) conflicts_ref: Vec, pub(crate) name: Symbol, - pub(crate) ty: Ty<'tcx>, + pub(crate) ty: String, #[suggestion(code = "ref ", applicability = "machine-applicable")] pub(crate) suggest_borrowing: Option, + #[note(mir_build_full_type_name)] + #[note(mir_build_consider_verbose)] + pub(crate) has_path: bool, + pub(crate) path: String, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index b5b7b54a1cc39..d8b04398d9a51 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -795,12 +795,16 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: } }); if !conflicts_ref.is_empty() { + let mut path = None; + let ty = cx.tcx.short_ty_string(ty, &mut path); sess.dcx().emit_err(BorrowOfMovedValue { binding_span: pat.span, conflicts_ref, name, ty, suggest_borrowing: Some(pat.span.shrink_to_lo()), + has_path: path.is_some(), + path: path.map(|p| p.display().to_string()).unwrap_or_default(), }); } return; diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.rs b/tests/ui/diagnostic-width/non-copy-type-moved.rs new file mode 100644 index 0000000000000..a5593ad7b2a3d --- /dev/null +++ b/tests/ui/diagnostic-width/non-copy-type-moved.rs @@ -0,0 +1,17 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" +type A = (String, String, String, String); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +trait Trait {} + +fn require_trait() {} + +fn foo(x: D) { + let _a = x; + let _b = x; //~ ERROR use of moved value +} + +fn main() {} diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr new file mode 100644 index 0000000000000..da9385a5b4dcd --- /dev/null +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `x` + --> $DIR/non-copy-type-moved.rs:14:14 + | +LL | fn foo(x: D) { + | - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait +LL | let _a = x; + | - value moved here +LL | let _b = x; + | ^ value used here after move + | + = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/non-copy-type-moved/non-copy-type-moved.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console +help: consider cloning the value if the performance cost is acceptable + | +LL | let _a = x.clone(); + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`.