static assert(0) in template is a disaster

Nils Lankila NilsLankila at gmx.us
Tue Jun 16 14:05:28 UTC 2020


Today I've decided to test the new -vtemplates feature.
I don't know if what i've found is already known but it looks 
like a dormant disaster in phobos.

So if you compile dparse with -vtemplate you'll get for example 
this strange thing:

>       694      694   AliasThisTypeOf(T) if (isAggregateType!T)

That's for the less very suspicious: 694 instantiations, 694 
unique instances !
So I've put a pragma msg in the template to check that every 
template parameter passed is unique. It's definitively not the 
case.

`AliasThisTypeOf` is really a simple template that wraps a 
compiler `__traits`:

>  private template AliasThisTypeOf(T)
>  if (isAggregateType!T)
>  {
>      alias members = __traits(getAliasThis, T);
> 
>      static if (members.length == 1)
>      {
>          alias AliasThisTypeOf = typeof(__traits(getMember, 
> T.init, members[0]));
>      }
>      else
>          static assert(0, T.stringof~" does not have alias this 
> type");
>  }

The problem can only comes from the assertion. So I've changed 
the implementation to

>  private template AliasThisTypeOf(T)
>  if (isAggregateType!T)
>  {
>      alias members = __traits(getAliasThis, T);
>
>      static if (members.length == 1)
>      {
>          alias AliasThisTypeOf = typeof(__traits(getMember, 
> T.init, members[0]));
>      }
>      else
>          alias AliasThisTypeOf = AliasSeq!();
>  }

And recompiled dparse. The results look more coherant now:

>       694      167   AliasThisTypeOf(T) if (isAggregateType!T)

conclusion: avoid static `assert(0)` in templates bodies. They 
prevent instance uniqueness. `std.traits` contains plenty of them 
and they should be removed in favor of something similar to 
what's done here.


More information about the Digitalmars-d mailing list