1
Fork 0

Improve message for closure returning a closure.

Now when a `FnMut` closure is returning a closure that contains a
reference to a captured variable, we provide an error that makes it more
clear what is happening.
This commit is contained in:
David Wood 2018-10-04 21:48:50 +02:00
parent c65e119229
commit 98633b458b
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
8 changed files with 18 additions and 8 deletions

View file

@ -310,9 +310,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
"captured variable cannot escape `FnMut` closure body", "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( diag.span_label(
span, 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 { match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1).source {

View file

@ -32,7 +32,7 @@ LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than
LL | | *y = 1; LL | | *y = 1;
LL | | drop(y); LL | | drop(y);
LL | | } 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: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape = note: ...therefore, they cannot allow references to captured variables to escape

View file

@ -32,7 +32,7 @@ LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than
LL | | *y = 1; LL | | *y = 1;
LL | | drop(y); LL | | drop(y);
LL | | } 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: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape = note: ...therefore, they cannot allow references to captured variables to escape

View file

@ -4,7 +4,7 @@ error: captured variable cannot escape `FnMut` closure body
LL | || { LL | || {
| - inferred to be a `FnMut` closure | - inferred to be a `FnMut` closure
LL | &mut x 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: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape = note: ...therefore, they cannot allow references to captured variables to escape

View file

@ -6,7 +6,7 @@ LL | || {
LL | / || { LL | / || {
LL | | x.push(()) LL | | x.push(())
LL | | } 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: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape = note: ...therefore, they cannot allow references to captured variables to escape

View file

@ -6,7 +6,7 @@ LL | || {
LL | / || { LL | / || {
LL | | let _y = &mut x; LL | | let _y = &mut x;
LL | | } 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: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape = note: ...therefore, they cannot allow references to captured variables to escape

View file

@ -2,7 +2,7 @@ error: captured variable cannot escape `FnMut` closure body
--> $DIR/issue-53040.rs:15:8 --> $DIR/issue-53040.rs:15:8
| |
LL | || &mut v; 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 | inferred to be a `FnMut` closure
| |

View file

@ -2,7 +2,7 @@ error: captured variable cannot escape `FnMut` closure body
--> $DIR/regions-return-ref-to-upvar-issue-17403.rs:17:24 --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:17:24
| |
LL | let mut f = || &mut x; //~ ERROR cannot infer 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 | inferred to be a `FnMut` closure
| |