Thread overview
Different visibility in template for class and struct?
May 11, 2020
Shigeki Karita
May 11, 2020
Shigeki Karita
May 11, 2020
Shigeki Karita
May 11, 2020
Why is local struct visible in this outer template, while local class is not?

https://wandbox.org/permlink/MfsDa68qgaMSIr4a

https://dlang.org/spec/template.html#instantiation_scope

---

enum p(T) = __traits(compiles, new T());

class GlobalC {}
struct GlobalS {}

void main()
{
    class LocalC {}
    static assert(p!GlobalC);
    static assert(!p!LocalC);

    struct LocalS {}
    static assert(p!GlobalS);
    static assert(p!LocalS); // ??
}

May 11, 2020
On 5/11/20 11:11 AM, Shigeki Karita wrote:
> Why is local struct visible in this outer template, while local class is not?
> 
> https://wandbox.org/permlink/MfsDa68qgaMSIr4a
> 
> https://dlang.org/spec/template.html#instantiation_scope
> 
> ---
> 
> enum p(T) = __traits(compiles, new T());
> 
> class GlobalC {}
> struct GlobalS {}
> 
> void main()
> {
>      class LocalC {}
>      static assert(p!GlobalC);
>      static assert(!p!LocalC);
> 
>      struct LocalS {}
>      static assert(p!GlobalS);
>      static assert(p!LocalS); // ??
> }
> 

First, it actually does compile, I think because the compiler recognizes that LocalS is POD (plain old data), without methods, so it doesn't need a context pointer.

e.g.:

auto make(T)() { return new T(); }

...

auto x = make!LocalS; // ok

If you add a method to LocalS, then make!LocalS fails to compile. However, strangely, p!LocalS still returns true, I think that is an error.

-Steve
May 11, 2020
On Monday, 11 May 2020 at 15:29:53 UTC, Steven Schveighoffer wrote:
> On 5/11/20 11:11 AM, Shigeki Karita wrote:
>> [...]
>
> First, it actually does compile, I think because the compiler recognizes that LocalS is POD (plain old data), without methods, so it doesn't need a context pointer.
>
> e.g.:
>
> auto make(T)() { return new T(); }
>
> ...
>
> auto x = make!LocalS; // ok
>
> If you add a method to LocalS, then make!LocalS fails to compile. However, strangely, p!LocalS still returns true, I think that is an error.
>
> -Steve

Thanks for your answer. Now I understand that POD matters here.

When I add a dtor: `struct LocalS { ~this() {} }`, the `p!LocalS` got false.
May 11, 2020
On 5/11/20 11:40 AM, Shigeki Karita wrote:
> On Monday, 11 May 2020 at 15:29:53 UTC, Steven Schveighoffer wrote:
>> On 5/11/20 11:11 AM, Shigeki Karita wrote:
>>> [...]
>>
>> First, it actually does compile, I think because the compiler recognizes that LocalS is POD (plain old data), without methods, so it doesn't need a context pointer.
>>
>> e.g.:
>>
>> auto make(T)() { return new T(); }
>>
>> ...
>>
>> auto x = make!LocalS; // ok
>>
>> If you add a method to LocalS, then make!LocalS fails to compile. However, strangely, p!LocalS still returns true, I think that is an error.
>>
> 
> Thanks for your answer. Now I understand that POD matters here.
> 
> When I add a dtor: `struct LocalS { ~this() {} }`, the `p!LocalS` got false.

There is still a bug though. if p!T returns true, but make!T doesn't compile, then something is inconsistent.

-Steve
May 11, 2020
On Monday, 11 May 2020 at 16:10:36 UTC, Steven Schveighoffer wrote:
> On 5/11/20 11:40 AM, Shigeki Karita wrote:
>> On Monday, 11 May 2020 at 15:29:53 UTC, Steven Schveighoffer wrote:
>>>[...]
>> 
>> Thanks for your answer. Now I understand that POD matters here.
>> 
>> When I add a dtor: `struct LocalS { ~this() {} }`, the `p!LocalS` got false.
>
> There is still a bug though. if p!T returns true, but make!T doesn't compile, then something is inconsistent.
>
> -Steve

I agree. This should be a bug https://wandbox.org/permlink/5YoKKt8xjdexzJHp