Bug 19420 – [master] TypeTrait semantic fails for non static aggregate members

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-11-21T21:13:38Z
Last change time
2018-11-26T14:42:39Z
Assigned to
No Owner
Creator
Basile-z

Comments

Comment #0 by b2.temp — 2018-11-21T21:13:38Z
With DMD ~master --- alias Seq(T...) = T; class One { int foo; void test() { alias p1 = Seq!(__traits(getMember, this, "foo"))[0]; alias p2 = __traits(getMember, this, "foo"); static assert(__traits(isSame, p1, p2)); } } void main(){} --- gives: ---- Error: static assert: `__traits(isSame, foo, int)` is false ---- with the new syntax `foo` is replaced by to its type: TypeTrait semantic tries getSymbol() on the trait. If this fails, it calls getType() which takes the type of the expression when this expression is not a type. There's something missing to transform the trait in dsymbol before it falls back to getType()
Comment #1 by b2.temp — 2018-11-22T08:34:49Z
When i think to what AliasSeq does maybe that the semantic for TypeTrait should always create a tuple and let the aliasSemantic() do its job on this tuple, without adding any pre-processing...
Comment #2 by b2.temp — 2018-11-22T08:45:14Z
(In reply to Basile B. from comment #1) > When i think to what AliasSeq does maybe that the semantic for TypeTrait > should always create a tuple and let the aliasSemantic() do its job on this > tuple, without adding any pre-processing... This but only when within an AliasDeclaration. Not sure if this would work when the __trait expression is used in place of a type (cast, var decl, etc)...
Comment #3 by b2.temp — 2018-11-22T10:46:39Z
This works for fixing this bug but then type solving from a __traits() that's inside an alias is broken: ``` override void visit(TypeTraits mtype) { import dmd.traits : semanticTraits; result = null; if (mtype.ty == Terror) { result = mtype; return; } if (mtype.exp.ident != Id.allMembers && mtype.exp.ident != Id.derivedMembers && mtype.exp.ident != Id.getMember && mtype.exp.ident != Id.parent && mtype.exp.ident != Id.getOverloads && mtype.exp.ident != Id.getVirtualFunctions && mtype.exp.ident != Id.getVirtualMethods && mtype.exp.ident != Id.getAttributes && mtype.exp.ident != Id.getUnitTests) { static immutable (const(char)*)[2] ctxt = ["as type", "in alias"]; .error(mtype.loc, "trait `%s` is either invalid or not supported %s", mtype.exp.ident.toChars, ctxt[mtype.inAliasDeclaration]); result = mtype; mtype.ty = Terror; return; } if (Expression e = semanticTraits(mtype.exp, sc)) { if (mtype.inAliasDeclaration) { Dsymbol aliased; if (TupleExp te = e.toTupleExp) { aliased = new TupleDeclaration(mtype.loc, Identifier.generateId("__aliastupmulti"), cast(Objects*) te.exps); } else { Objects* exps = new Objects(1); (*exps)[0] = e; TupleDeclaration td = new TupleDeclaration(mtype.loc, Identifier.generateId("__aliastupsingle"), exps); aliased = td; } AliasDeclaration ad = new AliasDeclaration(mtype.loc, Identifier.generateId("__aliastup"), aliased); aliasSemantic(ad, sc); mtype.sym = ad.aliassym ? ad.aliassym.toAlias2() : null; result = ad.type ? ad.type : new TypeError(); } else if (Type t = getType(e)) { result = t.addMod(mtype.mod); } else result = new TypeError(); } if (!mtype.inAliasDeclaration && !result) { if (!global.errors) .error(mtype.loc, "`%s` does not give a valid type", mtype.toChars); result = mtype; mtype.ty = Terror; } } ``` so when __aliastupsingleN represents a type. At this point it's a put them in the right order game.
Comment #4 by razvan.nitu1305 — 2018-11-22T13:58:17Z