-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Disallow discarding a value if a variable is used #9238
Comments
I like the idea of this proposal, but how does this work for something like |
I've been thinking about essentially the same thing recently, but I think this {
var x: u32 = 0;
discardvar x;
foo(x); // error: use of discarded value `x`. It was discarded here: ...
} Also, {
var x: u32 = 0;
var y: u32 = 0;
discardvar x, y;
foo(x); // error: use of discarded value `x`. It was discarded here: ...
foo(y); // error: use of discarded value `y`. It was discarded here: ...
} but I'm not sure if it would be a good idea since it would be inconsistent with variable declarations (there is no way to declare two different identifiers on a signle statement). |
Fixing an "unused" error for a local variable shouldn't be done with The canonical way to discard a parameter in such a situation is to This proposal addresses only the first problem. But the context-sensitivity thing makes me unsure whether to like it or not. And the other two problems would remain either way. To Express Intent Precisely it would be better to introduce a semantic annotation for discarding parameters, like / End rant. |
I was thinking on improving a coding pattern I've come across before but I think it would be better with a proposal I'm working on (mutable captures and function parameters): pub fn func(arg: SomeStruct) SomeStruct {
var arg_ = arg;
// mutate arg_
return arg_;
} By the way, there's another problem - if const x = 10;
doSomethingWith(x);
const x1 = 20;
const x2 = 30;
doSomethingWith(x1 + x2); This is perfectly valid code, but someone could argue that, since const x = 10;
doSomethingWith(x);
discardvar x;
const x1 = 20;
const x2 = 30;
doSomethingWith(x1 + x2); Someone could even argue that const x = 10;
doSomethingWith(x);
discardvar x;
const x1 = 20;
const x2 = 30;
doSomethingWith(x1 + x2);
discardvar x1, x2; I think this ends up violating the "only one obvious way to do things" lemma. Still, if we decide to add it in, I guess we could have a set of conventions to mitigate the problem. But then:
|
I agree that handling unused parameters with Personally if there's going to be a change for this I'm in favor of a new keyword - something like // A...
fn a(x: u32) u32 {
unused x; // mark the input as unused
return x + 10; // error: x was used after being marked unused
}
// B...
fn b(x: u32) u32 {
x += 20;
unused x; // error: x was marked unused after being used
return 100;
}
// C...
fn c(x: u32) u32 {
// replaces _ = callFn(...)
unused iDontCareAboutWhatThisFnReturns(x);
return x;
}
// D...
fn d(x: u32) u32 {
unused x;
const x = 20; // error - name shadows unused identifier
return x + 10;
}
I think that the strictness here of not allowing
will make it clear to anyone reading the code that, if they see Replacing |
I believe the fourth example fails to compile even now, since variable shadowing is already disallowed. |
Yeah it would, but I'm just putting it there to demonstrate that marking x as unused wouldn't unset/reset the name or anything. |
This has been implemented for a while. Test coverage here: https://github.com/ziglang/zig/blob/2ee328995a70c5c446f24c5593e0fad760e6d839/test/cases/compile_errors/pointless%20discard.zig |
Zig forces you to reference or discard every value, including function parameters. It might be harmful in bigger functions that will use a discarded value later in the code, so i propose to forbid this code:
This will prevent misleading discards of values where the value isn't actually discarded, but was only marked "i don't need this right now" by a (potentially different) programmer
The text was updated successfully, but these errors were encountered: