| Thread overview | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 17, 2016 typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
I have a problem, that .stringof doesn't return what I'm expecting. Consider the following:
template A(string T)
{
enum A : bool
{
yes = true,
}
}
void main()
{
A!"asdf" a1;
typeof(a1) a2;
mixin(typeof(a1).stringof ~ " a3;");
}
I get an error: some.d-mixin-13|13 error| Error: template some.A(string T) is used as a type
Why the second line in main() works but the third one not? typeof(a1).stringof seems to ignore the string template parameter T.
pragma(msg, typeof(a1).stringof) would return just "A".
Is it a bug?
| ||||
August 17, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Eugene Wissner | On 08/17/2016 02:08 PM, Eugene Wissner wrote: > I have a problem, that .stringof doesn't return what I'm expecting. > Consider the following: > > template A(string T) > { > enum A : bool > { > yes = true, > } > } > > void main() > { > A!"asdf" a1; > typeof(a1) a2; > mixin(typeof(a1).stringof ~ " a3;"); > } > > I get an error: some.d-mixin-13|13 error| Error: template some.A(string > T) is used as a type > > Why the second line in main() works but the third one not? > typeof(a1).stringof seems to ignore the string template parameter T. > pragma(msg, typeof(a1).stringof) would return just "A". > > Is it a bug? Not exactly a bug. .stringof gives you a simple, readable name. It's not meant to be used in code generation. You can use std.traits.fullyQualifiedName instead: import std.traits: fullyQualifiedName; mixin(fullyQualifiedName!(typeof(a1)) ~ " a3;"); | |||
August 17, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Wednesday, 17 August 2016 at 12:39:18 UTC, ag0aep6g wrote:
> On 08/17/2016 02:08 PM, Eugene Wissner wrote:
>> I have a problem, that .stringof doesn't return what I'm expecting.
>> Consider the following:
>>
>> template A(string T)
>> {
>> enum A : bool
>> {
>> yes = true,
>> }
>> }
>>
>> void main()
>> {
>> A!"asdf" a1;
>> typeof(a1) a2;
>> mixin(typeof(a1).stringof ~ " a3;");
>> }
>>
>> I get an error: some.d-mixin-13|13 error| Error: template some.A(string
>> T) is used as a type
>>
>> Why the second line in main() works but the third one not?
>> typeof(a1).stringof seems to ignore the string template parameter T.
>> pragma(msg, typeof(a1).stringof) would return just "A".
>>
>> Is it a bug?
>
> Not exactly a bug. .stringof gives you a simple, readable name. It's not meant to be used in code generation. You can use std.traits.fullyQualifiedName instead:
>
> import std.traits: fullyQualifiedName;
> mixin(fullyQualifiedName!(typeof(a1)) ~ " a3;");
What I find strange is that if A isn't a enum, but a class the .stringof returns the full type name, therefore I would expect it behave the same in the code above.
I will test later fullyQualifiedName, the example above is very simplified version of the code I had problem with. Thanks anyway
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | fullyQualifiedName doesn't work with BitFlags for example:
import std.stdio;
import std.typecons;
import std.traits;
enum Stuff
{
asdf
}
void main()
{
BitFlags!Stuff a;
typeof(a) b;
mixin(fullyQualifiedName!(typeof(a)) ~ " c;");
mixin(typeof(a).stringof ~ " d;");
}
Both mixins fail. fullyQualifiedName!(typeof(a)) becomes:
std.typecons.BitFlags!(test.Stuff, cast(Flag)false)
"cast(Flag)false" should be "cast(Flag!"unsafe")false". So string template parameter "unsafe" is missing. The same problem as I described before ("Flag" is an enum template like in my first example).
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Eugene Wissner | On 08/19/2016 02:42 PM, Eugene Wissner wrote:
> fullyQualifiedName doesn't work with BitFlags for example:
I think that qualifies as a bug, because fullyQualifiedName is supposed to be usable in code generation.
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Friday, 19 August 2016 at 15:15:55 UTC, ag0aep6g wrote:
> I think that qualifies as a bug, because fullyQualifiedName is supposed to be usable in code generation.
This is a misconception. Neither .stringof nor fullyQualifiedName should *ever* be used in code generation. There is a myriad of things that make strings unsuitable in the general case. The most obvious reason are imports: think a type coming via an alias parameter from a second module, which is not even important at the point of the mixin.
Instead of trying to make .stringof work do things it will never be able to, you need to use the type just as you would at the point of the mixin. In this example, you would write `mixin("typeof(a) d");`.
— David
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 08/19/2016 05:36 PM, David Nadlinger wrote: > This is a misconception. Neither .stringof nor fullyQualifiedName should > *ever* be used in code generation. The spec itself recommends fullyQualifiedName for code generation: > Note: Using .stringof for code generation is not recommended, as the internal representation of a type or expression can change between different compiler versions. > > Instead you should prefer to use the identifier trait, or one of the Phobos helper functions such as fullyQualifiedName. https://dlang.org/spec/property.html#stringof Someone should edit that, if fullyQualifiedName is no good either. | |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Friday, 19 August 2016 at 15:47:00 UTC, ag0aep6g wrote:
> https://dlang.org/spec/property.html#stringof
>
> Someone should edit that, if fullyQualifiedName is no good either.
Indeed. I'm sure the change was well-intentioned, but symbol visibility/import concerns and Voldemort types should make it abundantly clear that this can't work ever work in the general case.
— David
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Friday, August 19, 2016 15:36:02 David Nadlinger via Digitalmars-d-learn wrote:
> On Friday, 19 August 2016 at 15:15:55 UTC, ag0aep6g wrote:
> > I think that qualifies as a bug, because fullyQualifiedName is supposed to be usable in code generation.
>
> This is a misconception. Neither .stringof nor fullyQualifiedName should *ever* be used in code generation. There is a myriad of things that make strings unsuitable in the general case. The most obvious reason are imports: think a type coming via an alias parameter from a second module, which is not even important at the point of the mixin.
>
> Instead of trying to make .stringof work do things it will never be able to, you need to use the type just as you would at the point of the mixin. In this example, you would write `mixin("typeof(a) d");`.
Unfortunately, once you start doing stuff with things like __traits(allMembers, ...), you're dealing with strings, and you're pretty much forced to use stringof or fullyQualified name on the type that they go with if you then want to actually do much of anything with those members. So, while your advice is good in general, as far as I can tell, there are cases where it just doesn't work to avoid stringof or fullyQualifiedName.
- Jonathan M Davis
| |||
August 19, 2016 Re: typeof.stringof wrong type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Friday, 19 August 2016 at 18:52:02 UTC, Jonathan M Davis wrote:
> Unfortunately, once you start doing stuff with things like __traits(allMembers, ...), you're dealing with strings
You should immediately go back into symbol land by passing that string into __traits(getMember).
I agree that stringof is almost always a bug, if not ALWAYS a bug, when seen in code generator. There's better ways.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply