Bug 20744 – Using __parameters result in function definition causes wrong lookup
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-04-17T15:09:35Z
Last change time
2020-05-20T05:45:40Z
Keywords
pull
Assigned to
No Owner
Creator
Jean-Louis Leroy
Comments
Comment #0 by jl — 2020-04-17T15:09:35Z
Compiling this:
import std.traits;
struct attr;
void f(@attr int);
pragma(msg, ParameterDefaults!f.stringof);
Causes:
dmd -c bug.d
bug.d(4): Error: undefined identifier `attr`, did you mean variable `ptr`?
/home/jll/dlang/dmd-2.090.1/linux/bin64/../../src/phobos/std/traits.d(1526): Error: template instance `std.traits.ParameterDefaults!(f).Get!0LU` error instantiating
/home/jll/dlang/dmd-2.090.1/linux/bin64/../../src/phobos/std/traits.d(1529): instantiated from here: `Impl!0LU`
bug.d(6): instantiated from here: `ParameterDefaults!(f)`
bug.d(6): while evaluating `pragma(msg, ParameterDefaults!(f).stringof)`
Comment #1 by destructionator — 2020-04-17T16:58:10Z
this works though:
import std.traits;
struct attr;
void f(@attr int g = 4);
void main() {
pragma(msg, ParameterDefaults!f.stringof);
}
But this does not:
struct S{
pragma(msg, ParameterDefaults!f.stringof);
}
Looks like if the ParameterDefaults appears in function scope, it works, but otherwise it fails.
Order doesn't seem to matter, if I eval the pragma in a function first then in a struct later it still errors in the struct.
I'm gonna change the component here to dmd since I think it is the compiler's fault rather than the library's
Comment #2 by simen.kjaras — 2020-04-17T17:41:16Z
Definitely a compiler issue. It seems UDAs are being looked up in the scope where the result of `is(Func PT == __parameters)` is being used. Here's a very reduced example:
module foo;
import bar;
struct S {}
void f(@S int = 3);
pragma(msg, ParameterDefaults!f.stringof);
-----
module bar;
//enum S = 3; // Uncomment to make things compile
template ParameterDefaults(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
enum ParameterDefaults = (PT[0..1] args) @trusted {
return *&(args[0]);
}();
}
}
Comment #3 by simen.kjaras — 2020-04-18T10:00:22Z
Further reduction (one module, yay!):
struct A {
struct S {}
void f(@S int = 3);
pragma(msg, Issue20744!f);
}
template Issue20744(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
alias Issue20744 = (PT args) {};
}
}
Moving the template to the same scope as S makes things work.
Note that accessing UDAs inside the template is not a problem, nor is using those UDAs in most ways. The only thing I've found to cause issues is defining a function with the result of __parameters.
Comment #4 by dlang-bot — 2020-05-19T12:41:49Z
@BorisCarvajal created dlang/dmd pull request #11162 "Fix Issue 20744 - Using __parameters result in function definition ca…" fixing this issue:
- Fix Issue 20744 - Using __parameters result in function definition causes wrong lookup
https://github.com/dlang/dmd/pull/11162
Comment #5 by dlang-bot — 2020-05-20T05:45:40Z
dlang/dmd pull request #11162 "Fix Issue 20744 - Using __parameters result in function definition ca…" was merged into stable:
- 3719b636ff1357bf2e3e449b27ace16c5d53418d by Boris Carvajal:
Fix Issue 20744 - Using __parameters result in function definition causes wrong lookup
https://github.com/dlang/dmd/pull/11162