typeck: boxed closures can't capture by value #20244
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
closes #19141
closes #20193
closes #20228
Currently whenever we encounter
let f = || {/* */}
, we always type check the RHS as a boxed closure. This is wrong when the RHS ismove || {/* */}
(because boxed closures can't capture by value) and generates all sort of badness during trans (see issues above). What we should do is always type checkmove || {/* */}
as an unboxed closure, butI think (haven't tried)(2) this is not feasible right now because we have a limited form of kind (Fn
vsFnMut
vsFnOnce
) inference that only works when there is an expected type (1).In this PR, I've chosen to generate a type error whenever
let f = move || {/* */}
is encountered. The error asks the user to annotate the kind of the unboxed closure (e.g.move |:| {/* */}
). Once annotated, the compiler will type check the RHS as an unboxed closure which is what the user wants.r? @nikomatsakis
(1) AIUI it only triggers in this scenario:
(2) I checked, and it's not possible because
check_unboxed_closure
expects akind
argument, but we can't supply that argument in this case (i.e.let f = || {}
, what's the kind?). We could force theFnOnce
kind in that case, but that's ad hoc. We should try to infer the kind depending on how the closure is used afterwards, but there is no inference mechanism to do that (at least, not right now).