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

Allow traits to be implemented for almost all types #755

Merged
merged 2 commits into from
Jul 1, 2022

Conversation

cburgdorf
Copy link
Collaborator

@cburgdorf cburgdorf commented Jun 28, 2022

What was wrong?

Currently traits can only be implemented for structs. The reason for that is that prior to monomorphization we do not know the Location of a type generic type (e.g. T) and for that reason hard coded it to Location::Memory which would exclude primitive types such as u8.

How was it fixed?

I made attempts to get rid of Location in the analyzer entirely but I kept failing. Then I realized that we actually don't yet allow to assign generic arguments anyway. Since the location is only relevant for when variables are assigned we could have used Location::Value and it would have worked exactly the same, it's superfluous information for now.
Hence, I thought we could introduce a Location::Unresolved for now and in return lift the restriction to allow traits to be implemented for all base types, arrays and tuples.

In addition this fixes two ICEs related to calling to_mem() or clone() on a generic type.

E.g.

trait Double {
  fn double(self) -> u256;
}

impl Double for u8 {
  fn double(self) -> u256 {
    return u256(self + self)
  }
}

impl Double for u16 {
  fn double(self) -> u256 {
    return u256(self + self)
  }
}

impl Double for (u256, u256) {
  fn double(self) -> u256 {
    return u256(self.item0 + self.item0 + self.item1 + self.item1)
  }
}

struct Runner {
  pub fn run<T: Double>(self, _ val: T) -> u256 {
    return val.double()
  }
}


contract Example {
  pub fn generic_compute(self) {
    let runner: Runner = Runner();
    assert runner.run(u8(1)) == 2
    assert runner.run(u16(1000)) == 2000
    assert runner.run((1, 1)) == 4
  }
}

@cburgdorf cburgdorf force-pushed the christoph/feat/generics-for-all branch from 35368e7 to 81aa152 Compare June 28, 2022 20:01
@cburgdorf cburgdorf requested a review from sbillig June 28, 2022 20:10
@cburgdorf cburgdorf marked this pull request as ready for review June 28, 2022 20:10
Copy link
Collaborator

@sbillig sbillig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 😎 👍

@sbillig sbillig merged commit b1cbf87 into ethereum:master Jul 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants