[WIP] fix issue 7804 - Allow __traits(getMember) as a BasicType#8031
Conversation
|
Thanks for your pull request and interest in making D better, @bbasile! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
|
| } | ||
| else if (strcmp(te.ident.toChars, "getMember") != 0) | ||
| { | ||
| error("invalid `__traits`, only `getMember` can be aliased and not `%s`", |
There was a problem hiding this comment.
Should this really be handled by the parser?
There was a problem hiding this comment.
Yes. It's a semantic thing but it can be handled eagerly.
|
Nice work on handling such an ancient issue! |
src/dmd/dmangle.d
Outdated
| Tslice : '@', | ||
| Treturn : '@', | ||
| Tvector : '@', | ||
| TTraits : '@', |
There was a problem hiding this comment.
I think this should be Ttraits to follow the naming conventions.
src/dmd/parse.d
Outdated
| { | ||
| AST.TraitsExp te; | ||
| if (AST.Expression e = parsePrimaryExp()) | ||
| te = cast(AST.TraitsExp) e; |
There was a problem hiding this comment.
How about :
AST.Traits te = cast(AST.TraitsExp)parsePrimaryExp();
src/dmd/parse.d
Outdated
| te.ident.toChars); | ||
| t = new AST.TypeError; | ||
| } | ||
| else t = new AST.TypeTraits(loc, te); |
There was a problem hiding this comment.
Brackets for if/else bodies should be consistent (use {} for all or for none).
| buf.writestring(t.dstring); | ||
| } | ||
|
|
||
| override void visit(TypeTraits t) |
There was a problem hiding this comment.
A similar visit method should be added in the ParseTimeTransitiveVisitor [1] otherwise the tree traversal will be truncated.
[1] https://github.com/dlang/dmd/blob/master/src/dmd/transitivevisitor.d
|
|
||
| /** | ||
| */ | ||
| extern (C++) final class TypeTraits : Type |
There was a problem hiding this comment.
Please add some documentation for this class : why is it needed, when it is created and what information is kept in each field. Hope that is the intent with the empty comments 👍
There was a problem hiding this comment.
Indeed i planned to do it but forgot to.
|
First part, handling of types, is done now. Will start the second soon. |
src/dmd/parse.d
Outdated
| // error already emitted while parsing primary | ||
| t = new AST.TypeError; | ||
| } | ||
| else if (strcmp(te.ident.toChars, "getMember") != 0) |
There was a problem hiding this comment.
strcmp must die. Really, everyone, please stop using it! Use if (te.ident == Id.getMember).
There was a problem hiding this comment.
Would be good to approve sth. like #7893 then, s.t. we can start using DStrings everywhere.
| result = t.addMod(mtype.mod); | ||
| //if (result) printf("TypeTraits found to be %s\n".ptr, result.toChars); | ||
| if (result is null) | ||
| mtype.error(loc, "`%s` cannot be resolved to a valid type", |
There was a problem hiding this comment.
definitely need a test case for this
src/dmd/mtype.d
Outdated
| Tvector, | ||
| Tint128, | ||
| Tuns128, | ||
|
|
| override void visit(TypeTraits t) | ||
| { | ||
| //printf("TypeBasic::toCBuffer2(t.mod = %d)\n", t.mod); | ||
| visit(t.exp); |
src/dmd/mtype.d
Outdated
| } | ||
|
|
||
| /** | ||
| * This type is a shell containing a TraitsExp that can be |
There was a problem hiding this comment.
This type is a is completely redundant and can be elided.
|
(@reviewers: don't forget that this requires a PR to dlang.org with the spec update before this can be merged) |
src/dmd/mtype.d
Outdated
| { | ||
| this.loc = loc; | ||
| this.exp = exp; | ||
| super(Ttraits); |
There was a problem hiding this comment.
super call should go first.
src/dmd/mtype.d
Outdated
| { | ||
| TypeTraits tt; | ||
| TraitsExp te = cast(TraitsExp) exp.syntaxCopy(); | ||
| tt = new TypeTraits(loc, te); |
There was a problem hiding this comment.
Declare tt here, not on line 5250
| } | ||
| } | ||
|
|
||
| extern (C++) class TypeTraits : Type |
There was a problem hiding this comment.
Needs an entry in visitor.d, too.
There was a problem hiding this comment.
If i do so i get a conflict with the entry in transitivevisitor.d
| t = parseVector(); | ||
| break; | ||
|
|
||
| case TOK.traits: |
There was a problem hiding this comment.
Also needs entry in isBasicType(), parseMixin(), parseStatement(), parsePrimaryExp() and parseUnaryExp(). Basically, just look at where TOK.typeof_ appears, which is very similar.
|
I approve of the concept, but this needs much work. It'll need 100% test coverage. It also needs a changelog entry, and a spec change. |
|
I give the hand if someone wants to continue. It's not too hard to finish but i don't want to work on this anymore. |
|
Is there anyone that knows how to kick this across the line, or is this dead? :( |
|
This was almost finished actually, the second part didn't require to add a new AST node. |
To allow
alias AggrMember = __traits(getMember, Aggr, "member");TheBasicTypegrammar must be changed, since it's used byAliasDeclarationY.BasicType: BasicTypeX . IdentifierList IdentifierList Typeof Typeof . IdentifierList TypeCtor ( Type ) TypeVector + TraitsAs a bonus, declarations work with a
__traitsas type.Another more limited option would have been to change the grammar of
AliasDeclarationY:AliasDeclarationY: Identifier TemplateParametersopt = StorageClassesopt Type + Identifier TemplateParametersopt = StorageClassesopt Traits Identifier TemplateParametersopt = FunctionLiteralFor now, only Types are handled. A second part will allow this for Symbols.