Conversation
|
Hm, it seems modifying something via a closure doesn't work: fn main() {
let mut array = [1, 2, 3];
callback(|i| { array[i] = 0; });
println(array);
}
fn callback<Env>(f: fn[Env](u32) -> ()) {
f(1);
}The above prints For now I'll close this PR. Maybe this could be done with a macro instead but it would make the code much harder to read. |
It's expected. You need to explicitly capture the reference instead: |
|
@asterite to expand on the above, we have a decision to either capture by ref or by copy by default. If we copy by ref by default, then we can't actually just copy the let mut x = ...;
let y = x;
let f = || y;Someone may see let mut x = ...;
let y = &mut x; // clearly needed so that f has a mutable reference to x
let f = || y;It used to be that within the closure we'd mark the captured variable as immutable by default so we'd issue an error if the user tried to do: let mut x = ...;
|| {
x = 3; // error
}But I think when closure conversion was being worked on quite a while back this was causing some issue and all variables in closure's env were marked as mutable by default instead... If anything I think this is the issue we should fix - to make these immutable so that we can issue a proper error again. This issue appears to be the same one from here: #4795 which @michaeljklein has a draft PR open for which maybe we can revisit. |
Please. I'd never in a million years expect for this to be the default, and had no idea either syntax for mutable references even existed, since as far as I knew Noir didn't even expose references as a concept at all. And without an error I'd also not realize I was accidentally requiring captured variables to be mutable. |
|
@asterite do you want to reopen this and use explicit mutable references? |
|
I started doing this earlier today but I wasn't sure, it made the code looks a bit harder to read. I'll try it anyway and see how it looks and if we get any benefit to it. |
|
Reopening... |
|
It seems some external projects fail. The problem is, because we don't get an error if we incorrectly mutate something in a closure it's very hard to debug this, and that's why I'm hesitant about including it now. We could maybe try it again after we report an error in this case. |
fwiw the stdlib already has closures (e.g. |
Description
Problem
For #7119 (comment)
Summary
Additional Context
I'm not convinced about the name
for_loopso open to suggestions.Documentation
Check one:
PR Checklist
cargo fmton default settings.