www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Opaque type (struct) with a static immutable fails to compile without

reply frankp <frankp_12983 gmail.com> writes:
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?
Mar 04
next sibling parent reply harakim <harakim gmail.com> writes:
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?
Mar 04
parent frankp <frankp_12983 gmail.com> writes:
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.
Mar 04
prev sibling parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
Mar 04
parent reply frankp <frankp_12983 gmail.com> writes:
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.
Mar 04
parent reply frankp <frankp_12983 gmail.com> writes:
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.
Mar 04
parent reply frankp <frankp_12983 gmail.com> writes:
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.
Mar 04
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
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" 😉
Mar 04