From 0b7ff9660f95daf752281220f48722061db60def Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 6 Jul 2021 16:48:49 -0400 Subject: [PATCH] Add note on why the variable is not fully captured --- compiler/rustc_typeck/src/check/upvar.rs | 92 ++++++++++++------- .../migrations/auto_traits.stderr | 3 + .../migrations/insignificant_drop.fixed | 11 +++ .../migrations/insignificant_drop.rs | 11 +++ .../migrations/insignificant_drop.stderr | 58 ++++++++---- .../insignificant_drop_attr_migrations.fixed | 2 + .../insignificant_drop_attr_migrations.rs | 2 + .../insignificant_drop_attr_migrations.stderr | 14 ++- .../migrations/migrations_rustfix.fixed | 3 + .../migrations/migrations_rustfix.rs | 3 + .../migrations/migrations_rustfix.stderr | 13 ++- .../migrations/mir_calls_to_shims.stderr | 1 + .../migrations/precise.stderr | 4 + .../migrations/significant_drop.fixed | 11 +++ .../migrations/significant_drop.rs | 11 +++ .../migrations/significant_drop.stderr | 63 +++++++++---- 16 files changed, 227 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 4d6d1da194f..106fea2b2f7 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -510,6 +510,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .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 "); let closure_body_span = self.tcx.hir().span(body_id.hir_id); let (sugg, app) = @@ -579,13 +590,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { var_hir_id: hir::HirId, check_trait: Option, closure_clause: hir::CaptureBy, - ) -> bool { + ) -> Option<(Option, String)> { let root_var_min_capture_list = if let Some(root_var_min_capture_list) = min_captures.and_then(|m| m.get(&var_hir_id)) { root_var_min_capture_list } else { - return false; + return None; }; 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); 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 @@ -660,68 +671,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, var_hir_id: hir::HirId, closure_clause: hir::CaptureBy, - ) -> Option> { + ) -> Option<(FxHashSet<&str>, FxHashSet<(Option, String)>)> { let tcx = self.infcx.tcx; // Check whether catpured fields also implement the trait 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, var_hir_id, tcx.lang_items().clone_trait(), closure_clause, ) { 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, var_hir_id, tcx.lang_items().sync_trait(), closure_clause, ) { 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, var_hir_id, tcx.get_diagnostic_item(sym::send_trait), closure_clause, ) { 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, var_hir_id, tcx.lang_items().unpin_trait(), closure_clause, ) { 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, var_hir_id, tcx.get_diagnostic_item(sym::unwind_safe_trait), closure_clause, ) { 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, var_hir_id, tcx.get_diagnostic_item(sym::ref_unwind_safe_trait), closure_clause, ) { auto_trait_reasons.insert("`RefUnwindSafe`"); + diagnostics_info.insert(info); } if auto_trait_reasons.len() > 0 { - return Some(auto_trait_reasons); + return Some((auto_trait_reasons, diagnostics_info)); } return None; @@ -746,11 +764,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, closure_clause: hir::CaptureBy, var_hir_id: hir::HirId, - ) -> bool { + ) -> Option, String)>> { 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())) { - return false; + return None; } 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 { // Only migrate if closure is a move closure - hir::CaptureBy::Value => return true, + hir::CaptureBy::Value => return Some(FxHashSet::default()), hir::CaptureBy::Ref => {} } - return false; + return None; }; - let projections_list = root_var_min_capture_list - .iter() - .filter_map(|captured_place| match captured_place.info.capture_kind { + let mut projections_list = Vec::new(); + let mut diagnostics_info = FxHashSet::default(); + + 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 - ty::UpvarCapture::ByValue(..) => Some(captured_place.place.projections.as_slice()), - ty::UpvarCapture::ByRef(..) => None, - }) - .collect::>(); + ty::UpvarCapture::ByValue(..) => { + projections_list.push(captured_place.place.projections.as_slice()); + diagnostics_info.insert(( + captured_place.info.path_expr_id, + captured_place.to_string(self.tcx), + )); + } + ty::UpvarCapture::ByRef(..) => {} + } + } let is_moved = !projections_list.is_empty(); @@ -793,10 +819,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ -820,7 +846,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_span: Span, closure_clause: hir::CaptureBy, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, - ) -> (Vec, String) { + ) -> (Vec<(hir::HirId, FxHashSet<(Option, String)>)>, String) { let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) { upvars } else { @@ -834,14 +860,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Perform auto-trait analysis for (&var_hir_id, _) in upvars.iter() { 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) { need_migration = true; 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_span, min_captures, @@ -850,10 +879,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { need_migration = true; drop_reorder_reason = true; + responsible_captured_hir_ids.extend(diagnostics_info); } 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. fn migration_suggestion_for_2229( tcx: TyCtxt<'_>, - need_migrations: &Vec, + need_migrations: &Vec<(hir::HirId, FxHashSet<(Option, String)>)>, ) -> (String, String) { let need_migrations_variables = - need_migrations.iter().map(|v| var_name(tcx, *v)).collect::>(); + need_migrations.iter().map(|(v, _)| var_name(tcx, *v)).collect::>(); let migration_ref_concat = need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::>().join(", "); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr index 3d3dde15412..39b9dc2e22f 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -6,6 +6,7 @@ LL | thread::spawn(move || unsafe { LL | | LL | | LL | | *fptr.0 = 20; + | | ------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0` LL | | }); | |_____^ | @@ -32,6 +33,7 @@ LL | thread::spawn(move || unsafe { LL | | LL | | LL | | *fptr.0.0 = 20; + | | --------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0` LL | | }); | |_____^ | @@ -53,6 +55,7 @@ LL | let c = || { LL | | LL | | 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 | | }; | |_____^ diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed index 51d9c4881af..71fa99997d3 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed @@ -18,8 +18,11 @@ fn test1_all_need_migration() { //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2.0; + //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` }; c(); @@ -37,7 +40,9 @@ fn test2_only_precise_paths_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2; }; @@ -54,6 +59,7 @@ fn test3_only_by_value_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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); }; @@ -73,6 +79,7 @@ fn test4_only_non_copy_types_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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; }; @@ -92,6 +99,7 @@ fn test5_only_drop_types_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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; }; @@ -108,6 +116,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured 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(); @@ -124,6 +134,7 @@ fn test7_drop_non_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs index c732cbb4fa5..a80aa92aa80 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs @@ -18,8 +18,11 @@ fn test1_all_need_migration() { //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2.0; + //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` }; c(); @@ -37,7 +40,9 @@ fn test2_only_precise_paths_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2; }; @@ -54,6 +59,7 @@ fn test3_only_by_value_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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); }; @@ -73,6 +79,7 @@ fn test4_only_non_copy_types_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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; }; @@ -92,6 +99,7 @@ fn test5_only_drop_types_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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; }; @@ -108,6 +116,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured 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(); @@ -124,6 +134,7 @@ fn test7_drop_non_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr index 89a2b0eb953..64708027383 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr @@ -6,8 +6,16 @@ LL | let c = || { 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; + | | ---- in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` +LL | | LL | | }; | |_____^ | @@ -28,14 +36,19 @@ LL | let _t = t.0; ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:35:13 + --> $DIR/insignificant_drop.rs:38:13 | LL | let c = || { | _____________^ 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 | | }; | |_____^ @@ -48,11 +61,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | let _t1 = t1.0; +LL | ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:52:13 + --> $DIR/insignificant_drop.rs:57:13 | LL | let c = || { | _____________^ @@ -60,6 +73,8 @@ 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 | | println!("{}", t1.1); LL | | }; | |_____^ @@ -72,11 +87,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | println!("{}", t1.1); +LL | ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:71:13 + --> $DIR/insignificant_drop.rs:77:13 | LL | let c = || { | _____________^ @@ -84,6 +99,8 @@ 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; LL | | }; | |_____^ @@ -96,11 +113,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | let _t1 = t1.0; +LL | ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:90:13 + --> $DIR/insignificant_drop.rs:97:13 | LL | let c = || { | _____________^ @@ -108,6 +125,8 @@ 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 _s = s.0; LL | | }; | |_____^ @@ -120,11 +139,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | let _s = s.0; +LL | ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:106:13 + --> $DIR/insignificant_drop.rs:114:13 | LL | let c = move || { | _____________^ @@ -132,6 +151,11 @@ LL | | LL | | LL | | 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 | | }; | |_____^ | @@ -143,11 +167,11 @@ LL | LL | LL | LL | println!("{} {}", t1.1, t.1); -LL | }; - | +LL | + ... error: drop order will change in Rust 2021 - --> $DIR/insignificant_drop.rs:122:13 + --> $DIR/insignificant_drop.rs:132:13 | LL | let c = || { | _____________^ @@ -155,6 +179,8 @@ 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 | | }; | |_____^ | @@ -166,8 +192,8 @@ LL | LL | LL | LL | let _t = t.0; -LL | }; - | +LL | + ... error: aborting due to 7 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed index 8c85cd990d3..f150bd8cc9c 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed @@ -39,6 +39,7 @@ fn significant_drop_needs_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -57,6 +58,7 @@ fn generic_struct_with_significant_drop_needs_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs index 17cee28e311..03c0ab959b2 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs @@ -39,6 +39,7 @@ fn significant_drop_needs_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -57,6 +58,7 @@ fn generic_struct_with_significant_drop_needs_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr index 1d3bda03d0e..478b331f7fa 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr @@ -7,6 +7,8 @@ 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 | | }; | |_____^ | @@ -23,11 +25,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | }; - | +LL | + ... 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 || { | _____________^ @@ -35,6 +37,8 @@ LL | | LL | | LL | | LL | | let _t = t.1; + | | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` +LL | | LL | | }; | |_____^ | @@ -46,8 +50,8 @@ LL | LL | LL | LL | let _t = t.1; -LL | }; - | +LL | + ... error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed index c974299c153..a4a38d47500 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed @@ -21,6 +21,8 @@ fn closure_contains_block() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` + }; c(); @@ -30,6 +32,7 @@ fn closure_doesnt_contain_block() { let t = (Foo(0), Foo(0)); let c = || { let _ = &t; t.0 }; //~^ 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 //~| HELP: add a dummy let to cause `t` to be fully captured diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs index dd9556aa567..01a47dffd85 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs @@ -21,6 +21,8 @@ fn closure_contains_block() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` + }; c(); @@ -30,6 +32,7 @@ fn closure_doesnt_contain_block() { let t = (Foo(0), Foo(0)); let c = || t.0; //~^ 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 //~| HELP: add a dummy let to cause `t` to be fully captured diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr index 2d5e5e5e55c..58109128c2c 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr @@ -7,6 +7,9 @@ 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 | | LL | | }; | |_____^ | @@ -23,14 +26,16 @@ LL | LL | LL | LL | let _t = t.0; -LL | }; - | +LL | + ... 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; - | ^^^^^^ + | ^^^--- + | | + | in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` | = note: for more information, see help: add a dummy let to cause `t` to be fully captured diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr index dca5c454b83..2513ceecc69 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr @@ -6,6 +6,7 @@ LL | let result = panic::catch_unwind(move || { LL | | LL | | LL | | f.0() + | | --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.0` LL | | }); | |_____^ | diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr index 2788207296f..09829123db3 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -6,6 +6,7 @@ LL | let c = || { 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 | | let _t = &t.1; LL | | }; | |_____^ @@ -34,8 +35,11 @@ LL | let c = || { LL | | LL | | 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; + | | ----- in Rust 2018, closure captures all of `u`, but in Rust 2021, it only captures `u.0.1` 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 | | }; | |_____^ | diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed index 58ed2de26b3..5bdefb6762e 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed @@ -27,8 +27,11 @@ fn test1_all_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2.0; + //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` }; c(); @@ -46,7 +49,9 @@ fn test2_only_precise_paths_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2; }; @@ -63,6 +68,7 @@ fn test3_only_by_value_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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); }; @@ -81,6 +87,7 @@ fn test4_type_contains_drop_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -97,6 +104,7 @@ fn test5_drop_non_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -111,6 +119,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` }; c(); @@ -127,6 +136,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured 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(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs index 0890fc1c212..44119a76e14 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs @@ -27,8 +27,11 @@ fn test1_all_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2.0; + //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` }; c(); @@ -46,7 +49,9 @@ fn test2_only_precise_paths_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured 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; + //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0` let _t2 = t2; }; @@ -63,6 +68,7 @@ fn test3_only_by_value_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured 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); }; @@ -81,6 +87,7 @@ fn test4_type_contains_drop_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -97,6 +104,7 @@ fn test5_drop_non_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0` }; c(); @@ -111,6 +119,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; + //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` }; c(); @@ -127,6 +136,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() { //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured 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(); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr index ebf9f169fd4..fa4903b76ba 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr @@ -6,8 +6,15 @@ LL | let c = || { 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; + | | ---- in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0` +LL | | LL | | }; | |_____^ | @@ -24,18 +31,23 @@ LL | LL | LL | LL | let _t = t.0; -LL | let _t1 = t1.0; +LL | ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:44:13 + --> $DIR/significant_drop.rs:47:13 | LL | let c = || { | _____________^ 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 | | }; | |_____^ @@ -48,11 +60,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | let _t1 = t1.0; +LL | ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:61:13 + --> $DIR/significant_drop.rs:66:13 | LL | let c = || { | _____________^ @@ -60,6 +72,8 @@ 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 | | println!("{:?}", t1.1); LL | | }; | |_____^ @@ -72,11 +86,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | println!("{:?}", t1.1); +LL | ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:79:13 + --> $DIR/significant_drop.rs:85:13 | LL | let c = || { | _____________^ @@ -84,6 +98,8 @@ 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 | | }; | |_____^ | @@ -95,11 +111,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | }; - | +LL | + ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:95:13 + --> $DIR/significant_drop.rs:102:13 | LL | let c = || { | _____________^ @@ -107,6 +123,8 @@ 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 | | }; | |_____^ | @@ -118,11 +136,11 @@ LL | LL | LL | LL | let _t = t.0; -LL | }; - | +LL | + ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:109:13 + --> $DIR/significant_drop.rs:117:13 | LL | let c = || { | _____________^ @@ -130,6 +148,8 @@ LL | | LL | | LL | | LL | | let _t = t.1; + | | --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1` +LL | | LL | | }; | |_____^ | @@ -141,11 +161,11 @@ LL | LL | LL | LL | let _t = t.1; -LL | }; - | +LL | + ... error: drop order will change in Rust 2021 - --> $DIR/significant_drop.rs:125:13 + --> $DIR/significant_drop.rs:134:13 | LL | let c = move || { | _____________^ @@ -153,6 +173,11 @@ LL | | LL | | LL | | 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 | | }; | |_____^ | @@ -164,8 +189,8 @@ LL | LL | LL | LL | println!("{:?} {:?}", t1.1, t.1); -LL | }; - | +LL | + ... error: aborting due to 7 previous errors