Thread overview
Opaque type (struct) with a static immutable fails to compile without constructor - why?
Mar 04, 2021
frankp
Mar 04, 2021
harakim
Mar 04, 2021
frankp
Mar 04, 2021
Simen Kjærås
Mar 04, 2021
frankp
Mar 04, 2021
frankp
Mar 04, 2021
frankp
Mar 04, 2021
Imperatorn
March 04, 2021
Hi all,

I want to make an opaque type that simply contains an integer with some immutable constants and toString pretty printing. Like this:

struct Foo_t
{
   private long foo;
   alias foo this;
   static immutable long Inf = long.max; //1)

   void toString(...){}
}

On dmd 2.092.1 this fails with:
  1) Error: cannot implicitly convert expression 9223...L of type immutable(long) to Foo_t

I simply want to initialize an immutable long with long.max.
Why the conversion to Foo_t ?

If I add a constructor:
private this(long f)
{
   foo = f;
}

It compiles but according to code coverage this constructor is never called.
What's going on?
March 04, 2021
On Thursday, 4 March 2021 at 13:58:48 UTC, frankp wrote:
> Hi all,
>
> I want to make an opaque type that simply contains an integer with some immutable constants and toString pretty printing. Like this:
>
> struct Foo_t
> {
>    private long foo;
>    alias foo this;
>    static immutable long Inf = long.max; //1)
>
>    void toString(...){}
> }
>
> On dmd 2.092.1 this fails with:
>   1) Error: cannot implicitly convert expression 9223...L of type immutable(long) to Foo_t
>
> I simply want to initialize an immutable long with long.max.
> Why the conversion to Foo_t ?
>
> If I add a constructor:
> private this(long f)
> {
>    foo = f;
> }
>
> It compiles but according to code coverage this constructor is never called.
> What's going on?

This is the text of my program

import std.stdio;

struct Foo_t
{
   private long foo;
   alias foo this;
   static immutable long Inf = long.max; //1)

   void toString(...){ writeln(foo); }
}


void main()
{
	Foo_t sample;
	sample.foo = 100;
	
	sample.toString();
}


This is the results of running the program:

PS C:\Users\someone\source\tests> dmd forum1.d
PS C:\Users\someone\source\tests> ./forum1.exe
100
PS C:\Users\someone\source\tests> dmd --version
DMD32 D Compiler v2.095.1-dirty
Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved written by Walter Bright

So I was not able to reproduce your issue. Is it possible that error is coming from somewhere else?
March 04, 2021
On Thursday, 4 March 2021 at 13:58:48 UTC, frankp wrote:
> Hi all,
>
> I want to make an opaque type that simply contains an integer with some immutable constants and toString pretty printing. Like this:
>
> struct Foo_t
> {
>    private long foo;
>    alias foo this;
>    static immutable long Inf = long.max; //1)
>
>    void toString(...){}
> }
>
> On dmd 2.092.1 this fails with:
>   1) Error: cannot implicitly convert expression 9223...L of type immutable(long) to Foo_t
>
> I simply want to initialize an immutable long with long.max.
> Why the conversion to Foo_t ?
>
> If I add a constructor:
> private this(long f)
> {
>    foo = f;
> }
>
> It compiles but according to code coverage this constructor is never called.
> What's going on?

I tried compiling your code locally on DMD 2.094.1, and had no issues. Again with 2.095.0, no issues. On run.dlang.io, with all dmd compilers from 2.060, and it just plain works.

Now, that's after removing ... from toString. With that present, it fails with some variation of 'Error: undefined identifier '__va_list_tag''.

Most likely, you have shortened your program for clarity, and removed the issue you're experiencing in the process. Can we have another one, with the issue still there?

--
  Simen
March 04, 2021
On Thursday, 4 March 2021 at 14:18:07 UTC, harakim wrote:
>
>> [...]
>
> This is the text of my program
>
> import std.stdio;
>
> struct Foo_t
> {
>    private long foo;
>    alias foo this;
>    static immutable long Inf = long.max; //1)
>
>    void toString(...){ writeln(foo); }
> }
>
>
> void main()
> {
> 	Foo_t sample;
> 	sample.foo = 100;
> 	
> 	sample.toString();
> }
>
>
> This is the results of running the program:
>
> PS C:\Users\someone\source\tests> dmd forum1.d
> PS C:\Users\someone\source\tests> ./forum1.exe
> 100
> PS C:\Users\someone\source\tests> dmd --version
> DMD32 D Compiler v2.095.1-dirty
> Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved written by Walter Bright
>
> So I was not able to reproduce your issue. Is it possible that error is coming from somewhere else?

I wouldn't know, that's why I'm asking here :)
But since it compiles on dmd 2.095.1 I doubt it. I would upgrade the compiler but I fear if I do all sorts of other things are going to break. I'll keep my workaround and attach a todo note.

Thanks for testing.
March 04, 2021
On Thursday, 4 March 2021 at 14:31:23 UTC, Simen Kjærås wrote:
> On Thursday, 4 March 2021 at 13:58:48 UTC, frankp wrote:
>> Hi all,
>>
>> I want to make an opaque type that simply contains an integer with some immutable constants and toString pretty printing. Like this:
>>
>> struct Foo_t
>> {
>>    private long foo;
>>    alias foo this;
>>    static immutable long Inf = long.max; //1)
>>
>>    void toString(...){}
>> }
>>
>> On dmd 2.092.1 this fails with:
>>   1) Error: cannot implicitly convert expression 9223...L of type immutable(long) to Foo_t
>>
>> I simply want to initialize an immutable long with long.max.
>> Why the conversion to Foo_t ?
>>
>> If I add a constructor:
>> private this(long f)
>> {
>>    foo = f;
>> }
>>
>> It compiles but according to code coverage this constructor is never called.
>> What's going on?
>
> I tried compiling your code locally on DMD 2.094.1, and had no issues. Again with 2.095.0, no issues. On run.dlang.io, with all dmd compilers from 2.060, and it just plain works.
>
> Now, that's after removing ... from toString. With that present, it fails with some variation of 'Error: undefined identifier '__va_list_tag''.
>
> Most likely, you have shortened your program for clarity, and removed the issue you're experiencing in the process. Can we have another one, with the issue still there?
>
> --
>   Simen

toString was actually added at a later point. The compiler complained prior to that.
So if I rename the struct to Foo_t in my program it compiles.

However, the compiler complains if the struct is called "cycle_t". That's curious. Is that a reserved name?
I don't import anything by that name. Not to my knowledge at least - I'm strictly using named imports.
March 04, 2021
On Thursday, 4 March 2021 at 14:42:16 UTC, frankp wrote:
> However, the compiler complains if the struct is called "cycle_t". That's curious. Is that a reserved name?
> I don't import anything by that name. Not to my knowledge at least - I'm strictly using named imports.

False alarm. If I remove the constructor from cycle_t the compiler now complains about the same thing in Foo_t or any other name I try.

I give up. This makes no sense. I just accept this is the work of gremlins. I revert to a plain alias and an enum.

Sorry for wasting your time.
March 04, 2021
On Thursday, 4 March 2021 at 14:54:11 UTC, frankp wrote:
> I give up. This makes no sense. I just accept this is the work of gremlins. I revert to a plain alias and an enum.
>
> Sorry for wasting your time.

Not gremlins after all. It was simply a matter of the compiler pointing to the wrong line. Everything makes sense now. Anyways, thanks for your help.
March 04, 2021
On Thursday, 4 March 2021 at 15:19:16 UTC, frankp wrote:
> On Thursday, 4 March 2021 at 14:54:11 UTC, frankp wrote:
>> I give up. This makes no sense. I just accept this is the work of gremlins. I revert to a plain alias and an enum.
>>
>> Sorry for wasting your time.
>
> Not gremlins after all. It was simply a matter of the compiler pointing to the wrong line. Everything makes sense now. Anyways, thanks for your help.

"15 minutes of gremlins" 😉