@@ -22,7 +22,7 @@ use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
2222use rustc_target:: abi:: VariantIdx ;
2323use rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions;
2424
25- use crate :: session_diagnostics:: ClosureCannotAgain ;
25+ use crate :: session_diagnostics:: { CaptureCausedBy , ClosureCannotAgain } ;
2626
2727use super :: borrow_set:: BorrowData ;
2828use super :: MirBorrowckCtxt ;
@@ -982,37 +982,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
982982 CallKind :: FnCall { fn_trait_id, .. }
983983 if Some ( fn_trait_id) == self . infcx . tcx . lang_items ( ) . fn_once_trait ( ) =>
984984 {
985- err. span_label (
986- fn_call_span,
987- & format ! (
988- "{} {}moved due to this call{}" ,
989- place_name, partially_str, loop_message
990- ) ,
991- ) ;
992- err. span_note (
993- var_span,
994- "this value implements `FnOnce`, which causes it to be moved when called" ,
995- ) ;
985+ let label = CaptureCausedBy :: Call {
986+ place_name : & place_name,
987+ partially_str,
988+ loop_message,
989+ span : fn_call_span,
990+ } ;
991+ let note = CaptureCausedBy :: FnOnceVal { span : var_span } ;
992+ err. subdiagnostic ( note) ;
996993 }
997994 CallKind :: Operator { self_arg, .. } => {
998995 let self_arg = self_arg. unwrap ( ) ;
999- err . span_label (
1000- fn_call_span ,
1001- & format ! (
1002- "{} {}moved due to usage in operator{}" ,
1003- place_name , partially_str , loop_message
1004- ) ,
1005- ) ;
996+ let label = CaptureCausedBy :: OperatorUse {
997+ place_name : & place_name ,
998+ partially_str ,
999+ loop_message ,
1000+ span : fn_call_span ,
1001+ } ;
1002+ err . subdiagnostic ( label ) ;
10061003 if self . fn_self_span_reported . insert ( fn_span) {
1007- err . span_note (
1004+ let span =
10081005 // Check whether the source is accessible
10091006 if self . infcx . tcx . sess . source_map ( ) . is_span_accessible ( self_arg. span ) {
10101007 self_arg. span
10111008 } else {
10121009 fn_call_span
1013- } ,
1014- "calling this operator moves the left-hand side" ,
1015- ) ;
1010+ } ;
1011+ let note = CaptureCausedBy :: OperatorCall { span } ;
1012+ err . subdiagnostic ( note ) ;
10161013 }
10171014 }
10181015 CallKind :: Normal { self_arg, desugaring, is_option_or_result } => {
@@ -1047,13 +1044,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10471044 ) ;
10481045 }
10491046
1050- err . span_label (
1051- fn_call_span ,
1052- & format ! (
1053- "{} {}moved due to this implicit call to `.into_iter()`{}" ,
1054- place_name , partially_str , loop_message
1055- ) ,
1056- ) ;
1047+ let label = CaptureCausedBy :: ImplicitCall {
1048+ place_name : & place_name ,
1049+ partially_str ,
1050+ loop_message ,
1051+ span : fn_call_span ,
1052+ } ;
1053+ err . subdiagnostic ( label ) ;
10571054 // If we have a `&mut` ref, we need to reborrow.
10581055 if let Some ( ty:: Ref ( _, _, hir:: Mutability :: Mut ) ) = used_place
10591056 . map ( |used_place| used_place. ty ( self . body , self . infcx . tcx ) . ty . kind ( ) )
@@ -1074,38 +1071,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10741071 }
10751072 }
10761073 } else {
1077- err . span_label (
1078- fn_call_span ,
1079- & format ! (
1080- "{} {}moved due to this method call{}" ,
1081- place_name , partially_str , loop_message
1082- ) ,
1083- ) ;
1074+ let label = CaptureCausedBy :: MethodCall {
1075+ place_name : & place_name ,
1076+ partially_str ,
1077+ loop_message ,
1078+ span : fn_call_span ,
1079+ } ;
1080+ err . subdiagnostic ( label ) ;
10841081 }
10851082 // Avoid pointing to the same function in multiple different
10861083 // error messages.
10871084 if span != DUMMY_SP && self . fn_self_span_reported . insert ( self_arg. span ) {
1088- err. span_note (
1089- self_arg. span ,
1090- & format ! ( "this function takes ownership of the receiver `self`, which moves {}" , place_name)
1091- ) ;
1085+ let label = CaptureCausedBy :: FnTakeSelf {
1086+ place_name : & place_name,
1087+ span : self_arg. span ,
1088+ } ;
1089+ err. subdiagnostic ( label) ;
10921090 }
10931091 if is_option_or_result && maybe_reinitialized_locations_is_empty {
1094- err. span_label (
1095- var_span,
1096- "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents" ,
1097- ) ;
1092+ let label = CaptureCausedBy :: ConsiderManualBorrow { span : var_span } ;
1093+ err. subdiagnostic ( label) ;
10981094 }
10991095 }
11001096 // Other desugarings takes &self, which cannot cause a move
11011097 _ => { }
11021098 }
11031099 } else {
11041100 if move_span != span || !loop_message. is_empty ( ) {
1105- err. span_label (
1106- move_span,
1107- format ! ( "value {}moved{} here{}" , partially_str, move_msg, loop_message) ,
1108- ) ;
1101+ let label = CaptureCausedBy :: ValueHere {
1102+ move_msg,
1103+ partially_str,
1104+ loop_message,
1105+ span : move_span,
1106+ } ;
1107+ err. subdiagnostic ( label) ;
11091108 }
11101109 // If the move error occurs due to a loop, don't show
11111110 // another message for the same span
0 commit comments