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: add support for wildcard types #5275

Merged
merged 6 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
def_map::ModuleDefId,
resolution::{
errors::ResolverError,
resolver::{verify_mutable_reference, SELF_TYPE_NAME},
resolver::{verify_mutable_reference, SELF_TYPE_NAME, WILDCARD_TYPE},
},
type_check::{Source, TypeCheckError},
},
Expand Down Expand Up @@ -146,6 +146,9 @@ impl<'context> Elaborator<'context> {
}
return self_type;
}
} else if name == WILDCARD_TYPE {
let id = self.interner.next_type_variable_id();
return Type::type_variable(id);
guipublic marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ use super::errors::{PubPosition, ResolverError};
use super::import::PathResolution;

pub const SELF_TYPE_NAME: &str = "Self";
pub const WILDCARD_TYPE: &str = "_";

type Scope = GenericScope<String, ResolverMeta>;
type ScopeTree = GenericScopeTree<String, ResolverMeta>;
Expand Down
10 changes: 10 additions & 0 deletions docs/docs/noir/concepts/data_types/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ type Bad2 = Bad1;
// ^^^^^^^^^^^ 'Bad2' recursively depends on itself: Bad2 -> Bad1 -> Bad2
```

## Wildcard Type
When a variable has a complex type that the compiler cannot infer, it
Noir can infer the type of the variable from the context, so specifying the type of a variable is only required when it cannot be inferred. However, specifying a complex type can be tedious, especially with multiple generic arguments. Often the generic types can be inferred from the context, and Noir only needs a hint to properly infer them. This can be done by using the wildcard type `_` inside a complex type.
guipublic marked this conversation as resolved.
Show resolved Hide resolved
The example below tells Noir that `a` is an array of size 4, without specifying the type of its elements.

```rust
let a:[_;4] = foo(b);
guipublic marked this conversation as resolved.
Show resolved Hide resolved
```


### BigInt

You can achieve BigInt functionality using the [Noir BigInt](https://github.com/shuklaayush/noir-bigint) library.
6 changes: 6 additions & 0 deletions test_programs/execution_success/wildcard_type/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "wildcard_type"
type = "bin"
authors = [""]

[dependencies]
1 change: 1 addition & 0 deletions test_programs/execution_success/wildcard_type/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
enable = [4,7]
23 changes: 23 additions & 0 deletions test_programs/execution_success/wildcard_type/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
struct bar {
enable: [bool; 4],
data: [Field; 2],
pad: u32,
}

fn main(enable: [Field; 2]) -> pub [Field; 4] {
let mut result = [0; 4];
let a:[_;4] = foo(enable[1]);
guipublic marked this conversation as resolved.
Show resolved Hide resolved
for i in 0..4 {
result[i] = a[i].data[i % 2];
}
result
}

fn foo(x: Field) -> [bar; 4] {
[
bar { enable: [true, true, false, false], data: [x, x + 1], pad: 0 },
bar { enable: [true, false, false, false], data: [x + 2, x + 7], pad: 0 },
bar { enable: [true, true, false, true], data: [x + 3, x + 5], pad: 0 },
bar { enable: [false, false, false, false], data: [x + 4, x - 1], pad: 0 }
]
}
Loading