noir-lang / noir

Noir is a domain specific language for zero knowledge proofs
https://noir-lang.org
Apache License 2.0
821 stars 177 forks source link

feat: Insert trait impls into the program from type annotations #5327

Closed jfecher closed 4 days ago

jfecher commented 5 days ago

Description

Problem*

Resolves the vertical slice from this comment https://github.com/noir-lang/noir/issues/4594#issuecomment-2176746959

Summary*

This PR lets us actually insert the generated trait impl from the called macro into the program. Currently we only support inserting trait impls, functions, and globals to keep things simple. Each time these are inserted we have to call the def collection code on them so I wanted to avoid adding them all at once in a larger PR.

Additional Context

We can now generate impls for simple traits on a type! See the derive_impl test for details. The call site currently looks like this:

#[derive_default]
struct Foo {
    x: Field,
    y: Bar,
}

#[derive_default]
struct Bar {}

fn main() {
    let _foo: Foo = Default::default();
}

If Bar doesn't also derive Default the error that is issued is in the code to derive the impl unfortunately:

error: No matching impl found for `Bar: Default`
   ┌─ /.../derive_impl/src/main.nr:33:50
   │
33 │         result = result.push_back(quote { $name: Default::default(), });
   │                                                  ---------------- No impl for `Bar: Default`
   │

Since we only support unquoting a few items at top-level currently, here is what it looks like when we try to unquote a different item. In this case, a non-trait impl:

error: Unsupported statement type to unquote
   ┌─ /.../derive_impl/src/main.nr:23:1
   │  
23 │ ╭ #[derive_default]
24 │ │ struct Foo {
25 │ │     x: Field,
26 │ │     y: Bar,
27 │ │ }
   │ ╰─' Only functions, globals, and trait impls can be unquoted here
   │  
   = Unquoted item was:
     impl Foo {
         Attributes { function: None, secondary: [] }
         fn bar(self: Self) -> Self {
             self
         }
     }

Documentation*

Check one:

PR Checklist*