Skip to content

Commit 44e4e3a

Browse files
committed
CaptureCausedBy
1 parent 2a9b5f9 commit 44e4e3a

File tree

3 files changed

+141
-50
lines changed

3 files changed

+141
-50
lines changed

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
2222
use rustc_target::abi::VariantIdx;
2323
use 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

2727
use super::borrow_set::BorrowData;
2828
use 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

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,68 @@ pub(crate) enum ClosureCannotAgain {
359359
span: Span,
360360
},
361361
}
362+
363+
#[derive(SessionSubdiagnostic)]
364+
pub(crate) enum CaptureCausedBy<'a> {
365+
#[label(borrowck::moved_by_call)]
366+
Call {
367+
place_name: &'a str,
368+
partially_str: &'a str,
369+
loop_message: &'a str,
370+
#[primary_span]
371+
span: Span,
372+
},
373+
#[note(borrowck::moved_fnonce_value)]
374+
FnOnceVal {
375+
#[primary_span]
376+
span: Span,
377+
},
378+
#[label(borrowck::moved_by_operator_use)]
379+
OperatorUse {
380+
place_name: &'a str,
381+
partially_str: &'a str,
382+
loop_message: &'a str,
383+
#[primary_span]
384+
span: Span,
385+
},
386+
#[note(borrowck::lhs_moved_by_operator_call)]
387+
OperatorCall {
388+
#[primary_span]
389+
span: Span,
390+
},
391+
#[label(borrowck::moved_by_implicit_call)]
392+
ImplicitCall {
393+
place_name: &'a str,
394+
partially_str: &'a str,
395+
loop_message: &'a str,
396+
#[primary_span]
397+
span: Span,
398+
},
399+
#[label(borrowck::moved_by_method_call)]
400+
MethodCall {
401+
place_name: &'a str,
402+
partially_str: &'a str,
403+
loop_message: &'a str,
404+
#[primary_span]
405+
span: Span,
406+
},
407+
#[note(borrowck::function_takes_self_ownership)]
408+
FnTakeSelf {
409+
place_name: &'a str,
410+
#[primary_span]
411+
span: Span,
412+
},
413+
#[label(borrowck::consider_borrow_content_of_type)]
414+
ConsiderManualBorrow {
415+
#[primary_span]
416+
span: Span,
417+
},
418+
#[label(borrowck::value_moved_here)]
419+
ValueHere {
420+
move_msg: &'a str,
421+
partially_str: &'a str,
422+
loop_message: &'a str,
423+
#[primary_span]
424+
span: Span,
425+
},
426+
}

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,31 @@ borrowck_closure_cannot_invoke_again =
143143
closure cannot be invoked more than once because it moves the variable `{$place}` out of its environment
144144
145145
borrowck_closure_cannot_move_again =
146-
closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place}` out of its environment
146+
closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place}` out of its environment
147+
148+
borrowck_value_moved_here =
149+
value {$partially_str}moved{$move_msg} here{$loop_message}
150+
151+
borrowck_consider_borrow_content_of_type =
152+
help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
153+
154+
borrowck_function_takes_self_ownership =
155+
this function takes ownership of the receiver `self`, which moves {$place_name}
156+
157+
borrowck_moved_by_method_call =
158+
{$place_name} {$partially_str}moved due to this method call{$loop_message}
159+
160+
borrowck_moved_by_implicit_call =
161+
{$place_name} {$partially_str}moved due to this implicit call to `.into_iter()`{$loop_message}
162+
163+
borrowck_lhs_moved_by_operator_call =
164+
calling this operator moves the left-hand side
165+
166+
borrowck_moved_by_operator_use =
167+
{$place_name} {$partially_str}moved due to usage in operator{$loop_message}
168+
169+
borrowck_moved_fnonce_value =
170+
this value implements `FnOnce`, which causes it to be moved when called
171+
172+
borrowck_moved_by_call =
173+
{$place_name} {$partially_str}moved due to this call{$loop_message}

0 commit comments

Comments
 (0)