Skip to content

Really fix Issue 16478 - Don't allow to!T() in constraint#4922

Merged
schveiguy merged 1 commit intodlang:masterfrom
ntrel:to-empty-args
Nov 25, 2016
Merged

Really fix Issue 16478 - Don't allow to!T() in constraint#4922
schveiguy merged 1 commit intodlang:masterfrom
ntrel:to-empty-args

Conversation

@ntrel
Copy link
Contributor

@ntrel ntrel commented Nov 24, 2016

  • Use specialization to prefer to!S when S is a static array.

(For background, see #4898 (comment))

Ping @schveiguy.

Use specialization to prefer to!S when S is a static array.
@dlang-bot
Copy link
Contributor

Fix Bugzilla Description
16478 Don't allow to!T() in constraint

@schveiguy
Copy link
Member

I don't think this will work, because constraints aren't considered specialization.

int[1] arr;
to!string(arr); // ambiguity error

What you need is something like:

if(Args.length > 1 || (Args.length == 1 && !isStaticArray!(Args[0])))

Alternatively, to can require a parameter like isRawStaticArray did:

auto to(Val, Args...)(Val v, Args args) if(!isStaticArray!Val)
{
    return toImpl!T(v, args);
}

@schveiguy
Copy link
Member

Hm... it does work, but I don't understand why. I'm sure I've had to deal with this not being a specialization. I also can't find the rule that says why this is a specialization. But it seems to compile fine.

@ntrel
Copy link
Contributor Author

ntrel commented Nov 24, 2016

    T to(A...)(A args)
        if (A.length > 0);
    T to(S)(ref S arg)
        if (isStaticArray!S);

I think it works like this. When one argument is supplied to to, A.length is 1, but due to specialization of to(S) not being variadic, to(S) is preferred if its constraint passes. Otherwise, the only option is to(A). So static arrays instantiate to(S), everything else, to(A).

@schveiguy
Copy link
Member

Is that rule outlined in the spec somewhere?

@ntrel
Copy link
Contributor Author

ntrel commented Nov 24, 2016

Not sure. Although the constraints page seems to support this - right at the end (under Overloading based on Constraints) it shows:

void foo(T, int N)()        if (N & 1) { ... } // A
void foo(T : int, int N)()  if (N > 3) { ... } // B
...
foo!(int, 7)();   // picks B, more specialized
foo!(int, 1)();   // picks A, as it fails B's constraint

@schveiguy
Copy link
Member

But that is specialization as I understand it -- a colon with a specification is a specialization. See here: https://dlang.org/spec/template.html#parameters_specialization

I can't find the rule that says that individual type parameters are considered before variadic ones.

@schveiguy
Copy link
Member

Regarding the PR, I think it's fine as long as this rule is correct and understood. I just don't know if the current behavior is what is intended.

@schveiguy
Copy link
Member

Copy link
Member

@schveiguy schveiguy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@schveiguy
Copy link
Member

@CyberShadow why the failure?

@CyberShadow
Copy link
Member

Hrm, the heuristic for the dlang.org makefile's iffy LATEST feature failed. We really should get rid of it.

Pushed a fix and queued PRs for retesting, hopefully should be fixed now. May need a commit to master to seed the cache.

@schveiguy
Copy link
Member

Auto-merge toggled on

@schveiguy schveiguy merged commit bad369c into dlang:master Nov 25, 2016
@schveiguy
Copy link
Member

@CyberShadow thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants