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

Generic impl selfs don't really work #814

Closed
sezna opened this issue Feb 17, 2022 · 8 comments · Fixed by #913
Closed

Generic impl selfs don't really work #814

sezna opened this issue Feb 17, 2022 · 8 comments · Fixed by #913
Assignees
Labels
bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged

Comments

@sezna
Copy link
Contributor

sezna commented Feb 17, 2022

title

@sezna sezna self-assigned this Feb 17, 2022
@sezna
Copy link
Contributor Author

sezna commented Feb 17, 2022

script;

struct DoubleIdentity<T, F> {
  first: T,
  second: F
}

fn double_identity<T, F>(x: T, y: F) -> DoubleIdentity<T, F> {
  DoubleIdentity {
    first: x,
    second: y
  }
}

fn main() -> bool {
  let double_a = double_identity(true, true);
  let double_b = double_identity(10u32, 43u64);

  // for testing annotations
  let double_a: DoubleIdentity<bool, bool> = double_identity(true, true);
  let double_b: DoubleIdentity<u32, u64> = double_identity(10u32, 43u64);

  double_a.first
}

impl DoubleIdentity<T, F> {
  fn test(a: T) {  }
}

@mohammadfawaz
Copy link
Contributor

mohammadfawaz commented Feb 17, 2022

An even simpler example seems to have the same problem:

script;

struct DoubleIdentity<T> {
  first: T,
}

impl DoubleIdentity<T> {
  fn test(a: T) {  }
}

fn main() {
}

@sezna sezna mentioned this issue Feb 17, 2022
19 tasks
@adlerjohn adlerjohn added bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged labels Feb 19, 2022
@adlerjohn adlerjohn moved this to Todo in Fuel Network Feb 19, 2022
@emilyaherbert
Copy link
Contributor

Are we wanting this syntax:

impl DoubleIdentity<T, F> {
  fn test(a: T) {  }
}

or this syntax (what Rust does):

impl<T, F> DoubleIdentity<T, F> {
  fn test(a: T) {  }
}

CC @adlerjohn @sezna

@sezna
Copy link
Contributor Author

sezna commented Feb 22, 2022

We discussed this briefly and I think the simpler syntax is sufficient for us, although I think we should discuss it.

@emilyaherbert
Copy link
Contributor

emilyaherbert commented Feb 22, 2022

Personally I feel that this syntax:

impl<T, F> DoubleIdentity<T, F> {
  fn test(a: T) {  }
}

would be a preferable developer experience on Sway. Users will either 1) recognize the syntax coming over from Rust, or will 2) not realize and just acknowledge it as slightly cumbersome at worst. What I want to avoid is a situation in which a Rust person is using Sway and the language constructs for Sway generics diverts their expectations. I feel that if the implementation and use-case for Sway generics is the same as for Rust generics, then the syntax should be the same.

@otrho
Copy link
Contributor

otrho commented Feb 22, 2022

I was wondering why there is this redundancy. From the book:

Note that we have to declare T just after impl so we can use it to specify that we’re implementing methods on the type Point. By declaring T as a generic type after impl, Rust can identify that the type in the angle brackets in Point is a generic type rather than a concrete type. Because this is declaring the generic again, we could have chosen a different name for the generic parameter than the generic parameter declared in the struct definition, but using the same name is conventional. Methods written within an impl that declares the generic type will be defined on any instance of the type, no matter what concrete type ends up substituting for the generic type.

So it's to ensure that T is a generic type in the context of T being a type parameter for the struct.

@emilyaherbert emilyaherbert assigned emilyaherbert and unassigned sezna Feb 22, 2022
@otrho
Copy link
Contributor

otrho commented Feb 23, 2022

Is this a similar issue?

script;

struct Wrapper<T> {
    value: T,
}

impl Wrapper<T> {
    fn foo(self) {
    }
}

fn main() {
    let f: Wrapper<bool> = Wrapper { value: true };
    f.foo()
}
   |
29 |
30 |     let f: Wrapper<bool> = Wrapper { value: true };
31 |     f.foo()
   |       ^^^ No method named "foo" found for type "struct Wrapper<bool>".
32 | }
   |

There's no error if you pass f to a function and try calling foo() there.

@sezna
Copy link
Contributor Author

sezna commented Feb 23, 2022

Yes, monomorphizing on structs and enums was not finished. It was only fully implemented for functions. I'm wrapping that up on my branch right now: #625

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged
Projects
Archived in project
5 participants