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