1
Fork 0

Add note on why the variable is not fully captured

This commit is contained in:
Roxane 2021-07-06 16:48:49 -04:00
parent ee86f96ba1
commit 0b7ff9660f
16 changed files with 227 additions and 75 deletions

View file

@ -510,6 +510,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) )
.as_str(), .as_str(),
); );
for (var_hir_id, diagnostics_info) in need_migrations.iter() {
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);
diagnostics_builder.span_label(cause_span, format!("in Rust 2018, closure captures all of `{}`, but in Rust 2021, it only captures `{}`",
self.tcx.hir().name(*var_hir_id),
captured_name,
));
}
}
}
diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); 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); let closure_body_span = self.tcx.hir().span(body_id.hir_id);
let (sugg, app) = let (sugg, app) =
@ -579,13 +590,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
var_hir_id: hir::HirId, var_hir_id: hir::HirId,
check_trait: Option<DefId>, check_trait: Option<DefId>,
closure_clause: hir::CaptureBy, closure_clause: hir::CaptureBy,
) -> bool { ) -> Option<(Option<hir::HirId>, String)> {
let root_var_min_capture_list = if let Some(root_var_min_capture_list) = let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
min_captures.and_then(|m| m.get(&var_hir_id)) min_captures.and_then(|m| m.get(&var_hir_id))
{ {
root_var_min_capture_list root_var_min_capture_list
} else { } else {
return false; return None;
}; };
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id)); let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
@ -639,10 +650,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or(false); .unwrap_or(false);
if !obligation_holds_for_capture && obligation_should_hold { if !obligation_holds_for_capture && obligation_should_hold {
return true; return Some((capture.info.path_expr_id, capture.to_string(self.tcx)));
} }
} }
false None
} }
/// Figures out the list of root variables (and their types) that aren't completely /// Figures out the list of root variables (and their types) that aren't completely
@ -660,68 +671,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
var_hir_id: hir::HirId, var_hir_id: hir::HirId,
closure_clause: hir::CaptureBy, closure_clause: hir::CaptureBy,
) -> Option<FxHashSet<&str>> { ) -> Option<(FxHashSet<&str>, FxHashSet<(Option<hir::HirId>, String)>)> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
// Check whether catpured fields also implement the trait // Check whether catpured fields also implement the trait
let mut auto_trait_reasons = FxHashSet::default(); let mut auto_trait_reasons = FxHashSet::default();
let mut diagnostics_info = FxHashSet::default();
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.lang_items().clone_trait(), tcx.lang_items().clone_trait(),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`Clone`"); auto_trait_reasons.insert("`Clone`");
diagnostics_info.insert(info);
} }
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.lang_items().sync_trait(), tcx.lang_items().sync_trait(),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`Sync`"); auto_trait_reasons.insert("`Sync`");
diagnostics_info.insert(info);
} }
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.get_diagnostic_item(sym::send_trait), tcx.get_diagnostic_item(sym::send_trait),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`Send`"); auto_trait_reasons.insert("`Send`");
diagnostics_info.insert(info);
} }
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.lang_items().unpin_trait(), tcx.lang_items().unpin_trait(),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`Unpin`"); auto_trait_reasons.insert("`Unpin`");
diagnostics_info.insert(info);
} }
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.get_diagnostic_item(sym::unwind_safe_trait), tcx.get_diagnostic_item(sym::unwind_safe_trait),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`UnwindSafe`"); auto_trait_reasons.insert("`UnwindSafe`");
diagnostics_info.insert(info);
} }
if self.need_2229_migrations_for_trait( if let Some(info) = self.need_2229_migrations_for_trait(
min_captures, min_captures,
var_hir_id, var_hir_id,
tcx.get_diagnostic_item(sym::ref_unwind_safe_trait), tcx.get_diagnostic_item(sym::ref_unwind_safe_trait),
closure_clause, closure_clause,
) { ) {
auto_trait_reasons.insert("`RefUnwindSafe`"); auto_trait_reasons.insert("`RefUnwindSafe`");
diagnostics_info.insert(info);
} }
if auto_trait_reasons.len() > 0 { if auto_trait_reasons.len() > 0 {
return Some(auto_trait_reasons); return Some((auto_trait_reasons, diagnostics_info));
} }
return None; return None;
@ -746,11 +764,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
closure_clause: hir::CaptureBy, closure_clause: hir::CaptureBy,
var_hir_id: hir::HirId, var_hir_id: hir::HirId,
) -> bool { ) -> Option<FxHashSet<(Option<hir::HirId>, String)>> {
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id)); let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) { if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
return false; return None;
} }
let root_var_min_capture_list = if let Some(root_var_min_capture_list) = let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
@ -763,21 +781,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match closure_clause { match closure_clause {
// Only migrate if closure is a move closure // Only migrate if closure is a move closure
hir::CaptureBy::Value => return true, hir::CaptureBy::Value => return Some(FxHashSet::default()),
hir::CaptureBy::Ref => {} hir::CaptureBy::Ref => {}
} }
return false; return None;
}; };
let projections_list = root_var_min_capture_list let mut projections_list = Vec::new();
.iter() let mut diagnostics_info = FxHashSet::default();
.filter_map(|captured_place| match captured_place.info.capture_kind {
for captured_place in root_var_min_capture_list.iter() {
match captured_place.info.capture_kind {
// Only care about captures that are moved into the closure // Only care about captures that are moved into the closure
ty::UpvarCapture::ByValue(..) => Some(captured_place.place.projections.as_slice()), ty::UpvarCapture::ByValue(..) => {
ty::UpvarCapture::ByRef(..) => None, projections_list.push(captured_place.place.projections.as_slice());
}) diagnostics_info.insert((
.collect::<Vec<_>>(); captured_place.info.path_expr_id,
captured_place.to_string(self.tcx),
));
}
ty::UpvarCapture::ByRef(..) => {}
}
}
let is_moved = !projections_list.is_empty(); let is_moved = !projections_list.is_empty();
@ -793,10 +819,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
projections_list, projections_list,
) )
{ {
return true; return Some(diagnostics_info);
} }
return false; return None;
} }
/// Figures out the list of root variables (and their types) that aren't completely /// Figures out the list of root variables (and their types) that aren't completely
@ -820,7 +846,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_span: Span, closure_span: Span,
closure_clause: hir::CaptureBy, closure_clause: hir::CaptureBy,
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> (Vec<hir::HirId>, String) { ) -> (Vec<(hir::HirId, FxHashSet<(Option<hir::HirId>, String)>)>, String) {
let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) { let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
upvars upvars
} else { } else {
@ -834,14 +860,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Perform auto-trait analysis // Perform auto-trait analysis
for (&var_hir_id, _) in upvars.iter() { for (&var_hir_id, _) in upvars.iter() {
let mut need_migration = false; let mut need_migration = false;
if let Some(trait_migration_cause) = let mut responsible_captured_hir_ids = FxHashSet::default();
if let Some((trait_migration_cause, diagnostics_info)) =
self.compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause) self.compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause)
{ {
need_migration = true; need_migration = true;
auto_trait_reasons.extend(trait_migration_cause); auto_trait_reasons.extend(trait_migration_cause);
responsible_captured_hir_ids.extend(diagnostics_info);
} }
if self.compute_2229_migrations_for_drop( if let Some(diagnostics_info) = self.compute_2229_migrations_for_drop(
closure_def_id, closure_def_id,
closure_span, closure_span,
min_captures, min_captures,
@ -850,10 +879,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) { ) {
need_migration = true; need_migration = true;
drop_reorder_reason = true; drop_reorder_reason = true;
responsible_captured_hir_ids.extend(diagnostics_info);
} }
if need_migration { if need_migration {
need_migrations.push(var_hir_id); need_migrations.push((var_hir_id, responsible_captured_hir_ids));
} }
} }
@ -1877,10 +1907,10 @@ fn should_do_rust_2021_incompatible_closure_captures_analysis(
/// - s2: Comma separated names of the variables being migrated. /// - s2: Comma separated names of the variables being migrated.
fn migration_suggestion_for_2229( fn migration_suggestion_for_2229(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
need_migrations: &Vec<hir::HirId>, need_migrations: &Vec<(hir::HirId, FxHashSet<(Option<hir::HirId>, String)>)>,
) -> (String, String) { ) -> (String, String) {
let need_migrations_variables = let need_migrations_variables =
need_migrations.iter().map(|v| var_name(tcx, *v)).collect::<Vec<_>>(); need_migrations.iter().map(|(v, _)| var_name(tcx, *v)).collect::<Vec<_>>();
let migration_ref_concat = let migration_ref_concat =
need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", "); need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", ");

View file

@ -6,6 +6,7 @@ LL | thread::spawn(move || unsafe {
LL | | LL | |
LL | | LL | |
LL | | *fptr.0 = 20; LL | | *fptr.0 = 20;
| | ------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
LL | | }); LL | | });
| |_____^ | |_____^
| |
@ -32,6 +33,7 @@ LL | thread::spawn(move || unsafe {
LL | | LL | |
LL | | LL | |
LL | | *fptr.0.0 = 20; LL | | *fptr.0.0 = 20;
| | --------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
LL | | }); LL | | });
| |_____^ | |_____^
| |
@ -53,6 +55,7 @@ LL | let c = || {
LL | | LL | |
LL | | LL | |
LL | | let f_1 = f.1; LL | | let f_1 = f.1;
| | --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
LL | | println!("{:?}", f_1.0); LL | | println!("{:?}", f_1.0);
LL | | }; LL | | };
| |_____^ | |_____^

View file

@ -18,8 +18,11 @@ fn test1_all_need_migration() {
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2.0; let _t2 = t2.0;
//~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
}; };
c(); c();
@ -37,7 +40,9 @@ fn test2_only_precise_paths_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2; let _t2 = t2;
}; };
@ -54,6 +59,7 @@ fn test3_only_by_value_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
println!("{}", t1.1); println!("{}", t1.1);
}; };
@ -73,6 +79,7 @@ fn test4_only_non_copy_types_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
}; };
@ -92,6 +99,7 @@ fn test5_only_drop_types_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _s = s.0; let _s = s.0;
}; };
@ -108,6 +116,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t1`, `t` to be fully captured //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
println!("{} {}", t1.1, t.1); println!("{} {}", t1.1, t.1);
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
//~| NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
}; };
c(); c();
@ -124,6 +134,7 @@ fn test7_drop_non_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();

View file

@ -18,8 +18,11 @@ fn test1_all_need_migration() {
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2.0; let _t2 = t2.0;
//~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
}; };
c(); c();
@ -37,7 +40,9 @@ fn test2_only_precise_paths_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2; let _t2 = t2;
}; };
@ -54,6 +59,7 @@ fn test3_only_by_value_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
println!("{}", t1.1); println!("{}", t1.1);
}; };
@ -73,6 +79,7 @@ fn test4_only_non_copy_types_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
}; };
@ -92,6 +99,7 @@ fn test5_only_drop_types_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _s = s.0; let _s = s.0;
}; };
@ -108,6 +116,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t1`, `t` to be fully captured //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
println!("{} {}", t1.1, t.1); println!("{} {}", t1.1, t.1);
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
//~| NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
}; };
c(); c();
@ -124,6 +134,7 @@ fn test7_drop_non_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();

View file

@ -6,8 +6,16 @@ LL | let c = || {
LL | | LL | |
LL | | LL | |
LL | | LL | |
... | LL | |
LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _t1 = t1.0;
| | ---- in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
LL | |
LL | | let _t2 = t2.0; LL | | let _t2 = t2.0;
| | ---- in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -28,14 +36,19 @@ LL | let _t = t.0;
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:35:13 --> $DIR/insignificant_drop.rs:38:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
LL | | LL | |
LL | | LL | |
LL | | LL | |
... | LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _t1 = t1.0;
| | ---- in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
LL | |
LL | | let _t2 = t2; LL | | let _t2 = t2;
LL | | }; LL | | };
| |_____^ | |_____^
@ -48,11 +61,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | let _t1 = t1.0; LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:52:13 --> $DIR/insignificant_drop.rs:57:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -60,6 +73,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | println!("{}", t1.1); LL | | println!("{}", t1.1);
LL | | }; LL | | };
| |_____^ | |_____^
@ -72,11 +87,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | println!("{}", t1.1); LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:71:13 --> $DIR/insignificant_drop.rs:77:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -84,6 +99,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _t1 = t1.0; LL | | let _t1 = t1.0;
LL | | }; LL | | };
| |_____^ | |_____^
@ -96,11 +113,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | let _t1 = t1.0; LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:90:13 --> $DIR/insignificant_drop.rs:97:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -108,6 +125,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _s = s.0; LL | | let _s = s.0;
LL | | }; LL | | };
| |_____^ | |_____^
@ -120,11 +139,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | let _s = s.0; LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:106:13 --> $DIR/insignificant_drop.rs:114:13
| |
LL | let c = move || { LL | let c = move || {
| _____________^ | _____________^
@ -132,6 +151,11 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | println!("{} {}", t1.1, t.1); LL | | println!("{} {}", t1.1, t.1);
| | ---- --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
| | |
| | in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
LL | |
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -143,11 +167,11 @@ LL |
LL | LL |
LL | LL |
LL | println!("{} {}", t1.1, t.1); LL | println!("{} {}", t1.1, t.1);
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop.rs:122:13 --> $DIR/insignificant_drop.rs:132:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -155,6 +179,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -166,8 +192,8 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | }; LL |
| ...
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -39,6 +39,7 @@ fn significant_drop_needs_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -57,6 +58,7 @@ fn generic_struct_with_significant_drop_needs_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.1; let _t = t.1;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();

View file

@ -39,6 +39,7 @@ fn significant_drop_needs_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -57,6 +58,7 @@ fn generic_struct_with_significant_drop_needs_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.1; let _t = t.1;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();

View file

@ -7,6 +7,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -23,11 +25,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/insignificant_drop_attr_migrations.rs:55:13 --> $DIR/insignificant_drop_attr_migrations.rs:56:13
| |
LL | let c = move || { LL | let c = move || {
| _____________^ | _____________^
@ -35,6 +37,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.1; LL | | let _t = t.1;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -46,8 +50,8 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.1; LL | let _t = t.1;
LL | }; LL |
| ...
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -21,6 +21,8 @@ fn closure_contains_block() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -30,6 +32,7 @@ fn closure_doesnt_contain_block() {
let t = (Foo(0), Foo(0)); let t = (Foo(0), Foo(0));
let c = || { let _ = &t; t.0 }; let c = || { let _ = &t; t.0 };
//~^ ERROR: drop order //~^ ERROR: drop order
//~| NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured

View file

@ -21,6 +21,8 @@ fn closure_contains_block() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -30,6 +32,7 @@ fn closure_doesnt_contain_block() {
let t = (Foo(0), Foo(0)); let t = (Foo(0), Foo(0));
let c = || t.0; let c = || t.0;
//~^ ERROR: drop order //~^ ERROR: drop order
//~| NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured

View file

@ -7,6 +7,9 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -23,14 +26,16 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/migrations_rustfix.rs:31:13 --> $DIR/migrations_rustfix.rs:33:13
| |
LL | let c = || t.0; LL | let c = || t.0;
| ^^^^^^ | ^^^---
| |
| in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
| |
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured help: add a dummy let to cause `t` to be fully captured

View file

@ -6,6 +6,7 @@ LL | let result = panic::catch_unwind(move || {
LL | | LL | |
LL | | LL | |
LL | | f.0() LL | | f.0()
| | --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.0`
LL | | }); LL | | });
| |_____^ | |_____^
| |

View file

@ -6,6 +6,7 @@ LL | let c = || {
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | | let _t = &t.1; LL | | let _t = &t.1;
LL | | }; LL | | };
| |_____^ | |_____^
@ -34,8 +35,11 @@ LL | let c = || {
LL | | LL | |
LL | | LL | |
LL | | let _x = u.0.0; LL | | let _x = u.0.0;
| | ----- in Rust 2018, closure captures all of `u`, but in Rust 2021, it only captures `u.0.0`
LL | | let _x = u.0.1; LL | | let _x = u.0.1;
| | ----- in Rust 2018, closure captures all of `u`, but in Rust 2021, it only captures `u.0.1`
LL | | let _x = u.1.0; LL | | let _x = u.1.0;
| | ----- in Rust 2018, closure captures all of `u`, but in Rust 2021, it only captures `u.1.0`
LL | | }; LL | | };
| |_____^ | |_____^
| |

View file

@ -27,8 +27,11 @@ fn test1_all_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2.0; let _t2 = t2.0;
//~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
}; };
c(); c();
@ -46,7 +49,9 @@ fn test2_only_precise_paths_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2; let _t2 = t2;
}; };
@ -63,6 +68,7 @@ fn test3_only_by_value_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
println!("{:?}", t1.1); println!("{:?}", t1.1);
}; };
@ -81,6 +87,7 @@ fn test4_type_contains_drop_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -97,6 +104,7 @@ fn test5_drop_non_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -111,6 +119,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.1; let _t = t.1;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();
@ -127,6 +136,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t1`, `t` to be fully captured //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
println!("{:?} {:?}", t1.1, t.1); println!("{:?} {:?}", t1.1, t.1);
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
//~| NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();

View file

@ -27,8 +27,11 @@ fn test1_all_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2.0; let _t2 = t2.0;
//~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
}; };
c(); c();
@ -46,7 +49,9 @@ fn test2_only_precise_paths_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t`, `t1` to be fully captured //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
let _t1 = t1.0; let _t1 = t1.0;
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
let _t2 = t2; let _t2 = t2;
}; };
@ -63,6 +68,7 @@ fn test3_only_by_value_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
println!("{:?}", t1.1); println!("{:?}", t1.1);
}; };
@ -81,6 +87,7 @@ fn test4_type_contains_drop_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -97,6 +104,7 @@ fn test5_drop_non_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.0; let _t = t.0;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
}; };
c(); c();
@ -111,6 +119,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t` to be fully captured //~| HELP: add a dummy let to cause `t` to be fully captured
let _t = t.1; let _t = t.1;
//~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();
@ -127,6 +136,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
//~| NOTE: for more information, see //~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `t1`, `t` to be fully captured //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
println!("{:?} {:?}", t1.1, t.1); println!("{:?} {:?}", t1.1, t.1);
//~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
//~| NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
}; };
c(); c();

View file

@ -6,8 +6,15 @@ LL | let c = || {
LL | | LL | |
LL | | LL | |
LL | | LL | |
... | LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _t1 = t1.0;
| | ---- in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
LL | |
LL | | let _t2 = t2.0; LL | | let _t2 = t2.0;
| | ---- in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -24,18 +31,23 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | let _t1 = t1.0; LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:44:13 --> $DIR/significant_drop.rs:47:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
LL | | LL | |
LL | | LL | |
LL | | LL | |
... | LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | let _t1 = t1.0;
| | ---- in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
LL | |
LL | | let _t2 = t2; LL | | let _t2 = t2;
LL | | }; LL | | };
| |_____^ | |_____^
@ -48,11 +60,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | let _t1 = t1.0; LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:61:13 --> $DIR/significant_drop.rs:66:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -60,6 +72,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | println!("{:?}", t1.1); LL | | println!("{:?}", t1.1);
LL | | }; LL | | };
| |_____^ | |_____^
@ -72,11 +86,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | println!("{:?}", t1.1); LL |
... ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:79:13 --> $DIR/significant_drop.rs:85:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -84,6 +98,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -95,11 +111,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:95:13 --> $DIR/significant_drop.rs:102:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -107,6 +123,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.0; LL | | let _t = t.0;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -118,11 +136,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.0; LL | let _t = t.0;
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:109:13 --> $DIR/significant_drop.rs:117:13
| |
LL | let c = || { LL | let c = || {
| _____________^ | _____________^
@ -130,6 +148,8 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | let _t = t.1; LL | | let _t = t.1;
| | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -141,11 +161,11 @@ LL |
LL | LL |
LL | LL |
LL | let _t = t.1; LL | let _t = t.1;
LL | }; LL |
| ...
error: drop order will change in Rust 2021 error: drop order will change in Rust 2021
--> $DIR/significant_drop.rs:125:13 --> $DIR/significant_drop.rs:134:13
| |
LL | let c = move || { LL | let c = move || {
| _____________^ | _____________^
@ -153,6 +173,11 @@ LL | |
LL | | LL | |
LL | | LL | |
LL | | println!("{:?} {:?}", t1.1, t.1); LL | | println!("{:?} {:?}", t1.1, t.1);
| | ---- --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
| | |
| | in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
LL | |
LL | |
LL | | }; LL | | };
| |_____^ | |_____^
| |
@ -164,8 +189,8 @@ LL |
LL | LL |
LL | LL |
LL | println!("{:?} {:?}", t1.1, t.1); LL | println!("{:?} {:?}", t1.1, t.1);
LL | }; LL |
| ...
error: aborting due to 7 previous errors error: aborting due to 7 previous errors