Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-07 Thread Paul Backus via Digitalmars-d-learn
On 4/7/19 1:30 AM, Nicholas Wilson wrote:
> On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote:
>> Error: template instance `Reflect!(type)` cannot use local `type` as
>> parameter to non-global template `Reflect(Ts...)()`
>>
>> mixin(`import `~moduleName!(T)~`;`);   
>> mixin(`alias X = T.`~name~`;`);   
>> super.Reflect!(X);
>>
>> I realize X is local but I'm trying to figure out why it can't be
>> passed to a "non-global" template.
> 
> See
> https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
> 
> 
> TL;DR
> 
> At global scope
> alias Identity(alias X) = X;
> 
> then where the error is issued from use `Identity!(type)` instead of type.

This template is actually in Phobos now, as `std.meta.Alias`.


Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-07 Thread Alex via Digitalmars-d-learn

On Sunday, 7 April 2019 at 05:36:27 UTC, Vladimir Panteleev wrote:

On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote:
Error: template instance `Reflect!(type)` cannot use local 
`type` as parameter to non-global template `Reflect(Ts...)()`


mixin(`import `~moduleName!(T)~`;`);
mixin(`alias X = T.`~name~`;`); 
super.Reflect!(X);

I realize X is local but I'm trying to figure out why it can't 
be passed to a "non-global" template.


- In DMD, objects may have at most one scope (which can be a 
class, struct, or stack frame).


- Instantiating a template with a scoped object makes the 
template have the same scope as the object.


- If a template is already scoped (non-global), then it thus 
cannot have a second scope. Hence the error.


IIRC there is an experimental pull request which removes this 
limitation.


Workarounds:

- Make either the template or the argument global (non-scoped)

- Instead of passing the object as a template parameter, pass 
it as a runtime parameter with a type encapsulating the object. 
Each runtime parameter may be scoped, thus bypassing the 
limitation. I'm not sure this applies to your use case, if the 
Reflect template needs to perform compile-time introspection on 
the parameter.


- If you just need to pass the type, typeof(X) should work of 
course.


Ok, When I use typeof(X) the first instance works but then 
other's end up with junk.


This is what I get when I construct the field inside the base 
class


Fields = [
Id = type
TypeName = type
FullName = mModel.cDerived!(int).type
ModuleName = mModel
MangledName = _D6mModel__T8cDerivedTiZQm4typeCQBe5cType
Protection = public
Body =
IsZeroInit = false
IsTemplate = false
Uses = []
Attributes = []
DType = field
,
Id = testField1
TypeName = testField1
FullName = mModel.cDerived!(int).testField1
ModuleName = mModel
MangledName = _D6mModel__T8cDerivedTiZQm10testField1i
Protection = private
Body =
IsZeroInit = false
IsTemplate = false
Uses = []
Attributes = [sAttributeReflection("XXXRRERES", "string")]
DType = field
,
Id = testField2
TypeName = testField2
FullName = mModel.cDerived!(int).testField2
ModuleName = mModel
MangledName = _D6mModel__T8cDerivedTiZQm10testField2d
Protection = public
Body =
IsZeroInit = false
IsTemplate = false
Uses = []
Attributes = [sAttributeReflection("XXXRRERES4", "string")]
DType = field

and this is when I construct it then pass it using typeof

mixin(`import `~moduleName!(T)~`;`);
mixin(`alias TT = `~(T).stringof~`.`~name~`;`); 
super.Reflect!(typeof(TT));

(the code above is what the base class does, It's essentially 
moved in to the derived class here)


Fields = [
Id = cType
TypeName = cType
FullName = mModel.cType
ModuleName = mModel
MangledName = C6mModel5cType
Protection = public
Body =
IsZeroInit = true
IsTemplate = false
Uses = []
Attributes = []
DType = field
,
Id =
TypeName = int
FullName = int
ModuleName =
MangledName = i
Protection =
Body =
IsZeroInit = true
IsTemplate = false
Uses = []
Attributes = []
DType = field
,
Id =
TypeName = double
FullName = double
ModuleName =
MangledName = d
Protection =
Body =
IsZeroInit = false
IsTemplate = false
Uses = []
Attributes = []
DType = field



one can see something odd is going on though
FullName = mModel.cDerived!(int).type

vs

FullName = mModel.cType

as if the aggregate is being lost.





Here is the code:

			// We let the base class do all work, but must pass in type 
and name separately

//super.Reflect!(T, name);

mixin(`import `~moduleName!(T)~`;`);
mixin(`alias TT = `~(T).stringof~`.`~name~`;`); 

   

Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-06 Thread Vladimir Panteleev via Digitalmars-d-learn

On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote:
Error: template instance `Reflect!(type)` cannot use local 
`type` as parameter to non-global template `Reflect(Ts...)()`


mixin(`import `~moduleName!(T)~`;`);
mixin(`alias X = T.`~name~`;`); 
super.Reflect!(X);

I realize X is local but I'm trying to figure out why it can't 
be passed to a "non-global" template.


- In DMD, objects may have at most one scope (which can be a 
class, struct, or stack frame).


- Instantiating a template with a scoped object makes the 
template have the same scope as the object.


- If a template is already scoped (non-global), then it thus 
cannot have a second scope. Hence the error.


IIRC there is an experimental pull request which removes this 
limitation.


Workarounds:

- Make either the template or the argument global (non-scoped)

- Instead of passing the object as a template parameter, pass it 
as a runtime parameter with a type encapsulating the object. Each 
runtime parameter may be scoped, thus bypassing the limitation. 
I'm not sure this applies to your use case, if the Reflect 
template needs to perform compile-time introspection on the 
parameter.


- If you just need to pass the type, typeof(X) should work of 
course.




Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-06 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote:
Error: template instance `Reflect!(type)` cannot use local 
`type` as parameter to non-global template `Reflect(Ts...)()`


mixin(`import `~moduleName!(T)~`;`);
mixin(`alias X = T.`~name~`;`); 
super.Reflect!(X);

I realize X is local but I'm trying to figure out why it can't 
be passed to a "non-global" template.


See 
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/


TL;DR

At global scope
alias Identity(alias X) = X;

then where the error is issued from use `Identity!(type)` instead 
of type.


Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-06 Thread Alex via Digitalmars-d-learn
Error: template instance `Reflect!(type)` cannot use local `type` 
as parameter to non-global template `Reflect(Ts...)()`


mixin(`import `~moduleName!(T)~`;`);
mixin(`alias X = T.`~name~`;`); 
super.Reflect!(X);

I realize X is local but I'm trying to figure out why it can't be 
passed to a "non-global" template.