Bug 14756 – cannot deduce function with template constraint
Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2015-07-01T16:33:00Z
Last change time
2015-09-14T02:55:40Z
Assigned to
nobody
Creator
tim.dlang
Comments
Comment #0 by tim.dlang — 2015-07-01T16:33:05Z
The following code compiled with dmd v2.067, but results in an error for dmd v2.068.0-b1:
// copied from std.traits
enum bool isInstanceOf(alias S, T) = is(T == S!Args, Args...);
struct Test(size_t id)
{
static void from(Other)(Other other) if(isInstanceOf!(Test, Other))
{
}
}
void main()
{
Test!(1) test;
Test!(2).from(test);
}
Here is the error message:
test.d(14): Error: template test.Test!2u.Test.from cannot deduce function from argument types !()(Test!1u), candidates are:
test.d(6): test.Test!2u.Test.from(Other)(Other other) if (isInstanceOf!(Test, Other))
If the template constraint uses the is-expression directly, the error goes away.
Comment #1 by k.hara.pg — 2015-07-02T01:46:23Z
(In reply to Tim from comment #0)
This behavior change is an intentional bug fix. See issue 14290.
> enum bool isInstanceOf(alias S, T) = is(T == S!Args, Args...);
>
> struct Test(size_t id)
> {
> static void from(Other)(Other other)
> if (isInstanceOf!(Test, Other))
In here, 'Test' represents an instantiated struct, not a template. By fixing issue 14290, is-expression won't match to the instantiation form S!Args when S is a struct.
> If the template constraint uses the is-expression directly, the error goes
> away.
When you rewrite the condition as follows:
static void from(Other)(Other other)
if (is(Other == Test!Args, Args...))
'Test' is still a struct, but in here, the is-expression can recognize it may also represent the outer template Test(size_t id) because it's accessible through the lexical scope.
To fix the issue, you need to pass explicitly the template 'Test' to the isInstanceOf.
struct Test(size_t id)
{
static void from(Other)(Other other)
if (isInstanceOf!(.Test, Other))
// <-- Use Module Scope Operator (http://dlang.org/module)
{}
}
Comment #2 by k.hara.pg — 2015-09-14T02:55:40Z
*** Issue 15042 has been marked as a duplicate of this issue. ***