Extracting user defined attributes on function parameters

Simen Kjærås simen.kjaras at gmail.com
Fri Apr 17 17:33:23 UTC 2020


On Friday, 17 April 2020 at 16:54:42 UTC, Adam D. Ruppe wrote:
> This part seems fine...
>
>> pragma(msg, ParameterDefaults!f.stringof);
>
> It is this, specifically, that causes the problem. Replace it 
> with:
>
> void main() {
>         import std.stdio;
>         writeln(ParameterDefaults!f.stringof);
> }
>
> and it is fine.
>
> So pragma(msg) is doing something really weird, the bug doesn't 
> appear to be in Phobos per se, I think it is the compiler doing 
> the wrong thing, it seems to me it works inside a function 
> scope but not at module scope......

It's even more fascinating - the issue doesn't occur if 
ParameterDefaults is defined in the same module that it's used 
in, and it works if there's a type with the same name as the UDA. 
Reducing the code as much as I can, I get this:

struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

template ParameterDefaults(func...) {
     import std.traits : FunctionTypeOf;
     static if (is(FunctionTypeOf!(func[0]) PT == __parameters)) {
         enum ParameterDefaults = (PT[0..1] args) @trusted {
             return *&(args[0]);
         }();
     }
}


The above code works, and prints "3". If you move 
ParameterDefaults to a different module, something like this:

-----

import bar;

struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

-----

module bar;

template ParameterDefaults(func...) {
     static if (is(typeof(func[0]) PT == __parameters)) {
         enum ParameterDefaults = (PT[0..1] args) @trusted {
             return *&(args[0]);
         }();
     }
}
-----

Then you get an error message about 'undefined identifier S'. Add 
some kind of S to bar, and you get an error message about S not 
being readable at compile-time or things just work if it is 
readable. It seems the UDA is being looked up in the wrong 
context.

--
   Simen


More information about the Digitalmars-d-learn mailing list