Skip to content
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

Usage of .as_array() method on slice results in panic during inlining #5245

Closed
TomAFrench opened this issue Jun 13, 2024 · 3 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@TomAFrench
Copy link
Member

Aim

I would like to write a very simple program which just returns the modulus of the field being used.

use dep::std::field::modulus_be_bytes;

fn main() -> pub [u8; 32] {
    let bytes = dep::std::field::modulus_be_bytes();
    bytes.as_array()
}

Expected Behavior

I would expect that this program would successfully compile and I would get ACIR which directly commits to the values of each public input.

Bug

Compilation fails with a panic inside the inlining pass.

After Resolving IsUnconstrained:
acir(inline) fn main f0 {
  b0():
    v31 = call f1([u8 2⁴×3, u8 100, u8 78, u8 114, u8 225, u8 49, u8 2⁴×10, u8 41, u8 184, u8 2⁴×5, u8 69, u8 182, u8 129, u8 129, u8 88, u8 93, u8 40, u8 51, u8 232, u8 72, u8 121, u8 185, u8 2⁴×7, u8 145, u8 67, u8 225, u8 245, u8 147, u8 2⁴×15, u8 0, u8 0, u8 1])
    return v31
}
acir(inline) fn as_array f1 {
  b0(v0: u32, v1: [u8]):
    v4 = eq v0, u32 2⁵
    constrain v0 == u32 2⁵
    inc_rc [u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0]
    v8 = allocate
    store [u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0, u8 0] at v8
    jmp b1(u32 0)
  b1(v9: u32):
    v11 = lt v9, u32 2⁵
    jmpif v11 then: b2, else: b3
  b2():
    v12 = load v8
    v14 = lt v9, v0
    constrain v14 == u1 1 '"Index out of bounds"'
    v15 = array_get v1, index v9
    v16 = array_set v12, index v9, value v15
    v17 = add v9, u32 1
    store v16 at v8
    v18 = add v9, u32 1
    jmp b1(v18)
  b3():
    v19 = load v8
    return v19
}

The application panicked (crashed).
Message:  assertion `left == right` failed
  left: 2
 right: 1
Location: compiler/noirc_evaluator/src/ssa/opt/inlining.rs:299

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

Project Impact

None

Impact Context

No response

Workaround

None

Workaround Description

I can work around this by directly inlining the contents of as_array into my function as so.

use dep::std::field::modulus_be_bytes;

fn main() -> pub [u8; 32] {
    let bytes = dep::std::field::modulus_be_bytes();

    assert(bytes.len() == 32);

    let mut array = [0; 32];
    for i in 0..32 {
        array[i] = bytes[i];
    }
    array
}

Additional Context

No response

Installation Method

Compiled from source

Nargo Version

No response

NoirJS Version

No response

Would you like to submit a PR for this Issue?

None

Support Needs

No response

@TomAFrench TomAFrench added the bug Something isn't working label Jun 13, 2024
@github-project-automation github-project-automation bot moved this to 📋 Backlog in Noir Jun 13, 2024
@TomAFrench
Copy link
Member Author

TomAFrench commented Jun 13, 2024

use dep::std::field::modulus_be_bytes;

global BN254_MODULUS_BE_BYTES: [u8] = &[
            48, 100, 78, 114, 225, 49, 160, 41, 184, 80, 69, 182, 129, 129, 88, 93, 40, 51, 232, 72, 121, 185, 112, 145, 67, 225, 245, 147, 240, 0, 0, 1
        ];

fn main() -> pub bool {
    dep::std::field::modulus_be_bytes() == BN254_MODULUS_BE_BYTES
}

This can also be run into when just checking equality between two slices

@jfecher
Copy link
Contributor

jfecher commented Jun 13, 2024

We used to encounter this a lot when array literals & types were polymorphic over arrays and structs. Not sure why it is happening now.

@TomAFrench
Copy link
Member Author

Fixed by #5278

@github-project-automation github-project-automation bot moved this from 📋 Backlog to ✅ Done in Noir Jun 20, 2024
github-merge-queue bot pushed a commit that referenced this issue Jun 26, 2024
# Description

## Problem\*

Resolves <!-- Link to GitHub Issue -->

## Summary\*

This PR addresses a TODO in the stdlib now that #5245 is resolved.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants