1
Fork 0

Add note pointing to where a closure and it's captured variables are dropped

This commit is contained in:
Roxane 2021-07-07 10:29:06 -04:00
parent 0e8e89daa6
commit 2900c1a5e8
20 changed files with 373 additions and 30 deletions

View file

@ -511,6 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.as_str(),
);
for (var_hir_id, diagnostics_info) in need_migrations.iter() {
let mut captured_names = format!("");
for (captured_hir_id, captured_name) in diagnostics_info.iter() {
if let Some(captured_hir_id) = captured_hir_id {
let cause_span = self.tcx.hir().span(*captured_hir_id);
@ -518,8 +519,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.hir().name(*var_hir_id),
captured_name,
));
if captured_names == "" {
captured_names = format!("`{}`", captured_name);
} else {
captured_names = format!("{}, `{}`", captured_names, captured_name);
}
}
}
if reasons.contains("drop order") {
let drop_location_span = drop_location_span(self.tcx, &closure_hir_id);
diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` would be dropped here, but in Rust 2021, only {} would be dropped here alongside the closure",
self.tcx.hir().name(*var_hir_id),
captured_names,
));
}
}
diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
let closure_body_span = self.tcx.hir().span(body_id.hir_id);
@ -1350,6 +1365,31 @@ fn apply_capture_kind_on_capture_ty(
}
}
/// Returns the Span of where the value with the provided HirId would be dropped
fn drop_location_span(tcx: TyCtxt<'tcx>, hir_id: &hir::HirId) -> Span {
let owner_id = tcx.hir().get_enclosing_scope(*hir_id).unwrap();
let owner_node = tcx.hir().get(owner_id);
match owner_node {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Fn(_, _, owner_id) => {
let owner_span = tcx.hir().span(owner_id.hir_id);
tcx.sess.source_map().end_point(owner_span)
}
_ => {
bug!("Drop location span error: need to handle more ItemKind {:?}", item.kind);
}
},
hir::Node::Block(block) => {
let owner_span = tcx.hir().span(block.hir_id);
tcx.sess.source_map().end_point(owner_span)
}
_ => {
bug!("Drop location span error: need to handle more Node {:?}", owner_node);
}
}
}
struct InferBorrowKind<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,