Skip to content

Commit f2e52ff

Browse files
committed
2229: Produce a rustfix migration suggestion
1 parent cc41030 commit f2e52ff

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

compiler/rustc_typeck/src/check/upvar.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use super::FnCtxt;
3434

3535
use crate::expr_use_visitor as euv;
3636
use rustc_data_structures::fx::FxIndexMap;
37+
use rustc_errors::Applicability;
3738
use rustc_hir as hir;
3839
use rustc_hir::def_id::DefId;
3940
use rustc_hir::def_id::LocalDefId;
@@ -91,7 +92,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
9192
if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.kind {
9293
let body = self.fcx.tcx.hir().body(body_id);
9394
self.visit_body(body);
94-
self.fcx.analyze_closure(expr.hir_id, expr.span, body, cc);
95+
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, cc);
9596
}
9697

9798
intravisit::walk_expr(self, expr);
@@ -104,6 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
104105
&self,
105106
closure_hir_id: hir::HirId,
106107
span: Span,
108+
body_id: hir::BodyId,
107109
body: &'tcx hir::Body<'tcx>,
108110
capture_clause: hir::CaptureBy,
109111
) {
@@ -167,7 +169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
167169

168170
let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
169171
if should_do_migration_analysis(self.tcx, closure_hir_id) {
170-
self.perform_2229_migration_anaysis(closure_def_id, capture_clause, span);
172+
self.perform_2229_migration_anaysis(closure_def_id, body_id, capture_clause, span);
171173
}
172174

173175
// We now fake capture information for all variables that are mentioned within the closure
@@ -465,6 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
465467
fn perform_2229_migration_anaysis(
466468
&self,
467469
closure_def_id: DefId,
470+
body_id: hir::BodyId,
468471
capture_clause: hir::CaptureBy,
469472
span: Span,
470473
) {
@@ -488,7 +491,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
488491
let mut diagnostics_builder = lint.build(
489492
"drop order affected for closure because of `capture_disjoint_fields`",
490493
);
491-
diagnostics_builder.note(&migrations_text);
494+
let closure_body_span = self.tcx.hir().span(body_id.hir_id);
495+
let (sugg, app) =
496+
match self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
497+
Ok(s) => (
498+
format!("{{ {} {} }}", migrations_text, s),
499+
Applicability::MachineApplicable,
500+
),
501+
Err(_) => (migrations_text.clone(), Applicability::HasPlaceholders),
502+
};
503+
504+
diagnostics_builder.span_suggestion(
505+
closure_body_span,
506+
&format!("You can restore original behavior adding `{}` to the closure/generator", migrations_text),
507+
sugg,
508+
app,
509+
);
492510
diagnostics_builder.emit();
493511
},
494512
);
@@ -1517,10 +1535,14 @@ fn should_do_migration_analysis(tcx: TyCtxt<'_>, closure_id: hir::HirId) -> bool
15171535

15181536
fn migration_suggestion_for_2229(tcx: TyCtxt<'_>, need_migrations: &Vec<hir::HirId>) -> String {
15191537
let need_migrations_strings =
1520-
need_migrations.iter().map(|v| format!("{}", var_name(tcx, *v))).collect::<Vec<_>>();
1538+
need_migrations.iter().map(|v| format!("&{}", var_name(tcx, *v))).collect::<Vec<_>>();
15211539
let migrations_list_concat = need_migrations_strings.join(", ");
15221540

1523-
format!("drop(&({}));", migrations_list_concat)
1541+
if 1 == need_migrations.len() {
1542+
format!("let _ = {};", migrations_list_concat)
1543+
} else {
1544+
format!("let _ = ({});", migrations_list_concat)
1545+
}
15241546
}
15251547

15261548
/// Helper function to determine if we need to escalate CaptureKind from

0 commit comments

Comments
 (0)