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

Trait specialization for array and slice leads to compilation error #3502

Closed
grasshopper47 opened this issue Nov 17, 2023 · 3 comments
Closed
Labels
bug Something isn't working

Comments

@grasshopper47
Copy link
Contributor

grasshopper47 commented Nov 17, 2023

Aim

To implement a trait with dynamic behavior for an array type and a slice type

trait Extension
{
    fn echo(self);
}

impl<N> Extension for [u8; N]
{
    fn echo(self) { dep::std::println("array print"); }
}

impl Extension for [u8]
{
    fn echo(self) { dep::std::println("slice print"); }
}

Expected Behavior

Code should compile as is because the underlying types are supposed to be different.

NOTE

While this approach is nice because one can create an implementation for both types without duplicating the code, it is also inconsistent with other parts of the language. I cannot pass a slice to a method accepting an array, nor vice-versa (but it would be a great feature to have!!). In this issue's case however, it seemingly does indeed pass different instance types to "the same" (?!) method signature...

Bug

Error received on compilation: Impl for type [u8] overlaps with existing impl

Linked issue: #3474

Tried a different approach:

trait ArrayExtension
{
    fn echo(self);
}

impl<N> ArrayExtension for [u8; N]
{
    fn echo(self) { dep::std::println("array print"); }
}

trait SliceExtension
{
    fn echo(self);
}

impl SliceExtension for [u8]
{
    fn echo(self) { dep::std::println("slice print"); }
}

#[test]
unconstrained
fn test_print()
{
    let a_array : [u8; 3] = [1,2,3];
    let a_slice : [u8] = [1,2,3];

    a_array.echo();
    a_slice.echo();
}

This compiles, but echoes array print for both lines, which isn't expected.

It should output array print, then slice print

To Reproduce

Compile the examples above

Installation Method

Binary

Nargo Version

noirc version = 0.19.2+d7f919dcc001080ed24616ebbc37426ef7ac7638

Additional Context

No response

Would you like to submit a PR for this Issue?

No

Support Needs

No response

@jfecher
Copy link
Contributor

jfecher commented Nov 17, 2023

This is actually expected currently as a result of array literals being polymorphic over array or slice types. Fixing this would require a design change to separate "polymorphic over an array's size or a slice" from just "polymorphic over an array's size." Alternately since this feature is mostly unused by users we could remove it from the stdlib and duplicate the stdlib functions like len, map, etc that use it.

@jfecher
Copy link
Contributor

jfecher commented Nov 17, 2023

Also, please note that traits are still experimental so expect some bugs 🙂

@grasshopper47
Copy link
Contributor Author

grasshopper47 commented Nov 17, 2023

This is actually expected currently as a result of array literals being polymorphic over array or slice types. Fixing this would require a design change to separate "polymorphic over an array's size or a slice" from just "polymorphic over an array's size.

OK, then if it is documented, that would be preferred. It allows for considerable code reduction (duplicated definitions like your suggestion below).

Alternately since this feature is mostly unused by users we could remove it from the stdlib and duplicate the stdlib functions like len, map, etc that use it.

Probably no, better avoid this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

2 participants