|  | 
| 1 | 1 | #![allow(rustc::diagnostic_outside_of_impl)] | 
| 2 | 2 | #![allow(rustc::untranslatable_diagnostic)] | 
| 3 | 3 | 
 | 
|  | 4 | +use rustc_errors::Applicability; | 
| 4 | 5 | use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxtHandle}; | 
|  | 6 | +use rustc_hir as hir; | 
| 5 | 7 | use rustc_middle::span_bug; | 
| 6 | 8 | use rustc_middle::ty::{self, Ty, TyCtxt}; | 
| 7 | 9 | use rustc_span::Span; | 
| @@ -382,13 +384,35 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { | 
| 382 | 384 |         yield_span: Span, | 
| 383 | 385 |     ) -> Diag<'infcx> { | 
| 384 | 386 |         let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; | 
| 385 |  | -        struct_span_code_err!( | 
|  | 387 | +        let mut diag = struct_span_code_err!( | 
| 386 | 388 |             self.dcx(), | 
| 387 | 389 |             span, | 
| 388 | 390 |             E0626, | 
| 389 | 391 |             "borrow may still be in use when {coroutine_kind:#} yields", | 
| 390 |  | -        ) | 
| 391 |  | -        .with_span_label(yield_span, "possible yield occurs here") | 
|  | 392 | +        ); | 
|  | 393 | +        diag.span_label( | 
|  | 394 | +            self.infcx.tcx.def_span(self.body.source.def_id()), | 
|  | 395 | +            format!("within this {coroutine_kind:#}"), | 
|  | 396 | +        ); | 
|  | 397 | +        diag.span_label(yield_span, "possible yield occurs here"); | 
|  | 398 | +        if matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_)) { | 
|  | 399 | +            let hir::Closure { capture_clause, fn_decl_span, .. } = self | 
|  | 400 | +                .infcx | 
|  | 401 | +                .tcx | 
|  | 402 | +                .hir_node_by_def_id(self.body.source.def_id().expect_local()) | 
|  | 403 | +                .expect_closure(); | 
|  | 404 | +            let span = match capture_clause { | 
|  | 405 | +                rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(), | 
|  | 406 | +                rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(), | 
|  | 407 | +            }; | 
|  | 408 | +            diag.span_suggestion_verbose( | 
|  | 409 | +                span, | 
|  | 410 | +                "add `static` to mark this coroutine as unmovable", | 
|  | 411 | +                "static ", | 
|  | 412 | +                Applicability::MaybeIncorrect, | 
|  | 413 | +            ); | 
|  | 414 | +        } | 
|  | 415 | +        diag | 
| 392 | 416 |     } | 
| 393 | 417 | 
 | 
| 394 | 418 |     pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> { | 
|  | 
0 commit comments