-
Notifications
You must be signed in to change notification settings - Fork 252
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
[BUG] @value @struct type
doesn't compile
#447
Comments
I think the current behavior is by design. The meta functions list is a pipe of transformations with the type as input. You're suggesting to make the process impossible to be pure by introducing dependent state. |
My first though was, since constructors emitted from reflection API, they could be marked somehow to distinguish cppfront-generated from user-defined. Probably thats just extra flag in node. I haven't looked at code, but suppose type formed from text code, then meta applied, so it possibly can be tracked. Last suggestion can be scratched off. Regarding pipe, could it be then some @meta1 writes something, then @meta2 overwrites it, breaking @meta1 assumption? Currently I haven't found such cases, but could it be in future? |
It doesn't break Your suggestion can also be done as a library. |
Ok you motivated me to find better (or worse) example :)
Compiles, having nonvirtual function
While I understand what you mean, by metaclasses are executed compile time programs, this feels like broken expectation for programmer, since I declaratively asked it to be interface, and it's contradicting requirements aren't checked. |
That's a fair case. |
One more finding, |
One idea, if combining requirements isn't possible, have syntax like Another wild idea, run meta application twice, allowing earlier metas to recheck if they still hold. I haven't explored in depth, will it work in any cases; but possibly this could work with imposed limitations, that metas only either check for some condition, or check+emit, in second pass emit could be skipped. |
Should this even be supported? There are metaclasses that contradict each other as shown in comments above. So should we enable this feature just to support a small set of combinations? Probably not |
Probably, I have reported for that particular issue, but probably it can be superseded with bigger issue, if multiple metaclasses should be allowed at all. On the other hand, it could be reasonable to have something Also interaction with inheritance should be explored, i.e
(polymorphic_base is planned to change, but currently it is not allowing data) |
Something that concerns me is the use of |
You can see a use-case by |
Edit: author answered that is intent. |
Yeah, you did comment on that at 38aec57#r113218852. |
See #447 comment thread and 38aec57#r113218852
Ah, that "noncopyable" is a stray comment from an earlier design I was trying out. Thanks for the catch, comment fixed. |
While I'm here: Yes, the design is to pipeline these. And I'm still considering the |
Then this can be closed, I think? Since it's probably not worth effort and should be programmer responsibility. |
OK, and thanks again. |
That sounds like a terribly limited feature. Opting into a nominal interface is much more generally useful |
Maybe I don't fully understand your point, but is it similar to deriving feature in haskell. We have interfaces in cpp2, but they are limited as the user has to implement the methods himself or he could rely on default implementation which is not always enough (default implementation can't access members). Using metaprogramming, we could make it so that implementations could be generated for a type.
currently this is baked into the language but this could be user-written with reflection. I'm talking about somethings like |
According to grammar and other notes, type can have several metaclasses
meta-functions-list: meta-functions-list '@' id-expression
But compilation depends on order of those declaration.
S : @struct @value type = { i: int = 0; }
Compiles
S : @value @struct type = { i: int = 0; }
error: while applying @struct - a struct may not have a user-defined operator=
Another example
S : @interface @polymorphic_base type = { }
Compiles
S : @polymorphic_base @interface type = { }
error: while applying @interface - interface functions must not have a function body; remove the '=' initializer
https://cpp2.godbolt.org/z/4v47aGcGn
Version
latest (38aec57)
Command lines
cppfront/cppfront $1.cpp2 -p
clang++-15 -Icppfront/include $1.cpp -std=c++20 -o $1
Expected result
Consistent compilation result, not depending on order
Additional notes
In this particular combination, @struct check there are no user operator=, and then emits its own as basic_value.
But as @value already emitted it's own, @struct doesn't distinguish that those aren't user defined.
For @interface that's probably add_virtual_destructor from @polymorphic base.
Optional Enhancement Suggestion
Other combinations can give errors both cases, but different depending on order.
For example,
S: @interface @value type //error: while applying @value - a value type may not have a protected or virtual function
S: @value @interface type //error: while applying @interface - interfaces may not copy or move; consider a virtual clone() instead
Suggestion - applying of @meta can track and signal what @Metas are contradicting.
The text was updated successfully, but these errors were encountered: