Skip to content

Commit

Permalink
feat: Option expect method (#4219)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

#4101 resolves
#3113 which was preventing an
expect function on our Option struct.

## Summary\*

This adds an `expect` method and a test inside of `compile_failure`.
Here is the example for the test under `compile_failure/option_expect`:
<img width="716" alt="Screenshot 2024-01-31 at 11 12 51 AM"
src="https://github.com/noir-lang/noir/assets/43554004/1a84d489-bd7f-446a-96be-ebf63ae63f47">



## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[Exceptional Case]** 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.

---------

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: Tom French <tom@tomfren.ch>
  • Loading branch information
3 people committed Feb 1, 2024
1 parent c284e01 commit 8e042f2
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 4 deletions.
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/monomorphization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,10 +1038,10 @@ impl<'interner> Monomorphizer<'interner> {
// since they cannot be passed from ACIR into Brillig
if let HirType::Array(size, _) = typ {
if let HirType::NotConstant = **size {
unreachable!("println does not support slices. Convert the slice to an array before passing it to println");
unreachable!("println and format strings do not support slices. Convert the slice to an array before passing it to println");
}
} else if matches!(typ, HirType::MutableReference(_)) {
unreachable!("println does not support mutable references.");
unreachable!("println and format strings do not support mutable references.");
}

let printable_type: PrintableType = typ.into();
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/noir/standard_library/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ Returns the wrapped value if `self.is_some()`. Otherwise, returns the given defa

Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return a default value.

### expect

Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value. The custom message is expected to be a format string.

### map

If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.
Expand Down
6 changes: 6 additions & 0 deletions noir_stdlib/src/option.nr
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ impl<T> Option<T> {
}
}

/// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value
fn expect<N, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T {
assert(self.is_some(), message);
self._value
}

/// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.
pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U> {
if self._is_some {
Expand Down
2 changes: 2 additions & 0 deletions test_programs/compile_failure/assert_msg_runtime/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "5"
y = "10"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "5"
7 changes: 7 additions & 0 deletions test_programs/compile_failure/option_expect/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "option_expect"
type = "bin"
authors = [""]
compiler_version = ">=0.23.0"

[dependencies]
8 changes: 8 additions & 0 deletions test_programs/compile_failure/option_expect/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let inner_value = 3;
let none = Option::none();
let some = Option::some(inner_value);

assert(some.expect(f"Should have the value {inner_value}") == 3);
assert(none.expect(f"Should have the value {inner_value}") == 3);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "option_expect_bad_input"
type = "bin"
authors = [""]
compiler_version = ">=0.23.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
let inner_value = 3;
let some = Option::some(inner_value);

assert(some.expect("Should have the value {inner_value}") == 3);
}
4 changes: 2 additions & 2 deletions test_programs/compile_success_empty/option/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use dep::std::option::Option;

fn main() {
let ten = 10; // giving this a name, to ensure that the Option functions work with closures
let none = Option::none();
Expand All @@ -22,6 +20,8 @@ fn main() {
assert(some.map(|x| x * 2).unwrap() == 6);
assert(some.map(|x| x * ten).unwrap() == 30);

assert(some.expect(f"Should have a value") == 3);

assert(none.map_or(0, |x| x * 2) == 0);
assert(some.map_or(0, |x| x * 2) == 6);
assert(none.map_or(0, |x| x * ten) == 0);
Expand Down

0 comments on commit 8e042f2

Please sign in to comment.