Open nventuro opened 4 days ago
Spoke in DMs. This is a duplicate of #5202 but with a much nicer reproduction :medal_sports:
Given that we now have a smaller failing example, perhaps this could be used to look into why the optimization disabled in https://github.com/noir-lang/noir/pull/5240 was faulty so that it can be fixed instead of removed? That'd also increase our confidence in the fix if we understood exactly why things broke.
Aim
I run into an extremely confusing scenario in which the presence of
assert_eq
statements seems to put the program in an inconsistent state in which variables are equal to multiple values at the same time, or have different values depending on how they are inspected.Expected Behavior
The following example may seem a bit convoluted, but it originates from a legitimate use-case in the Aztec codebase, and it seems all of the elements present here are required to trigger the bug.
As mentioned in the comments,
nargo test
passes, somagic
is both true and false.Bug
It took me a fair bit of effort to realize that this was a Noir issue, and then to further narrow down the issue to the code sample above. This was quite hard to analyse as it seems the results I get from testing depend on how I inspect the values. I'll share here some of my findings, hoping they might be useful to whomever looks into this.
The trigger for the weird behavior seems to be the
assert_eq
statement. I don't think this is a red-herring: I did not find a single instance of strange behavior that did not include the assertion.It looks like the presence of
assert_eq
somehow confuses Noir when it comes to what the value of the thing being asserted is. Note that in my exampleoption
is asome
value, I then doassert_eq
to a differentsome
value, and yet I later get thatis_some
is not the same before and after theassert_eq
statement. In the example above I only produce a magic boolean that is both true and false, but in testing with extended infrastructure I got Noir to emit oracle calls in whichpre_assert
is 1 (as expected) andpost_assert
is 0. This is why I had to useto_field
: my logging function only receives fields.Making the unconstrained functions constrained causes for the issue to not occur, so this must be somehow related.
I also noticed that performing boolean comparison instead of using
to_field
seemingly causes the issue to go way, but I'm not sure this is entirely true. I only calledto_field
in order to get logging working (and to produce this failing example), but in my original code this was not present.Project Impact
Blocker
Nargo Version
nargo version = 0.30.0 noirc version = 0.30.0+5c3772f09e812a05882039ad888089c238f14001 (git version hash: 5c3772f09e812a05882039ad888089c238f14001, is dirty: false)