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

Reply via email to