Skip to content

Commit

Permalink
feat: add definitions for From and Into traits to Noir prelude (#4169)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Supercedes #4148 

## Summary\*

This PR adds a definition of `From` and `Into` traits into the Noir
prelude. I've provided implementations for the primitive types along
with the trivial general implementations of the traits.

## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [x] **[Exceptional Case]** Documentation to be submitted in a separate
PR.
Will document once codegen is up.
# 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.
  • Loading branch information
TomAFrench authored Jan 25, 2024
1 parent ed14628 commit 4421ce4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
56 changes: 56 additions & 0 deletions noir_stdlib/src/convert.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
trait From<T> {
fn from(input: T) -> Self;
}

impl<T> From<T> for T {
fn from(input: T) -> T {
input
}
}

trait Into<T> {
fn into(input: Self) -> T;
}

impl<T, U> Into<T> for U where T: From<U> {
fn into(input: U) -> T {
T::from(input)
}
}

// Unsigned integers
impl From<u8> for u16 { fn from(value: u8) -> u16 { value as u16 } }

impl From<u8> for u32 { fn from(value: u8) -> u32 { value as u32 } }
impl From<u16> for u32 { fn from(value: u16) -> u32 { value as u32 } }

impl From<u8> for u64 { fn from(value: u8) -> u64 { value as u64 } }
impl From<u16> for u64 { fn from(value: u16) -> u64 { value as u64 } }
impl From<u32> for u64 { fn from(value: u32) -> u64 { value as u64 } }

impl From<u8> for Field { fn from(value: u8) -> Field { value as Field } }
impl From<u16> for Field { fn from(value: u16) -> Field { value as Field } }
impl From<u32> for Field { fn from(value: u32) -> Field { value as Field } }
impl From<u64> for Field { fn from(value: u64) -> Field { value as Field } }

// Signed integers
impl From<i8> for i16 { fn from(value: i8) -> i16 { value as i16 } }

impl From<i8> for i32 { fn from(value: i8) -> i32 { value as i32 } }
impl From<i16> for i32 { fn from(value: i16) -> i32 { value as i32 } }

impl From<i8> for i64 { fn from(value: i8) -> i64 { value as i64 } }
impl From<i16> for i64 { fn from(value: i16) -> i64 { value as i64 } }
impl From<i32> for i64 { fn from(value: i32) -> i64 { value as i64 } }

// Booleans
impl From<bool> for u8 { fn from(value: bool) -> u8 { value as u8 } }
impl From<bool> for u16 { fn from(value: bool) -> u16 { value as u16 } }
impl From<bool> for u32 { fn from(value: bool) -> u32 { value as u32 } }
impl From<bool> for u64 { fn from(value: bool) -> u64 { value as u64 } }
impl From<bool> for i8 { fn from(value: bool) -> i8 { value as i8 } }
impl From<bool> for i16 { fn from(value: bool) -> i16 { value as i16 } }
impl From<bool> for i32 { fn from(value: bool) -> i32 { value as i32 } }
impl From<bool> for i64 { fn from(value: bool) -> i64 { value as i64 } }
impl From<bool> for Field { fn from(value: bool) -> Field { value as Field } }

1 change: 1 addition & 0 deletions noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod ec;
mod unsafe;
mod collections;
mod compat;
mod convert;
mod option;
mod string;
mod test;
Expand Down
1 change: 1 addition & 0 deletions noir_stdlib/src/prelude.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ use crate::{print, println, assert_constant};
use crate::uint128::U128;
use crate::cmp::{Eq, Ord};
use crate::default::Default;
use crate::convert::{From, Into};
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

fn main() {
let xs: [Field; 1] = [3];
let ys: [u32; 1] = [3];
Expand All @@ -8,21 +7,21 @@ fn main() {
assert_eq(15, sum_static(Data { a: 5, b: 10 }));
}

fn foo<T, U>(x: T, u: U) where T: Into<U>, U: Eq {
fn foo<T, U>(x: T, u: U) where T: MyInto<U>, U: Eq {
assert(x.into() == u);
}

trait Into<T> {
trait MyInto<T> {
fn into(self) -> T;
}

impl<T, U, N> Into<[U; N]> for [T; N] where T: Into<U> {
impl<T, U, N> MyInto<[U; N]> for [T; N] where T: MyInto<U> {
fn into(self) -> [U; N] {
self.map(|x: T| x.into())
}
}

impl Into<u32> for Field {
impl MyInto<u32> for Field {
fn into(self) -> u32 {
self as u32
}
Expand Down

0 comments on commit 4421ce4

Please sign in to comment.