noir icon indicating copy to clipboard operation
noir copied to clipboard

Polymorphic Trait Inheritance Fails

Open michaeljklein opened this issue 4 months ago • 0 comments

Aim

Attempted to compile the following programs:

Single inheritance:

trait Foo {
    fn foo(self) -> Self;
}

trait Baz: Foo {}

impl<T> Baz for T where T: Foo {}

fn main() { }

Double inheritance:

trait Foo {
    fn foo(self) -> Self;
}

trait Bar {
    fn bar(self) -> Self;
}

trait Baz: Foo + Bar {}

impl<T> Baz for T where T: Foo + Bar {}

fn main() { }

Expected Behavior

Expected the programs to compile successfully

Bug

Compilation fails with:

Single inheritance:

error: The trait bound `T: Foo` is not satisfied
  ┌─ src/main.nr:5:12
  │
5 │ trait Baz: Foo {}
  │            --- required by this bound in `Baz
6 │ 
7 │ impl<T> Baz for T where T: Foo {}
  │                 - The trait `Foo` is not implemented for `T
  │

Aborting due to 1 previous error

Double inheritance:

error: The trait bound `T: Foo` is not satisfied
   ┌─ src/main.nr:9:12
   │
 9 │ trait Baz: Foo + Bar {}
   │            --- required by this bound in `Baz
10 │ 
11 │ impl<T> Baz for T where T: Foo + Bar {}
   │                 - The trait `Foo` is not implemented for `T
   │

error: The trait bound `T: Bar` is not satisfied
   ┌─ src/main.nr:9:18
   │
 9 │ trait Baz: Foo + Bar {}
   │                  --- required by this bound in `Baz
10 │ 
11 │ impl<T> Baz for T where T: Foo + Bar {}
   │                 - The trait `Bar` is not implemented for `T
   │

Aborting due to 2 previous errors

(Could be related to https://github.com/noir-lang/noir/issues/6023, but this where clause is on an impl)

To Reproduce

Workaround

Yes

Workaround Description

Define each impl of the "trait alias" trait Baz monomorphically:

trait Foo {
    fn foo(self) -> Self;
}

trait Bar {
    fn bar(self) -> Self;
}

trait Baz: Foo + Bar {}

impl Foo for Field {
    fn foo(self) -> Self {
        self + 1
    }
}

impl Bar for Field {
    fn bar(self) -> Self {
        self + 2
    }
}

// impl<T> Baz for T where T: Foo + Bar {}
impl Baz for Field {}

fn main() {
    assert(0.foo().bar() == 3);
}

Additional Context

No response

Project Impact

Nice-to-have

Blocker Context

No response

Nargo Version

nargo version = 0.35.0 noirc version = 0.35.0+51ae1b324cd73fdb4fe3695b5d483a44b4aff4a9 (git version hash: 51ae1b324cd73fdb4fe3695b5d483a44b4aff4a9, is dirty: false)

NoirJS Version

No response

Proving Backend Tooling & Version

No response

Would you like to submit a PR for this Issue?

None

Support Needs

No response

michaeljklein avatar Oct 22 '24 17:10 michaeljklein