Skip to content

Commit 95d4d13

Browse files
authored
feat: add Not trait to stdlib (#4999)
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> ## Summary\* This PR adds a `Not` trait which is an equivalent of Rust's `std::ops::Not` trait which represents a bitwise NOT. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] 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.
1 parent f01d309 commit 95d4d13

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

docs/docs/noir/standard_library/traits.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,15 @@ impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } }
241241
Implementations:
242242
#include_code neg-trait-impls noir_stdlib/src/ops/arith.nr rust
243243

244+
### `std::ops::Not`
245+
246+
#include_code not-trait noir_stdlib/src/ops/bit.nr rust
247+
248+
`Not::not` is equivalent to the unary bitwise NOT operator `!`.
249+
250+
Implementations:
251+
#include_code not-trait-impls noir_stdlib/src/ops/bit.nr rust
252+
244253
### `std::ops::{ BitOr, BitAnd, BitXor }`
245254

246255
#include_code bitor-trait noir_stdlib/src/ops/bit.nr rust

noir_stdlib/src/ops.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ mod arith;
22
mod bit;
33

44
use arith::{Add, Sub, Mul, Div, Rem, Neg};
5-
use bit::{BitOr, BitAnd, BitXor, Shl, Shr};
5+
use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr};

noir_stdlib/src/ops/bit.nr

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
// docs:start:not-trait
2+
trait Not {
3+
fn not(self: Self) -> Self;
4+
}
5+
// docs:end:not-trait
6+
7+
// docs:start:not-trait-impls
8+
impl Not for bool { fn not(self) -> bool { !self } }
9+
10+
impl Not for u64 { fn not(self) -> u64 { !self } }
11+
impl Not for u32 { fn not(self) -> u32 { !self } }
12+
impl Not for u16 { fn not(self) -> u16 { !self } }
13+
impl Not for u8 { fn not(self) -> u8 { !self } }
14+
impl Not for u1 { fn not(self) -> u1 { !self } }
15+
16+
impl Not for i8 { fn not(self) -> i8 { !self } }
17+
impl Not for i16 { fn not(self) -> i16 { !self } }
18+
impl Not for i32 { fn not(self) -> i32 { !self } }
19+
impl Not for i64 { fn not(self) -> i64 { !self } }
20+
// docs:end:not-trait-impls
21+
122
// docs:start:bitor-trait
223
trait BitOr {
324
fn bitor(self, other: Self) -> Self;

noir_stdlib/src/uint128.nr

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ops::{Add, Sub, Mul, Div, Rem, BitOr, BitAnd, BitXor, Shl, Shr};
1+
use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr};
22
use crate::cmp::{Eq, Ord, Ordering};
33

44
global pow64 : Field = 18446744073709551616; //2^64;
@@ -228,11 +228,20 @@ impl Ord for U128 {
228228
}
229229
}
230230

231+
impl Not for U128 {
232+
fn not(self) -> U128 {
233+
U128 {
234+
lo: (!(self.lo as u64)) as Field,
235+
hi: (!(self.hi as u64)) as Field
236+
}
237+
}
238+
}
239+
231240
impl BitOr for U128 {
232241
fn bitor(self, other: U128) -> U128 {
233242
U128 {
234243
lo: ((self.lo as u64) | (other.lo as u64)) as Field,
235-
hi: ((self.hi as u64) | (other.hi as u64))as Field
244+
hi: ((self.hi as u64) | (other.hi as u64)) as Field
236245
}
237246
}
238247
}
@@ -284,3 +293,20 @@ impl Shr for U128 {
284293
self / U128::from_integer(y)
285294
}
286295
}
296+
297+
mod test {
298+
use crate::uint128::{U128, pow64};
299+
300+
#[test]
301+
fn test_not() {
302+
let num = U128::from_u64s_le(0, 0);
303+
let not_num = num.not();
304+
305+
let max_u64: Field = pow64 - 1;
306+
assert_eq(not_num.hi, max_u64);
307+
assert_eq(not_num.lo, max_u64);
308+
309+
let not_not_num = not_num.not();
310+
assert_eq(num, not_not_num);
311+
}
312+
}

0 commit comments

Comments
 (0)