From 4421ce4f8f91c7fcac34fbdb76e204df93a46df8 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 18:54:38 +0000 Subject: [PATCH] feat: add definitions for From and Into traits to Noir prelude (#4169) # 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. --- noir_stdlib/src/convert.nr | 56 +++++++++++++++++++ noir_stdlib/src/lib.nr | 1 + noir_stdlib/src/prelude.nr | 1 + .../trait_generics/src/main.nr | 9 ++- 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 noir_stdlib/src/convert.nr diff --git a/noir_stdlib/src/convert.nr b/noir_stdlib/src/convert.nr new file mode 100644 index 00000000000..294b5097cd7 --- /dev/null +++ b/noir_stdlib/src/convert.nr @@ -0,0 +1,56 @@ +trait From { + fn from(input: T) -> Self; +} + +impl From for T { + fn from(input: T) -> T { + input + } +} + +trait Into { + fn into(input: Self) -> T; +} + +impl Into for U where T: From { + fn into(input: U) -> T { + T::from(input) + } +} + +// Unsigned integers +impl From for u16 { fn from(value: u8) -> u16 { value as u16 } } + +impl From for u32 { fn from(value: u8) -> u32 { value as u32 } } +impl From for u32 { fn from(value: u16) -> u32 { value as u32 } } + +impl From for u64 { fn from(value: u8) -> u64 { value as u64 } } +impl From for u64 { fn from(value: u16) -> u64 { value as u64 } } +impl From for u64 { fn from(value: u32) -> u64 { value as u64 } } + +impl From for Field { fn from(value: u8) -> Field { value as Field } } +impl From for Field { fn from(value: u16) -> Field { value as Field } } +impl From for Field { fn from(value: u32) -> Field { value as Field } } +impl From for Field { fn from(value: u64) -> Field { value as Field } } + +// Signed integers +impl From for i16 { fn from(value: i8) -> i16 { value as i16 } } + +impl From for i32 { fn from(value: i8) -> i32 { value as i32 } } +impl From for i32 { fn from(value: i16) -> i32 { value as i32 } } + +impl From for i64 { fn from(value: i8) -> i64 { value as i64 } } +impl From for i64 { fn from(value: i16) -> i64 { value as i64 } } +impl From for i64 { fn from(value: i32) -> i64 { value as i64 } } + +// Booleans +impl From for u8 { fn from(value: bool) -> u8 { value as u8 } } +impl From for u16 { fn from(value: bool) -> u16 { value as u16 } } +impl From for u32 { fn from(value: bool) -> u32 { value as u32 } } +impl From for u64 { fn from(value: bool) -> u64 { value as u64 } } +impl From for i8 { fn from(value: bool) -> i8 { value as i8 } } +impl From for i16 { fn from(value: bool) -> i16 { value as i16 } } +impl From for i32 { fn from(value: bool) -> i32 { value as i32 } } +impl From for i64 { fn from(value: bool) -> i64 { value as i64 } } +impl From for Field { fn from(value: bool) -> Field { value as Field } } + diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 23a7c71ff45..b86834712a6 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -16,6 +16,7 @@ mod ec; mod unsafe; mod collections; mod compat; +mod convert; mod option; mod string; mod test; diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index b57ff460371..26c6a805d54 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -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}; diff --git a/test_programs/compile_success_empty/trait_generics/src/main.nr b/test_programs/compile_success_empty/trait_generics/src/main.nr index 9a3c54c3fa1..30b2e79d579 100644 --- a/test_programs/compile_success_empty/trait_generics/src/main.nr +++ b/test_programs/compile_success_empty/trait_generics/src/main.nr @@ -1,4 +1,3 @@ - fn main() { let xs: [Field; 1] = [3]; let ys: [u32; 1] = [3]; @@ -8,21 +7,21 @@ fn main() { assert_eq(15, sum_static(Data { a: 5, b: 10 })); } -fn foo(x: T, u: U) where T: Into, U: Eq { +fn foo(x: T, u: U) where T: MyInto, U: Eq { assert(x.into() == u); } -trait Into { +trait MyInto { fn into(self) -> T; } -impl Into<[U; N]> for [T; N] where T: Into { +impl MyInto<[U; N]> for [T; N] where T: MyInto { fn into(self) -> [U; N] { self.map(|x: T| x.into()) } } -impl Into for Field { +impl MyInto for Field { fn into(self) -> u32 { self as u32 }