-
Notifications
You must be signed in to change notification settings - Fork 210
Implement traits, impls and generic functions with trait bounds #710
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
Conversation
a858bdb to
a268c9a
Compare
93c68c1 to
d0ba7c0
Compare
d0ba7c0 to
2f8a917
Compare
|
I just changed this back to draft because I will update it soon™ with all the remaining parts to cover |
588483d to
48525b2
Compare
91c3387 to
f97afea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments.
Also, the below code causes ICE.
trait Computable {
fn compute(self) -> u256;
}
struct Mac {
pub fn compute(self) -> u256 {
return 0
}
}
impl Computable for Mac {
fn compute(self) -> u256 {
return 1
}
}
contract Bar {
pub fn foo() -> u256 {
let mac: Mac = Mac()
return mac.compute()
}
pub fn foo2() -> u256 {
let mac: Mac = Mac()
return foo_computable(val: mac)
}
}
fn foo_computable<T: Computable>(val: T) -> u256 {
return val.compute()
}
thread 'main' panicked at 'should be lowered in `lower_types_in_functions`', crates/mir/src/lower/types.rs:25:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I haven't looked into this yet, but it'd be better to address this in this PR.
| pub enum TypeDef { | ||
| Alias(TypeAliasId), | ||
| Struct(StructId), | ||
| Trait(TraitId), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to discuss whether traits should be regarded as a type. For our use case, it feels be better to treat trait as an Item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes. That's a good point. I initially made it a type because I started by ignoring generics to just support something like:
pub fn bar(val: SomeTrait) {
}But then later I noticed that it would be better to add generics first and only support
pub fn bar<T: SomeTrait(val: T) {
}I don't know if we ever want to support the first example (or maybe val: impl SomeTrait as rust does) or just leave it to generics entirely. My current thinking is that we should not support the first example and leave it to generics to work with traits and hence could remove Trait as a type and add it as its own category of Item.
Thanks, this code should have been rejected because generics should not be supported yet outside of struct functions. Fixed it on my local machine. |
|
Ok, I misunderstood the cause of ICE. I wrote the test case to check what would happen when method name conflicts happen, and it caused ICE, so I wrongly suspected that function name conflict was the cause of the ICE. After modifying the test case, it causes ICE because of name conflicts this time. ↓ So we need to mangle the function name to fix the bug, I think it would be better to implement the mangling in |
f97afea to
9ff971e
Compare
|
Oh, I see. I believe this is because here we are considering the
Do you suggest to fix it here? Wouldn't that mean that we let Follow up question, we could fix that by making |
Partially yes, this is one of the concrete examples. But I didn't come up with a concrete example when I reviewed it, I just felt that it may reduce too much of the amount of information that should be kept.
Yes, it would work perfectly in this case. I just thought that name mangling should be performed in the codegen phase because the mangled name is never used from another compilation pass. But yes, fixing the class perfectly works in this case.
I think the "name" of the function would differ depending on the context. What context is in your head? Currently, the "name" of the function is used in two contexts,
Now, I'm feeling that defining separate two functions for the two purposes and removing |
5ac761f to
468e585
Compare
|
Thanks again for the feedback @Y-Nak I didn't feel like adding the removal of I think the only thing left from your suggestions is the removal of |
468e585 to
170460a
Compare
Y-Nak
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @cburgdorf!
we can leave that as is for now and revisit later as we extend and tune the trait support?
👍
Abstract
We want to have traits as well as generic functions with trait bounds. One of the main motivations is to properly implement
emiton theContextstruct aspub fn emit<T: Event>(val: T) { ... }How was it fixed?
Working example below:
https://github.com/ethereum/fe/blob/f97afea7937202e32b40de5f866b960b60d84c0a/crates/test-files/fixtures/features/generic_functions.fe#L1-L42
Some notes:
FunctionIdand intoFunctionSigIdto allow traits to reuse a bunch of code that doesn't care about the body anyway.trait PartialEq { pub fn eq<T>(self, other: T); })SomeTrait::some_fun()