You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The actual use case is more complicated than the snippet I post below. I want to pass on a list of mutable characters (which all have various attributes like position, health etc.) to various functions that handle player actions and events. I would like to avoid a syntax like:
fn do_something(char: &mut Character) {
// modify char
}
//...
let mut my_char_0 = Character {...};
let mut my_char_1 = Character {...};
///...
if actor_id == 0 { do_something(&mut my_char_0); }
else if actor_id == 1 { do_something(&mut my_char_1);
// ...
I would also prefer to avoid creating hard-to-test monster classes like
I would rather prefer being able to pass on the whole array, however, since array elements cannot be referenced and non-mutable-references that are being passed on are only local, my idea was to use arrays of mutable references. This allows the following syntax:
let my_chars = [&mut Character {...}, &mut Character {...}, ...];
do_something(my_chars[actor_id]);
These references could then even be stored in the Game struct
In tests this works all fine, however, when trying to build (nargo compile), I get an error
Expected Behavior
If Noir language server and nargo test accept a syntax, I expect it to work on nargo compile as well.
Instead the compiler panics.
Bug
The application panicked (crashed).
Message: internal error: entered unreachable code: Expected all allocate instructions to be removed before acir_gen
Location: compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs:689
This is a bug. We may have already fixed this in newer versions of Nargo so try searching for similar issues at https://github.com/noir-lang/noir/issues/.
If there isn't an open issue for this bug, consider opening one at https://github.com/noir-lang/noir/issues/new?labels=bug&template=bug_report.yml
To Reproduce
The minimal version to reproduce this bug is the following code:
The workaround is to use gigantic return values (in the simple example below this is not too bad, but imagine the Game struct having more properties ...)
struct Character {
x: u8,
y: u8,
health: u8,
}
struct Game {
my_chars: [Character; 5],
}
fn handle_explosion(game: Game, x: u8, y: u8, dmg: u8) -> Game {
let mut new_chars = game.my_chars;
for i in 0..5 {
if (new_chars[i].x == x) & (new_chars[i].y == y) {
new_chars[i] = Character { x: x, y: y, health: new_chars[i].health - dmg };
} else if ((new_chars[i].x == x) & ((new_chars[i].y == y + 1) | (new_chars[i].y == y - 1)))
| ((new_chars[i].y == y) & ((new_chars[i].x == x + 1) | (new_chars[i].x == x - 1))) {
new_chars[i] = Character { x: x, y: y, health: new_chars[i].health - (dmg / 2) };
}
}
Game { my_chars: new_chars }
}
fn main(my_chars: [Character; 5], explosion_x: pub u8, explosion_y: pub u8, healths: pub [u8; 5]) {
let game = Game { my_chars };
let new_game = handle_explosion(game, explosion_x, explosion_y, 100);
for i in 0..5 {
assert(new_game.my_chars[i].health == healths[i]);
}
}
#[test]
fn test_main() {
main(
[
Character { x: 12, y: 5, health: 100 },
Character { x: 13, y: 5, health: 100 },
Character { x: 13, y: 4, health: 100 },
Character { x: 20, y: 5, health: 100 },
Character { x: 20, y: 0, health: 100 }
],
13,
5,
[50, 0, 50, 100, 100]
);
}
or god-classes:
struct Character {
x: u8,
y: u8,
health: u8,
}
struct Game {
my_chars: [Character; 5],
}
impl Game {
fn handle_explosion(&mut self, x: u8, y: u8, dmg: u8) {
for i in 0..5 {
if (self.my_chars[i].x == x) & (self.my_chars[i].y == y) {
self.my_chars[i] = Character { x: x, y: y, health: self.my_chars[i].health - dmg };
} else if ((self.my_chars[i].x == x)
& ((self.my_chars[i].y == y + 1) | (self.my_chars[i].y == y - 1)))
| ((self.my_chars[i].y == y)
& ((self.my_chars[i].x == x + 1) | (self.my_chars[i].x == x - 1))) {
self.my_chars[i] = Character { x: x, y: y, health: self.my_chars[i].health - (dmg / 2) };
}
}
}
}
fn main(my_chars: [Character; 5], explosion_x: pub u8, explosion_y: pub u8, healths: pub [u8; 5]) {
let mut game = Game { my_chars };
game.handle_explosion(explosion_x, explosion_y, 100);
for i in 0..5 {
assert(game.my_chars[i].health == healths[i]);
}
}
#[test]
fn test_main() {
main(
[
Character { x: 12, y: 5, health: 100 },
Character { x: 13, y: 5, health: 100 },
Character { x: 13, y: 4, health: 100 },
Character { x: 20, y: 5, health: 100 },
Character { x: 20, y: 0, health: 100 }
],
13,
5,
[50, 0, 50, 100, 100]
);
}
Additional Context
Interestingly, sometimes the bug does not appear. Like here:
The error you are getting is due to the fact we do not handle references which we cannot resolve at compile time.
This is why in some cases you do not get the issue; when the references could be resolved.
I made a PR to report this error instead of the compiler panic.
# Description
## Problem\*
Resolves#5175
## Summary\*
When we cannot resolve some references to an array, its allocate is not
simplified and we get a panic.
I changed this to an error message saying that we could not resolve all
references from the array.
I believe an error message is better than the panic, however I am not
sure whether having remaining allocates only happens because of this
case.
## Additional Context
## Documentation\*
Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.
# PR Checklist\*
- [ ] I have tested the changes locally.
- [ ] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
Aim
The actual use case is more complicated than the snippet I post below. I want to pass on a list of mutable characters (which all have various attributes like position, health etc.) to various functions that handle player actions and events. I would like to avoid a syntax like:
I would also prefer to avoid creating hard-to-test monster classes like
I would rather prefer being able to pass on the whole array, however, since array elements cannot be referenced and non-mutable-references that are being passed on are only local, my idea was to use arrays of mutable references. This allows the following syntax:
These references could then even be stored in the Game struct
In tests this works all fine, however, when trying to build (nargo compile), I get an error
Expected Behavior
If Noir language server and
nargo test
accept a syntax, I expect it to work onnargo compile
as well.Instead the compiler panics.
Bug
To Reproduce
The minimal version to reproduce this bug is the following code:
Project Impact
None
Impact Context
No response
Workaround
Yes
Workaround Description
The workaround is to use gigantic return values (in the simple example below this is not too bad, but imagine the Game struct having more properties ...)
or god-classes:
Additional Context
Interestingly, sometimes the bug does not appear. Like here:
Installation Method
Binary (
noirup
default)Nargo Version
nargo version = 0.30.0 noirc version = 0.30.0+af57471035e4fa7eaffa71693219df6d029dbcde (git version hash: af57471, is dirty: false)
NoirJS Version
No response
Would you like to submit a PR for this Issue?
None
Support Needs
No response
The text was updated successfully, but these errors were encountered: