noir
noir copied to clipboard
feat: Implement turbofish operator
Description
Problem*
Resolves #3413
Summary*
Adds the turbofish operator ::<>
to variables and method calls in Noir.
Additional Context
I'm publishing this as a draft because I'm shelving this work for now after implementing the majority of it.
The work that remains to be done is handling the special case of method calls on generic impls. A generic impl will implicitly add the impl generics to each method - which means the generic count on a method itself as seen by the turbofish operator will not match the actual generics on the function internally. We'll likely need to separate out these implicit generics internally. Such that expected_generic_count = function_generics - impl_generics
. I've added this as a test case to the generics
test to ensure it works when this is merged.
Documentation*
Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] [Exceptional Case] Documentation to be submitted in a separate PR.
- [x] No documentation is in this PR yet since it is still a draft.
PR Checklist*
- [x] I have tested the changes locally.
- [ ] I have formatted the changes with Prettier and/or
cargo fmt
on default settings.
Would be nice to revive it
This should be ready again for the original simple test cases. I will have follow-ups to enable the use case issues for turbofish listed in the original post of https://github.com/noir-lang/noir/issues/4710.
To handle implicit generics on an impl I save the number of generics on the object type when converting a method call to a regular call. We then prepend these implicit generics to the supplied turbofish generics on the function for constructing the new function call HirIdent. We need to do this as the Type::Forall
we will instantiate against will include these implicit generics along with the function generics. I kept the function generic count and implicit generics count as distinct variables as I found it to be simpler.
LGTM, lets add some formatter tests for completeness.
It looks like the tests you adding are failing. I will update them but we did have some other strange bugs and am working on follow-ups.
Odd, they were working locally.
Ah, it's due to the lack of stdlib. ~I can fix these~ Not gonna try and commit at the same time as you but copying the trait impls from the other test should fix it.
Not gonna try and commit at the same time as you but copying the trait impls from the other test should fix it.
Trying to wrap up a separate bug right now, but will get back to this shortly.
One more thing to note is implementing this in the new elaborator as well. I will add that before merging.
Ah, it's due to the lack of stdlib. ~I can fix these~ Not gonna try and commit at the same time as you but copying the trait impls from the other test should fix it.
Ok noirc_frontend tests are updated and should be passing. Added some basic formatter tests as well
Looks like the formatter is injecting unwanted spaces before the fish.
Are we planning to add docs for this now or later?
Are we planning to add docs for this now or later?
I'll do a follow-up as this is a pretty old PR so let's get this in first
Looks like the formatter is injecting unwanted spaces before the fish.
Hmm I'll look again I thought I had it working locally
In light of https://github.com/noir-lang/noir/pull/5049 I'm going to double check how turbofish arguments are stored for the monomorphizer. Please hold off on merging until then. (I can't request changes).
Edit: Looks fine to me. The turbofish args are correctly stored as the instantiation bindings.
This should be ready again
LGTM
Ok going to merge
Tried using it and got the error on the simplest example:
use dep::std::unsafe::zeroed;
fn main() -> pub Field {
fun::<2>()
}
fn fun<N>() -> Field {
0
}
error: expected type Field, found type ()
┌─ /Users/leonidlogvinov/Dev/ZK/trait_repro/src/main.nr:3:18
│
3 │ fn main() -> pub Field {
│ ----- expected Field because of return type
│ ╭────────────────────────'
4 │ │ fun::<2>()
5 │ │ }
│ ╰─' () returned here
│
error: Unexpected ::, expected one of binary operator, Ident
┌─ /Users/leonidlogvinov/Dev/ZK/trait_repro/src/main.nr:4:8
│
4 │ fun::<2>()
│ ---
│
Aborting due to 2 previous errors
I'm on Noir 0.30.0
Turbofish isn't in the 0.30.0 release, this code compiles fine on master.