Skip to content

Passing by value into unconstrained function generates constraints #4244

@zac-williamson

Description

@zac-williamson

Aim

I have a Struct that contains arrays. I iterate over the arrays in an unconstrained function. Many constraints generated. Sad face.

use dep::std::field::bn254::assert_gt;

struct ListItem {
    key: Field,
    previous: Field,
    next: Field,
}

impl ListItem {
    fn default() -> ListItem {
        ListItem {
            key: 0,
            previous: 0,
            next: 0,
        }
    }
}

struct Map<Size> {
    entries: [ListItem; Size],
    size: Field,
    is_empty: bool,
    first_index: Field,
    last_index: Field,
}

unconstrained fn find_previous_key_location<Size>(map: Map<Size>, key: Field) -> (Field) {
    let mut found_index: Field = 0;
    found_index
}

unconstrained fn find_previous_key_location_nocopy<Size>(key: Field) -> (Field) {
    let mut found_index: Field = 0;
    found_index
}

unconstrained fn find_previous_key_location_two<Size>(map: &mut Map<Size>, key: Field) -> (Field) {
    let mut found_index: Field = 0;
    found_index
}

impl<Size> Map<Size> {
    fn default() -> Map<Size> {
        Map{
            entries: [ListItem::default(); Size], // todo fix
            size: 0,
            is_empty: true,
            first_index: 0,
            last_index: 0,
        }
    }


    fn insert_expensive(&mut self, key: Field) {
        let previous_indexx = find_previous_key_location(*self, key);
        self.entries[previous_indexx].key = key;
    }

    fn insert_cheap(&mut self, key: Field) {
        let previous_indexx = find_previous_key_location_nocopy(key);
        self.entries[previous_indexx].key = key;
    }
}

fn main(x: Field, y: pub Field) {
    let mut test_list: Map<50> = Map::default();
    test_list.insert(x);
    test_list.insert(x + y);
    test_list.insert(x + y * y);
}

Expected Behavior

6 constraints. Not 2000+

Bug

Passing by value into unconstrained fn should not generate constraints

To Reproduce

  1. nargo info
  2. observe high gate count
  3. replace call to find_previous_key_location with find_previous_key_location_nocopy
  4. observe low gate count

Installation Method

Binary

Nargo Version

0.23.0

Additional Context

No response

Would you like to submit a PR for this Issue?

No

Support Needs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions