-
Notifications
You must be signed in to change notification settings - Fork 13k
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
librustc: Copy or move upvars by value [breaking-change]. #14620
Conversation
(for use in forthcoming commits.)
Closes rust-lang#12831. This breaks many closures (about 10%) that look like this: let mut sum = 0; f.map(|x| sum += x); Instead, rewrite them like this: let mut sum = 0; { let sum_ptr = &mut sum; f.map(|x| *sum_ptr += x); } Or, ideally, switch to RAII- or iterator-like patterns. [breaking-change]
So, just for the record, this history edited version (as of commit b846820) ends in a code base that is nearly identical to pcwalton's #14501. It basically just has some bug fixes to let me get Here is the complete diff between the two, as of commit b846820. (I keep adding that qualification because I will need to rebase it atop master before merging, and that will make the diff comparison between this and PR #14501 useless.) The diff:
|
It's probably too late now, but I would much rather shadow outer variables rather than suffix them all with |
Just wanted to make sure there was a test for something like this as well: let a = box 1;
let b = || { println!("{}", a) };
drop(b);
// no memory should leak |
@alexcrichton it is not too late, its easy to rebase -i and edit commits, especially since I will need to rebase it on top of master before attempting to land this anyway. (I've put this PR on the mtg agenda for tonight, just to double-check everyone is okay with the shift in the character of the language.) |
I noticed that many of the captures are written like let mut foo: T = init();
let foo_ptr: &mut T = &mut foo_ptr;
... but can be written like let mut foo: &mut T = &mut init();
... For closures where This is especially true of many of the closures in tests and benchmarks. |
@huonw I don't suppose you have any ready estimate as to how many of the changes your suggestion would apply to? (My plan, based on the discussion at last night's meeting, was to just close this PR, but your comment has made me wonder if I should try to clean it up further, and refloat the idea of just doing by-value-upvars, or at least make that the easy default.) |
closing; we are reconsidering forcing all closures to move to by-value upvars : see rust-lang/rfcs#114 |
librustc: Copy or move upvars by value [breaking-change].
This is a commit-refactored version of PR #14501.
(pnkfelix will rebase atop master as necessary; he just wanted to transition from pcwalton's PR over to this one cleanly first.)
Original PR message follows.
Closes #12831.
This breaks many closures (about 10%) that look like this:
let mut sum = 0;
f.map(|x| sum += x);
Instead, rewrite them like this:
let mut sum = 0;
{
let sum_ptr = &mut sum;
f.map(|x| *sum_ptr += x);
}
Or, ideally, switch to RAII- or iterator-like patterns.
[breaking-change]