diff options
| author | bors <bors@rust-lang.org> | 2022-08-16 11:00:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-16 11:00:25 +0000 |
| commit | a39bdb1d6b9eaf23f2636baee0949d67890abcd8 (patch) | |
| tree | 134af937e12c013ef621e3972a60934f652d99ea /compiler | |
| parent | 14a459bf37bc19476d43e0045d078121c12d3fef (diff) | |
| parent | 15713e1717219be78c46234d2255fb105f87c02c (diff) | |
| download | rust-a39bdb1d6b9eaf23f2636baee0949d67890abcd8.tar.gz rust-a39bdb1d6b9eaf23f2636baee0949d67890abcd8.zip | |
Auto merge of #99612 - yanchen4791:issue-95079-fix, r=compiler-errors
Fix #95079 unhelpful error when missing move in nested closure Fix #95079 by adding help for missing move in nested closure
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index bd3a2a3d694..0dce5be953e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -546,6 +546,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { executing...", ); diag.note("...therefore, they cannot allow references to captured variables to escape"); + self.suggest_move_on_borrowing_closure(&mut diag); diag } @@ -716,6 +717,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); + self.suggest_move_on_borrowing_closure(&mut diag); diag } @@ -901,4 +903,39 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag); } + + fn suggest_move_on_borrowing_closure(&self, diag: &mut Diagnostic) { + let map = self.infcx.tcx.hir(); + let body_id = map.body_owned_by(self.mir_def_id()); + let expr = &map.body(body_id).value; + let mut closure_span = None::<rustc_span::Span>; + match expr.kind { + hir::ExprKind::MethodCall(.., args, _) => { + // only the first closre parameter of the method. args[0] is MethodCall PathSegment + for i in 1..args.len() { + if let hir::ExprKind::Closure(..) = args[i].kind { + closure_span = Some(args[i].span.shrink_to_lo()); + break; + } + } + } + hir::ExprKind::Block(blk, _) => { + if let Some(ref expr) = blk.expr { + // only when the block is a closure + if let hir::ExprKind::Closure(..) = expr.kind { + closure_span = Some(expr.span.shrink_to_lo()); + } + } + } + _ => {} + } + if let Some(closure_span) = closure_span { + diag.span_suggestion_verbose( + closure_span, + format!("consider adding 'move' keyword before the nested closure"), + "move ", + Applicability::MaybeIncorrect, + ); + } + } } |
