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

feat!: replace U128::from_integer with From impls and U128::from_field #4944

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

TomAFrench
Copy link
Member

Description

Problem*

Resolves

Summary*

This PR replaces the overly wide generic function U128::from_integer with From impls for u1, u8, u32, and u64. I've also added U128::from_field to maintain the ability to create a U128 from fields.

Additional Context

Opened #4943 based off of issues when making this PR.

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 and/or cargo fmt on default settings.

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Apr 29, 2024
Copy link
Contributor

github-actions bot commented Apr 29, 2024

Copy link
Contributor

github-actions bot commented Apr 29, 2024

FYI @noir-lang/developerrelations on Noir doc changes.

@TomAFrench TomAFrench marked this pull request as draft April 30, 2024 09:03
@TomAFrench
Copy link
Member Author

This is blocked by #4944

Comment on lines 142 to 146
impl From<u64> for U128 {
fn from(value: u64) -> U128 {
U128::from_u64s_le(value, 0)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a from_u64 in addition to from_field? I think it'd make this easier to find for users

U128 { lo, hi }
}

pub fn to_integer<T>(self) -> T {
crate::from_field(self.lo + self.hi * pow64)
crate::from_field(self.lo + self.hi * POW_64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have plans to remove from_field and as_field eventually? It seems they'd be better replaced by the From trait.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've kept from_field and not implemented From<Field> as this conversion can fail.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may want to have something along the lines of an AssertFrom trait which is essentially From but will throw a constraint error if the conversion isn't valid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I was just thinking of TryFrom

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would TryFrom work here? I'm thinking of AssertFrom as we have a number of conversions where it's much easier to assert that the conversion is valid rather than checking whether it is valid or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryFrom would always be similar to AssertFrom, it just gives users the option to recover from an error if possible but would be less efficient than the AssertFrom in cases where users do just want to panic on failure.

@jfecher
Copy link
Contributor

jfecher commented Apr 30, 2024

This is blocked by #4944

I assume you mean #4943?

If so we should be able to unblock this using From::from & type hints or using non-trait constructors like from_u64 directly once they're added.

@TomAFrench
Copy link
Member Author

Yep, just noticed I copy-pasted incorrectly there. From::from is a bit of an ugly workaround so I think we should avoid situations where it's necessary in user code.

I'll add from_u64 however.

Comment on lines +54 to +58
Conversion between unsigned integer types and U128 are done through the use of the `From` trait and `to_integer` method. There also exists a `from_field` method which accepts a `Field` type as input (which is asserted to fit within a `U128`).

```rust
fn main() {
let x = U128::from_integer(23);
let x = U128::from(23);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs updating to use from_u64 as the From trait is broken

@TomAFrench
Copy link
Member Author

This performance regression on U128 is interesting 🤔

@jfecher
Copy link
Contributor

jfecher commented May 1, 2024

From the CI itself it looks like although there are more ACIR instructions the overall circuit size is still smaller for u128 at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants