-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
invariant_booleans: False positives and negatives with repeated conditions. #57643
Comments
Same issue here (also void main() {
final bar = 0;
final foo = 10;
for (var i = 0; i < foo; ++i) {}
for (var i = 0; i < foo; ++i) {} // invariant_booleans: i < foo
if (bar == 10) {}
} |
Hitting this as well. @alexeieleusis ? @pq ? |
Sorry, no update just yet. Hoping to set aside some time to look in the coming week. cc @bwilkerson |
I have a fix for the bug itself, some other tests broke though. I don't know yet if the problem are the tests themselves, will upload the progress I have if I can't finish it before Tuesday (2/20). |
Awesome. Thanks @alexeieleusis ! |
While @alexeieleusis' PR targets the case @lexaknyazev demonstrated above, it doesn't address a single one of the cases in the issue description (none of which include a Please reopen this issue (as I evidently don't have the permissions to). |
We decided when the rule was implemented that false negatives like the one produced by invoking The rule detects early returns and does not use those conditions, as @rkirsling points out. As for ternary operators, sounds like a missing implementation. I am unsure about adding it, the reason being that I haven't found a single true positive in code in the real world. The idea behind this rule was to catch debugging leftovers, which in my case, are always caught by Thoughts? |
cc @bwilkerson |
That makes sense—I mentioned the false negatives so as to give the most complete description of the problem that I could, but it's really just that the false positive is plaguing me in actual code. 😄 |
Looks like you are writing an interpreter, I wonder how useful this lint is for you. I have the impression that performance constraints require changes undetectable for the lint to be common place. |
As a policy, I've been keeping as many lint rules enabled as possible. If I disagree with a rule, I'll turn it off, but I don't disagree with |
Reproduced: void main() {
Foo()
..a() // prints 'true'
..a()
..a(); // prints 'false'
}
class Foo {
int x = 1;
void a() {
if (x + 2 > 2) {
b();
// Produces an invariant_booleans warning
if (x + 2 <= 2) {
print('true');
return;
} else {
print('false');
}
}
x += 2;
}
void b() {
x--;
}
} |
I think the lint to flag a case like the one above is too ambitious, the most common use case I have (in any language) is forcing a condition to be true or false for debugging purposes, in such cases I use constants (with a FIXME comment) to avoid committing that change. Catching a case like the one in the example above can become too expensive rendering the lint unusable (think of the code changing a property inside an object and the code is performed in a different library). |
We've deprecated |
In
2.0.0-dev.4.0
,invariant_booleans
behaves erratically when the same condition occurs multiple times in a function.First, checking the value of a field before and after updating it can cause a false positive:
The choices of
> 0
and++
for comparison and assignment don't matter, andint
can be replaced with a different numerical type. EvenString
with+= 's'
will repro.Now, if we modify our test function to use a ternary, the problem goes away...
...but don't rejoice just yet, because if we keep going we hit a false negative!
And even without the ternary, if we use a boolean field,
invariant_booleans
ironically doesn't care how many times we check it. 😆Follow-up: It didn't occur to me earlier, but the false positive seems to hinge on the first conditional being an early
return
.The text was updated successfully, but these errors were encountered: