-
-
Notifications
You must be signed in to change notification settings - Fork 657
[WIP] fix issue 7804 - Allow __traits(getMember) as a BasicType #8031
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -784,6 +784,12 @@ public: | |
| buf.writestring(t.dstring); | ||
| } | ||
|
|
||
| override void visit(TypeTraits t) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A similar visit method should be added in the [1] https://github.com/dlang/dmd/blob/master/src/dmd/transitivevisitor.d |
||
| { | ||
| //printf("TypeBasic::toCBuffer2(t.mod = %d)\n", t.mod); | ||
| visit(t.exp); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need test case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is tested hdrgen ? |
||
| } | ||
|
|
||
| override void visit(TypeVector t) | ||
| { | ||
| //printf("TypeVector::toCBuffer2(t.mod = %d)\n", t.mod); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -513,6 +513,7 @@ final class Parser(AST) : Lexer | |
| case TOK.union_: | ||
| case TOK.class_: | ||
| case TOK.interface_: | ||
| case TOK.traits: | ||
| Ldeclaration: | ||
| a = parseDeclarations(false, pAttrs, pAttrs.comment); | ||
| if (a && a.dim) | ||
|
|
@@ -3495,6 +3496,28 @@ final class Parser(AST) : Lexer | |
| t = parseVector(); | ||
| break; | ||
|
|
||
| case TOK.traits: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also needs entry in |
||
| { | ||
| AST.TraitsExp te = cast(AST.TraitsExp) parsePrimaryExp(); | ||
| if (!te) | ||
| { | ||
| // error already emitted while parsing primary | ||
| t = new AST.TypeError; | ||
| } | ||
| else if (te.ident != Id.getMember) | ||
| { | ||
| // even if this is not a grammar error, it's not worth continuing. | ||
| error("invalid `__traits`, only `getMember` can be aliased and not `%s`", | ||
| te.ident.toChars); | ||
| t = new AST.TypeError; | ||
| } | ||
| else | ||
| { | ||
| t = new AST.TypeTraits(loc, te); | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| case TOK.const_: | ||
| // const(type) | ||
| nextToken(); | ||
|
|
@@ -6502,6 +6525,16 @@ final class Parser(AST) : Lexer | |
| goto Lfalse; | ||
| goto L3; | ||
|
|
||
| case TOK.traits: | ||
| // __traits(getMember | ||
| t = peek(t); | ||
| if (t.value != TOK.leftParentheses) | ||
| goto Lfalse; | ||
| t = peek(t); | ||
| if (t.value != TOK.identifier || t.ident != Id.getMember) | ||
| goto Lfalse; | ||
| break; | ||
|
|
||
| case TOK.const_: | ||
| case TOK.immutable_: | ||
| case TOK.shared_: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1307,6 +1307,21 @@ private extern (C++) final class TypeSemanticVisitor : Visitor | |
| result = t; | ||
| } | ||
|
|
||
| override void visit(TypeTraits mtype) | ||
| { | ||
| import dmd.traits : semanticTraits; | ||
| import dmd.dtemplate : getType; | ||
|
|
||
| result = null; | ||
| if (Expression e = semanticTraits(mtype.exp, sc)) | ||
| if (Type t = getType(e)) | ||
| 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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. definitely need a test case for this |
||
| mtype.toChars()); | ||
| } | ||
|
|
||
| override void visit(TypeReturn mtype) | ||
| { | ||
| //printf("TypeReturn::semantic() %s\n", toChars()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| /* | ||
| TEST_OUTPUT: | ||
| --- | ||
| fail_compilation/e7804_1.d(9): Error: invalid `__traits`, only `getMember` can be aliased and not `farfelu` | ||
| --- | ||
| */ | ||
| module e7804_1; | ||
|
|
||
| __traits(farfelu, Aggr, "member") a; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| module e7804; | ||
|
|
||
| struct Bar {static struct B{}} | ||
| alias BarB = __traits(getMember, Bar, "B"); | ||
| static assert(is(BarB == Bar.B)); | ||
| static assert(is(const(__traits(getMember, Bar, "B")) == const(Bar.B))); | ||
|
|
||
|
|
||
| struct Foo {alias MyInt = int;} | ||
| alias FooInt = __traits(getMember, Foo, "MyInt"); | ||
| static immutable FooInt fi = 42; | ||
| static assert(fi == 42); | ||
|
|
||
|
|
||
| enum __traits(getMember, Foo, "MyInt") a0 = 12; | ||
| static assert(is(typeof(a0) == int)); | ||
| static assert(a0 == 12); | ||
|
|
||
|
|
||
| const __traits(getMember, Foo, "MyInt") a1 = 46; | ||
| static this(){assert(a1 == 46);} | ||
|
|
||
|
|
||
| __traits(getMember, Foo, "MyInt") a2 = 78; | ||
| static this(){assert(a2 == 78);} | ||
|
|
||
|
|
||
| const(__traits(getMember, Foo, "MyInt")) a3 = 63; | ||
| static this(){assert(a3 == 63);} | ||
|
|
||
|
|
||
| void main(){} |
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.
Needs an entry in
visitor.d, too.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.
If i do so i get a conflict with the entry in
transitivevisitor.d