D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7686 - template argument ignored with specialization for dependent parameter
Summary: template argument ignored with specialization for dependent parameter
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-11 09:58 UTC by Martin Nowak
Modified: 2021-03-16 10:23 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Martin Nowak 2012-03-11 09:58:11 UTC
cat > bug.d << CODE
struct Pair(T1, T2) {}

template foo(T : Pair!(T, U), U)
{
    pragma(msg, "foo ", T, U);
}

template bar(T : Pair!(T, U), U:int)
{
    pragma(msg, "bar ", T, U);
}

static assert(!__traits(compiles, foo!(Pair!(double, short), int))); // OK
static assert(!__traits(compiles, bar!(Pair!(double, short), int))); // fails
CODE

dmd -c bug

--------

For bar the argument to U is ignored and U is deduced from Pair.
Comment 1 Martin Nowak 2012-03-11 11:48:11 UTC
cat > bug.d << CODE
struct Pair(T1, T2) {}

template foo(T : Pair!(T, U), U)
{
    enum val = 0;
}

template foo(T : Pair!(T, U), U:int)
{
    enum val = 1;
}

static assert(foo!(Pair!(int, int)).val == 1);   // FAIL - matches both
static assert(foo!(Pair!(int, short)).val == 1); // FAIL - matches the first
static assert(foo!(Pair!(int, float)).val == 0); // OK   - matches the first
CODE

dmd -c bug

--------

This also behaves incorrect for specialized overloads.
Comment 2 RazvanN 2021-03-16 10:23:28 UTC
The code example in [1] now compiles successfully, as it should. The code example in [2] fails the first 2 asserts. That is the correct behavior IMHO. The first and second Pair instantiations match both overloads and the third one matches a single template (the one that is not specialized on U). What else could be the correct behavior?

For example, in [1], both:

static assert(__traits(compiles, foo!(Pair!(double, short), short)));
static assert(__traits(compiles, bar!(Pair!(double, short), short)));

and

static assert(__traits(compiles, foo!(Pair!(double, int), int)));
static assert(__traits(compiles, bar!(Pair!(double, int), int)));

compile successfully.

Closing as WORKSFORME. Please reopen if I am missing something. 

[1] https://issues.dlang.org/show_bug.cgi?id=7686#c0
[2] https://issues.dlang.org/show_bug.cgi?id=7686#c1