diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 6a21e0025884..8c2a5f19038b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -73,7 +73,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) .or_else(|| { self.give_name_if_anonymous_region_appears_in_output( - infcx.tcx, mir, mir_def_id, fr, counter, diag) + infcx, mir, mir_def_id, fr, counter, diag) }) .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr)) } @@ -577,38 +577,51 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// or be early bound (named, not in argument). fn give_name_if_anonymous_region_appears_in_output( &self, - tcx: TyCtxt<'_, '_, 'tcx>, + infcx: &InferCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>, mir_def_id: DefId, fr: RegionVid, counter: &mut usize, diag: &mut DiagnosticBuilder<'_>, ) -> Option { + let tcx = infcx.tcx; + let return_ty = self.universal_regions.unnormalized_output_ty; debug!( "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty ); - if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { + if !infcx.tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; } - let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir"); - let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) + let type_name = with_highlight_region(fr, *counter, || { + infcx.extract_type_name(&return_ty) + }); + + let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir"); + + let (return_span, mir_description) = if let hir::ExprKind::Closure(_, _, _, span, gen_move) = tcx.hir.expect_expr(mir_node_id).node { - span + ( + tcx.sess.codemap().end_point(span), + if gen_move.is_some() { " of generator" } else { " of closure" } + ) } else { - mir.span + // unreachable? + (mir.span, "") }; - let region_name = self.synthesize_region_name(counter); diag.span_label( - args_span, - format!("lifetime `{}` appears in return type", region_name), + return_span, + format!("return type{} is {}", mir_description, type_name), ); - Some(region_name) + // This counter value will already have been used, so this function will increment it + // so the next value will be used next and return the region name that would have been + // used. + Some(self.synthesize_region_name(counter)) } /// Create a synthetic region named `'1`, incrementing the diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr index 27a51cb83fb2..3f9104373d6e 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr @@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints --> $DIR/E0621-does-not-trigger-for-closures.rs:25:26 | LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495 - | ------ ^^^^^ requires that `'1` must outlive `'2` - | | | - | | has type `&'1 i32` - | lifetime `'2` appears in return type + | -- ^^^^^ requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 i32 + | has type `&'1 i32` error: aborting due to previous error diff --git a/src/test/ui/issue-40510-1.nll.stderr b/src/test/ui/issue-40510-1.nll.stderr index 7eb6a0e7fb22..6c77bcb27572 100644 --- a/src/test/ui/issue-40510-1.nll.stderr +++ b/src/test/ui/issue-40510-1.nll.stderr @@ -3,9 +3,9 @@ error: unsatisfied lifetime constraints | LL | || { | -- - | | + | || + | |return type of closure is &'2 mut std::boxed::Box<()> | lifetime `'1` represents this closure's body - | lifetime `'2` appears in return type LL | &mut x | ^^^^^^ return requires that `'1` must outlive `'2` | diff --git a/src/test/ui/issue-40510-3.nll.stderr b/src/test/ui/issue-40510-3.nll.stderr index ae3ae3a27ab2..8aeef86c2e86 100644 --- a/src/test/ui/issue-40510-3.nll.stderr +++ b/src/test/ui/issue-40510-3.nll.stderr @@ -3,9 +3,9 @@ error: unsatisfied lifetime constraints | LL | || { | -- - | | + | || + | |return type of closure is [closure@$DIR/issue-40510-3.rs:18:9: 20:10 x:&'2 mut std::vec::Vec<()>] | lifetime `'1` represents this closure's body - | lifetime `'2` appears in return type LL | / || { LL | | x.push(()) LL | | } diff --git a/src/test/ui/issue-49824.nll.stderr b/src/test/ui/issue-49824.nll.stderr index 432036c9d90c..fb4bed76a717 100644 --- a/src/test/ui/issue-49824.nll.stderr +++ b/src/test/ui/issue-49824.nll.stderr @@ -3,9 +3,9 @@ error: unsatisfied lifetime constraints | LL | || { | -- - | | + | || + | |return type of closure is [closure@$DIR/issue-49824.rs:22:9: 24:10 x:&'2 mut i32] | lifetime `'1` represents this closure's body - | lifetime `'2` appears in return type LL | / || { LL | | let _y = &mut x; LL | | } diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr index 4baa90444246..84d0730025a5 100644 --- a/src/test/ui/nll/issue-48238.stderr +++ b/src/test/ui/nll/issue-48238.stderr @@ -3,9 +3,9 @@ error: unsatisfied lifetime constraints | LL | move || use_val(&orig); //~ ERROR | ------- ^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - | | + | | | + | | return type of closure is &'2 u8 | lifetime `'1` represents this closure's body - | lifetime `'2` appears in return type | = note: closure implements `Fn`, so references to captured variables can't escape the closure