-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(frontend): Correctly monomorphize turbofish functions (#5049)
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> Working towards #4514 and fully resolving #4710 ## Summary\* We need to accurately monomorphize functions with turbofish operators where no function parameters or the return type using the specified generic. Without this change the following would pass: ``` fn main(x: Field, y: pub Field) { let mut hasher = PoseidonHasher::default(); hasher.write(x); hasher.write(y); let poseidon_expected_hash = hasher.finish(); assert(hash_simple_array::<PoseidonHasher>([x, y]) == poseidon_expected_hash); let mut hasher = Poseidon2Hasher::default(); hasher.write(x); hasher.write(y); let poseidon2_expected_hash = hasher.finish(); assert(hash_simple_array::<Poseidon2Hasher>([x, y]) == poseidon_expected_hash); assert(hash_simple_array::<Poseidon2Hasher>([x, y]) != poseidon2_expected_hash); } fn hash_simple_array<H>(input: [Field; 2]) -> Field where H: Hasher + Default { let mut hasher: H = H::default(); hasher.write(input[0]); hasher.write(input[1]); hasher.finish() } ``` Essentially any future invocations of `hash_simple_array` would use the `PoseidonHasher`. We now correctly monomorphize the functions to use the correct type. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Jake Fecher <[email protected]> Co-authored-by: Jake Fecher <[email protected]> Co-authored-by: Tom French <[email protected]>
- Loading branch information
1 parent
89846cf
commit fd772e7
Showing
5 changed files
with
81 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
test_programs/execution_success/turbofish_call_func_diff_types/Nargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "turbofish_call_func_diff_types" | ||
type = "bin" | ||
authors = [""] | ||
compiler_version = ">=0.29.0" | ||
|
||
[dependencies] |
2 changes: 2 additions & 0 deletions
2
test_programs/execution_success/turbofish_call_func_diff_types/Prover.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
x = "5" | ||
y = "10" |
36 changes: 36 additions & 0 deletions
36
test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use dep::std::hash::Hasher; | ||
use dep::std::hash::poseidon2::Poseidon2Hasher; | ||
use dep::std::hash::poseidon::PoseidonHasher; | ||
|
||
fn main(x: Field, y: pub Field) { | ||
let mut hasher = PoseidonHasher::default(); | ||
hasher.write(x); | ||
hasher.write(y); | ||
let poseidon_expected_hash = hasher.finish(); | ||
// Check that we get the same result when using the hasher in a | ||
// method that purely uses trait methods without a supplied implementation. | ||
assert(hash_simple_array::<PoseidonHasher>([x, y]) == poseidon_expected_hash); | ||
|
||
// Now let's do the same logic but with a different `Hasher` supplied to the turbofish operator | ||
// We want to make sure that we have correctly monomorphized a function with a trait generic | ||
// where the generic is not used on any function parameters or the return value. | ||
let mut hasher = Poseidon2Hasher::default(); | ||
hasher.write(x); | ||
hasher.write(y); | ||
let poseidon2_expected_hash = hasher.finish(); | ||
assert(hash_simple_array::<Poseidon2Hasher>([x, y]) == poseidon2_expected_hash); | ||
} | ||
|
||
fn hash_simple_array<H>(input: [Field; 2]) -> Field where H: Hasher + Default { | ||
// Check that we can call a trait method instead of a trait implementation | ||
// TODO(https://github.com/noir-lang/noir/issues/5063): Need to remove the need for this type annotation | ||
// Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` | ||
let mut hasher: H = H::default(); | ||
// Regression that the object is converted to a mutable reference type `&mut _`. | ||
// Otherwise will see `Expected type &mut _, found type H`. | ||
// Then we need to make sure to also auto dereference later in the type checking process | ||
// when searching for a matching impl or else we will get `No matching impl found for `&mut H: Hasher` | ||
hasher.write(input[0]); | ||
hasher.write(input[1]); | ||
hasher.finish() | ||
} |