diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index c906ed3129d..8191dd720e7 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -310,9 +310,19 @@ impl<'tcx> RegionInferenceContext<'tcx> { "captured variable cannot escape `FnMut` closure body", ); + // We should check if the return type of this closure is in fact a closure - in that + // case, we can special case the error further. + let return_type_is_closure = self.universal_regions.unnormalized_output_ty.is_closure(); + let message = if return_type_is_closure { + "returns a closure that contains a reference to a captured variable, which then \ + escapes the closure body" + } else { + "returns a reference to a captured variable which escapes the closure body" + }; + diag.span_label( span, - "creates a reference to a captured variable which escapes the closure body", + message, ); match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1).source { diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr index c2fd674d56c..5721c52ba21 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr @@ -32,7 +32,7 @@ LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than LL | | *y = 1; LL | | drop(y); LL | | } - | |_________________^ creates a reference to a captured variable which escapes the closure body + | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr index c2fd674d56c..5721c52ba21 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr @@ -32,7 +32,7 @@ LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than LL | | *y = 1; LL | | drop(y); LL | | } - | |_________________^ creates a reference to a captured variable which escapes the closure body + | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape diff --git a/src/test/ui/issues/issue-40510-1.nll.stderr b/src/test/ui/issues/issue-40510-1.nll.stderr index c5a6934484e..1aeb1a89ead 100644 --- a/src/test/ui/issues/issue-40510-1.nll.stderr +++ b/src/test/ui/issues/issue-40510-1.nll.stderr @@ -4,7 +4,7 @@ error: captured variable cannot escape `FnMut` closure body LL | || { | - inferred to be a `FnMut` closure LL | &mut x - | ^^^^^^ creates a reference to a captured variable which escapes the closure body + | ^^^^^^ returns a reference to a captured variable which escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape diff --git a/src/test/ui/issues/issue-40510-3.nll.stderr b/src/test/ui/issues/issue-40510-3.nll.stderr index f0a88fa1cdf..c334e592fbc 100644 --- a/src/test/ui/issues/issue-40510-3.nll.stderr +++ b/src/test/ui/issues/issue-40510-3.nll.stderr @@ -6,7 +6,7 @@ LL | || { LL | / || { LL | | x.push(()) LL | | } - | |_________^ creates a reference to a captured variable which escapes the closure body + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape diff --git a/src/test/ui/issues/issue-49824.nll.stderr b/src/test/ui/issues/issue-49824.nll.stderr index c95e8169176..2e0463fdd1d 100644 --- a/src/test/ui/issues/issue-49824.nll.stderr +++ b/src/test/ui/issues/issue-49824.nll.stderr @@ -6,7 +6,7 @@ LL | || { LL | / || { LL | | let _y = &mut x; LL | | } - | |_________^ creates a reference to a captured variable which escapes the closure body + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape diff --git a/src/test/ui/nll/issue-53040.stderr b/src/test/ui/nll/issue-53040.stderr index d65d3aafbc5..fac9969f193 100644 --- a/src/test/ui/nll/issue-53040.stderr +++ b/src/test/ui/nll/issue-53040.stderr @@ -2,7 +2,7 @@ error: captured variable cannot escape `FnMut` closure body --> $DIR/issue-53040.rs:15:8 | LL | || &mut v; - | - ^^^^^^ creates a reference to a captured variable which escapes the closure body + | - ^^^^^^ returns a reference to a captured variable which escapes the closure body | | | inferred to be a `FnMut` closure | diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr index 8ce249f2a29..300a5639822 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr @@ -2,7 +2,7 @@ error: captured variable cannot escape `FnMut` closure body --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:17:24 | LL | let mut f = || &mut x; //~ ERROR cannot infer - | - ^^^^^^ creates a reference to a captured variable which escapes the closure body + | - ^^^^^^ returns a reference to a captured variable which escapes the closure body | | | inferred to be a `FnMut` closure |