-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move+return in a for loop "moving out of captured outer immutable variable in a stack closure" #4654
Comments
A work-around is to use a swap and a dummy value:
Not exactly convenient… |
I can only guess that the compiler complains because if vec.each didn't implement the for loop protocol correctly (which the compiler can't check) then the closure might be called twice. |
@Dretch, would that be a problem with |
Without looking at the compiler code that does this, my guess is that borrowck doesn't treat I might be missing something here, though, since it's late :-) |
The borrow checker is not being overly conservative. |
Is there a nicer work-around than temporary variables and Simplified a bit:
|
Why can't the compiler check that |
@SimonSapin the usual way is the so-called "option dance":
@jruderman in principle such a thing might be possible but it'd involve a new analysis that we haven't even begun to think about. |
@nikomatsakis good to know… Now I’m trying to decide which is less ugly. |
Could the generated for loop code fail at runtime if the return-inside-the-closure is called more than once? I think that would mean the return would be able to move safely. |
For the compiler to check that It seems preferable to put restrictions on the |
If |
@SimonSapin actually the revised for loop protocol I suggested in a recent blog post would make |
@jruderman interesting idea. I wonder how hard it'd be to implement a simple static analysis for this. It does seem plausible. |
I like the revised loop protocol very much. Seems absolutely plausible to do it that way! About
And we could easily make the return value of
turn into:
Well, not sure if it is really usable, though maybe there are some examples where this could be useful. |
non-critical for 0.6, de-milestoning |
Nominating for maturity milestone 1, "well-defined" |
declined for milestone; maybe-someday |
@thestinger's |
@bstrie , do you mean changing the semantics of for-loops to use external iterators and make |
In the meantime, std::util::replace makes this a bit less painful. |
I just came up with this macro to do for-loops on iterators without involving closures, thus eliminating this whole class of issues:
Usage:
The When the semantics of
|
The old |
Hi,
I have some code similar to this:
Compiler output:
Making the variable mutable does not helpe. I am confident that this move should be fine: the variable is not used afterwards because of the return statement. A very similar code compiles fine when no closure is involved:
Am I seeing a guarantee that the compiler doesn’t or is the compiler seeing a risk that I don’t?
The text was updated successfully, but these errors were encountered: