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