[Issue 1528] [tdpl] overloading template and non-template functions

2014-05-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=1528

--- Comment #40 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/33d25844140a0b7785a480cf77f603b40154e7ff
[Refactoring] Remove unnecessary workaround for issue 1528

--


[Issue 1528] [tdpl] overloading template and non-template functions

2013-10-23 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Kenji Hara k.hara...@gmail.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-07-20 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Jonathan M Davis jmdavisp...@gmx.com changed:

   What|Removed |Added

 CC||mitch.haye...@gmail.com


--- Comment #39 from Jonathan M Davis jmdavisp...@gmx.com 2013-07-20 21:58:59 
PDT ---
*** Issue 4749 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-06-28 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #37 from github-bugzi...@puremagic.com 2013-06-28 12:17:44 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/edd0f6fbeeff70eccd7d2e15429b20418360eca5
fix Issue 1528 - [tdpl] overloading template and non-template functions

- Improve `resolveFuncCall` for integrated function call resolution.
  All of error reporting is done in here.

- Remove `overloadResolve` and `deduceFuncitonTemplate`
  The works was in `overloadResolve` are moved to `resolveFuncCall`,
  and things was in `deduceFuncitonTemplate` are divided to
  `templateResolve` and `resolveFuncCall`.

- Change the name from `overloadResolveX` to `functionResolve`
  It is paired with `templateResolve`.

- Decide 'most specialized' function based on the two `MATCH` values derived
from `tiargs` and `fargs`.
  With non template functions, `last matching level for tiargs` is treated as
`MATCHexact`.


The bug that is fixed at the same time:
fix Issue 9596 - Ambiguous match is incorrectly hidden by additional lesser
match

  The change in test/runnable/template9.d is related.

https://github.com/D-Programming-Language/dmd/commit/fba440cc7dc1210b0450f8b01d18661ebbd0da55
Merge pull request #1409 from 9rnsr/fix1528

Issue 1528 - [tdpl] overloading template and non-template functions

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-06-28 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


bearophile_h...@eml.cc changed:

   What|Removed |Added

 CC||bearophile_h...@eml.cc


--- Comment #38 from bearophile_h...@eml.cc 2013-06-28 14:16:04 PDT ---
(In reply to comment #37)
 Commits pushed to master at 

This is a significant improvement.

I am testing this feature a little. This is code reduced from your Comment 10:


int f1(int a, double=10) { return 1; }
int f1(int a, string=) { return 2; }
int f2(T:int)(T b, double=10) { return 1; }
int f2(T:int)(T b, string=) { return 2; }
void main() {
f1(1);
f2(1L);
}


It gives the errors:

test.d(6): Error: called with argument types:
(int)
matches both:
test.d(1): test.f1(int a, double _param_1 = 10.)
and:
test.d(2): test.f1(int a, string _param_1 = )
test.d(7): Error: template test.f2 does not match any function template
declaration. Candidates are:
test.d(3):test.f2(T : int)(T b, double = 10)
test.d(4):test.f2(T : int)(T b, string = )
test.d(7): Error: template test.f2(T : int)(T b, double = 10) cannot deduce
template function from argument types !()(long)


For the error at line 6 it nicely indents the lines test.d(1) and test.d(2).

While for the error at line 7 it doesn't indent the lines test.d(3) and
test.d(4).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-04-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #33 from Andrei Alexandrescu and...@erdani.com 2013-04-07 
07:33:07 PDT ---
Great thread. Sorry I'm late to it! Let me make an appeal to simplicity - even
if we come up with a very meaningful and consistent set of overloading rules,
we lose if they are complicated. Simplicity is very important for figuring out
what function will be called in a context.

In that spirit I'd like to propose a basic strategy as follows:

1. Define a SIMPLE partial ordering relation = between functions called at
least as specialized (and correspondingly a strict version  meaning more
specialized).

2. Whenever two or more functions match a call, there is a winner only if it
is more specialized than all other candidates. (Not all candidates must be
partially ordered among themselves, but the winner must be more specialized
than all others.) Otherwise, there is ambiguity.

Now for the simple partial ordering relation: consider a call to a function
fun(args) with two overloads fun1 and fun2 that would accept the arguments,
i.e. fun1(args) and fun2(args) would both compile in isolation.

To decide whether fun1 and fun2 are partially ordered, we look at the sets of
accepted arguments. If fun2 accepts any argument fun1 would accept, we write
fun1 = fun2 and we say fun1 is at least as specialized as fun2 or fun2 is
not more specialized than fun1.

Now, if fun1 = fun2 and fun2 = fun1 then the two are as specialized so a
decision cannot be made between the two. If only one of the relations applies,
then one of them is strictly more specialized and it is preferred in an
overloaded call. If neither relation applies, the functions are unordered so
again a decision cannot be made.

On the examples given by Kenji:

int f1(int a, double=10) { return 1; }
int f1(int a, string=) { return 2; }

These functions are not ordered because e.g. f1(2, 3.4) would not be accepted
by the second overload and f1(2, hello) would not be accepted. So the call
f1(5) is ambiguous.

int f2(T:int)(T b, double=10) { return 1; }
int f2(T:int)(T b, string=) { return 2; }

Same here, these overloads are not ordered.

// vs deduced parameter
int f3(int a) { return 1; }
int f3(T)(T b) { return 2; }

Here the second overload accepts f3(hello) so the first overload is more
specialized. It will be preferred even in calls with an implicit conversion,
e.g. f3(cast(short) 42). THIS IS A DEPARTURE FROM C++'S RULES.

// vs specialized parameter
int f4(int a) { return 1; }
int f4(T:int)(T b) { return 2; }

These two functions are in the same equivalence classes because they accept the
same argument sets: f4_1 = f4_2 and f4_2 = f4_1. So any call that would match
these two would be ambiguous. 

// vs deduced parameter + template constraint (1)
int f5(int a) { return 1; }
int f5(T)(T b) if (is(T == int)) { return 2; }

The constraint is evaluated first and then disappears leaving two functions.
Of these, the non-template is more specialized.

// vs deduced parameter + template constraint (2)
int f6(int a) { return 1; }
int f6(T)(T b) if (is(T : int)) { return 2; }

Same here. Given that the constraints are arbitrary Boolean expressions, we
can't make good estimates on what sets of arguments they'll match.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-04-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #34 from Kenji Hara k.hara...@gmail.com 2013-04-07 18:44:04 PDT 
---
(In reply to comment #33)
[snip]

That's the rule described in TDPL. I can completely agree with you.
I believe that my patch implements it enough.



I'd like to add one note for your better understand.

 // vs specialized parameter
 int f4(int a) { return 1; }
 int f4(T:int)(T b) { return 2; }
 
 These two functions are in the same equivalence classes because they accept
 the same argument sets: f4_1 = f4_2 and f4_2 = f4_1. So any call that would
 match these two would be ambiguous. 

That's true if and only if one int argument is given. In D, the template
specialized parameter (T:int) means T should exactly matches to int.

  int fx(T:int)(T b) { return 2; }
  void main() { fx(1L); }

  test.d(2): Error: template test.fx does not match any function template
declaration. Candidates are:
  test.d(1):test.fx(T : int)(T b)
  test.d(2): Error: template test.fx(T : int)(T b) cannot deduce template
function from argument types !()(long)

So, f4 would match to non-template version if a non-int argument is given.

  assert(f4(1L) == 1);   // not ambiguous

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-04-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #35 from Andrei Alexandrescu and...@erdani.com 2013-04-07 
19:13:35 PDT ---
@Kenji: My bad, I forgot T:int means exact match, thought it's match with
conversion. (BTW that's a mistake: The syntax in classes suggests that class
T:U means subtyping. But it's too late to fix that now.)

So, you're right. Thanks for the clarification! Have you linked a pull request
yet?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-04-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Kenji Hara k.hara...@gmail.com changed:

   What|Removed |Added

   Keywords||pull


--- Comment #36 from Kenji Hara k.hara...@gmail.com 2013-04-07 19:28:23 PDT 
---
(In reply to comment #35)
 @Kenji: My bad, I forgot T:int means exact match, thought it's match with
 conversion. (BTW that's a mistake: The syntax in classes suggests that class
 T:U means subtyping. But it's too late to fix that now.)
 
 So, you're right. Thanks for the clarification! Have you linked a pull request
 yet?

Oh, I forgot to add 'pull' tag. Will do.

URL is already in comment #9, but I re-post it here.
https://github.com/D-Programming-Language/dmd/pull/1409

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-15 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #30 from Kenji Hara k.hara...@gmail.com 2013-03-15 07:27:23 PDT 
---
(In reply to comment #29)
 (In reply to comment #28)
  (In reply to comment #26)
  
  It's not about the polysemous literals.
  What's irritating me is that a function call with conversion
  is preferred over a function template instantiation with
  exact arguments.
  
  int f3(long) { return 1; }
  int f3(T)(T) { return 2; }
  
  int v = 2;
  f3(v);
  
  MATCHexact / MATCHconvert vs.
  MATCHconvert / MATCHexact
 
 IMO the second should be MATCHexact / MATCHexact.

No. type parameter deduction is less specialized than matching to explicitly
specialized type parameter.

void foo(T)(T) {}  // generic version
void foo(T:int)(T) {}  // specialized to int

foo(1);  // calls T:int version

That is why f3(v) makes MATCHconvert / MATCHexact with template version.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-15 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #31 from timon.g...@gmx.ch 2013-03-15 15:52:59 PDT ---
(In reply to comment #30)
 ...
 Parameter deduction is less specialized than matching to explicitly
 specialized type parameter.
 ...

It's not less specialized than a normal function call without type parameters.
A type parameter should match a type argument exactly.

Specialization mustn't be confused with the matching level -- it should be
checked in a second step, as is done for functions.

Why?: Specialization is a partial order, while the matching levels form a full
order. There is no way to correctly implement specialization only by abusing
matching levels.

(At the very least, the logic for template specialization should not interfere
with template vs. function overloading!)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-15 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #32 from Kenji Hara k.hara...@gmail.com 2013-03-15 16:51:36 PDT 
---
(In reply to comment #31)
 (In reply to comment #30)
  ...
  Parameter deduction is less specialized than matching to explicitly
  specialized type parameter.
  ...
 
 It's not less specialized than a normal function call without type parameters.
 A type parameter should match a type argument exactly.
 
 Specialization mustn't be confused with the matching level -- it should be
 checked in a second step, as is done for functions.
 
 Why?: Specialization is a partial order, while the matching levels form a full
 order. There is no way to correctly implement specialization only by abusing
 matching levels.
 
 (At the very least, the logic for template specialization should not interfere
 with template vs. function overloading!)

I talked the expected behavior by using the words used in dmd implementation.
Yes, MATCH(exact|const|convert|nomatch) might not be the best word to talk
language specification. But it is not a true problem.

Essentially the thing I talking is:

void foo(int) {}   // 1
void foo(T:int)(T) {}  // 2
void foo(T)(T) {}  // 3
foo(1);

Non template function (1) is specialized _as same as_ explicitly specialized
template function (2). Then, normally deduced template function is less
specialized than (1) and (2).

My patch represents the specialization order for IFTI by the pair of MATCH
value. And, (3) is represented by MATCHconvert / MATCHexact internally.

Do not confuse internal representation and expected language
specification/behavior.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-14 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #24 from Martin Nowak c...@dawg.eu 2013-03-14 08:46:43 PDT ---
(In reply to comment #23)

I think this rule is problematic for the function vs. deduced parameter case.

// vs deduced parameter
int f3(int a) { return 1; }
int f3(T)(T b) { return 2; }
f3(1L);

With first overload version,
Phase 1: normal function is treated as having empty template parameter list, so
 matching is always exact  == MATCHexact
Phase 2: int - 1L == MATCHconvert == MATCHconvert

With second overload version,
Phase 1: T - typeof(1L) = long== MATCHconvert
Phase 2: T - 1L == MATCHexact == MATCHexact

- the current implementation in the pull request chooses
  the function whereas comment #13 and #16 suggest to go
  with the function template

https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L216
https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L279

- C++ chooses the function template

- For me it's counterintuitive to call with conversion when an exact
  match can be instantiated. Even an ambiguous error seems more reasonable to
me.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-14 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #25 from Martin Nowak c...@dawg.eu 2013-03-14 08:52:21 PDT ---
I find the C++ rule pretty plausible.

 In most cases a function template behaves just like a normal function when
 considering overload resolution. The template argument deduction is
 applied, if it succeeds, the function is added to the candidates set. Such
 a function is handled like any other function, except when two viable
 functions are equally good, the non-template one is selected. In case both
 are a specialisation of a function template, partial ordering rules are
 applied. The partial ordering rules are out of the scope of this article.

http://accu.org/index.php/journals/268#d0e340

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-14 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #26 from Kenji Hara k.hara...@gmail.com 2013-03-14 09:01:49 PDT 
---
(In reply to comment #24)
 (In reply to comment #23)
 
 I think this rule is problematic for the function vs. deduced parameter case.
 
 // vs deduced parameter
 int f3(int a) { return 1; }
 int f3(T)(T b) { return 2; }
 f3(1L);
 
 With first overload version,
 Phase 1: normal function is treated as having empty template parameter list, 
 so
  matching is always exact  == MATCHexact
 Phase 2: int - 1L == MATCHconvert == MATCHconvert
 
 With second overload version,
 Phase 1: T - typeof(1L) = long== MATCHconvert
 Phase 2: T - 1L == MATCHexact == MATCHexact
 
 - the current implementation in the pull request chooses
   the function whereas comment #13 and #16 suggest to go
   with the function template
 
 https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L216
 https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L279
 
 - C++ chooses the function template
 
 - For me it's counterintuitive to call with conversion when an exact
   match can be instantiated. Even an ambiguous error seems more reasonable to
 me.

Right now I think that was little bad example.

Ques. Why f3(1L) chooses non-template version?

Short Ans. Because the given argument 1L is a literal.

Long Ans.
In D, literals works as like polysemous value. 1L is implicitly convertible to
int by Value Range Propagation, so it matchs with MATCHconvert.

If you give a runtime long value to f3:

long n;
f3(n);

With first overload version,
Phase 1: normal function is treated as having empty template parameter list, so
 matching is always exact  == MATCHexact
Phase 2: int - n == MATCHnomatch(changed!!)

With second overload version,
Phase 1: T - typeof(1L) = long== MATCHconvert
Phase 2: T - 1L == MATCHexact == MATCHexact

So it will choose template version. How about?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-14 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #27 from timon.g...@gmx.ch 2013-03-14 15:34:50 PDT ---
(In reply to comment #25)
 I find the C++ rule pretty plausible.
 
  In most cases a function template behaves just like a normal function when
  considering overload resolution. The template argument deduction is
  applied, if it succeeds, the function is added to the candidates set. Such
  a function is handled like any other function, except when two viable
  functions are equally good, the non-template one is selected. In case both
  are a specialisation of a function template, partial ordering rules are
  applied. The partial ordering rules are out of the scope of this article.
 
 http://accu.org/index.php/journals/268#d0e340

C++ does not have template value parameters. The C++ behaviour is approximated
closely when IFTI type parameter deduction is treated as exact match. (There is
no reason to do anything else, a type is required, and a type is given.)

However, it is not too clear that there must be one matching level for the
template and one for the function.

@Kenji, why do you think this is required? Why does one matching level for
everything not suffice?

Eg, I think the following code should not compile and show an ambiguity error.

void foo(double a)(int b){ }
void foo(int a)(double b){ }

void main(){
foo!1(1);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-14 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #28 from Martin Nowak c...@dawg.eu 2013-03-14 15:55:08 PDT ---
(In reply to comment #26)

It's not about the polysemous literals.
What's irritating me is that a function call with conversion
is preferred over a function template instantiation with
exact arguments.

int f3(long) { return 1; }
int f3(T)(T) { return 2; }

int v = 2;
f3(v);

MATCHexact / MATCHconvert vs.
MATCHconvert / MATCHexact

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Martin Nowak c...@dawg.eu changed:

   What|Removed |Added

 CC||c...@dawg.eu


--- Comment #17 from Martin Nowak c...@dawg.eu 2013-03-01 02:19:23 PST ---
 template type parameter deduction without specialization always be 
 MATCHconvert

AFAIK this is a kludgy implementation detail to make specialization work. The
last time we worked on that we concluded (with Daniel Murphy?) that there
should be an additional level between convert and exact. I don't remember the
details right now, but I'll try to find the relevant discussion.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #18 from timon.g...@gmx.ch 2013-03-01 03:15:40 PST ---
(In reply to comment #17)
  template type parameter deduction without specialization always be 
  MATCHconvert
 
 AFAIK this is a kludgy implementation detail

It is a bug.

 to make specialization work.

Why wouldn't they work otherwise?

 The
 last time we worked on that we concluded (with Daniel Murphy?) that there
 should be an additional level between convert and exact. I don't remember the
 details right now, but I'll try to find the relevant discussion.

There already is a level between them (conversion to const.)

Anyway, I do not see why another level would be required, or even helpful in
any way.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #19 from Kenji Hara k.hara...@gmail.com 2013-03-01 03:26:51 PST 
---
(In reply to comment #17)
  template type parameter deduction without specialization always be 
  MATCHconvert
 
 AFAIK this is a kludgy implementation detail to make specialization work. The
 last time we worked on that we concluded (with Daniel Murphy?) that there
 should be an additional level between convert and exact. I don't remember the
 details right now, but I'll try to find the relevant discussion.

Are you saying about MATCHdeduced? I had seen the Daniel Murphy's pull request
somewhere, but it is completely unnecessary.

In IFTI, the match level for template arguments and for function arguments are
distinguished. The former is prior than the latter, so there is 3 * 3 + 1 match
level in IFTI.

  For tiargs: exact or const or convert  (3)
  For funargs: exact or const or convert  (* 3)
  noatch (+ 1)

During implementation, I found that the two matching levels had not be
separated correctly (the bug was in
TemplateDeclaration::deduceFunctionTemplateMatch). After fixing the bug, I can
believe that MATCHdeduced is not need anymore.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #20 from timon.g...@gmx.ch 2013-03-01 03:40:36 PST ---
(In reply to comment #19)
 (In reply to comment #17)
 ...
 
 In IFTI, the match level for template arguments and for function arguments are
 distinguished. The former is prior than the latter, so there is 3 * 3 + 1 
 match
 level in IFTI.
 
   For tiargs: exact or const or convert  (3)
   For funargs: exact or const or convert  (* 3)
   noatch (+ 1)
 ...

It can be seen that way. They are ordered from worst to best like this:

no match
ifti convert
function convert
ifti const
function const
ifti exact
function exact

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #21 from Kenji Hara k.hara...@gmail.com 2013-03-01 03:55:37 PST 
---
(In reply to comment #20)
 (In reply to comment #19)
  (In reply to comment #17)
  ...
  
  In IFTI, the match level for template arguments and for function arguments 
  are
  distinguished. The former is prior than the latter, so there is 3 * 3 + 1 
  match
  level in IFTI.
  
For tiargs: exact or const or convert  (3)
For funargs: exact or const or convert  (* 3)
noatch (+ 1)
  ...
 
 It can be seen that way. They are ordered from worst to best like this:

More precisely:

MATCHnomatch
tiargs:MATCHconvert / funarg:MATCHconvert
tiargs:MATCHconvert / funarg:MATCHconst
tiargs:MATCHconvert / funarg:MATCHexact
tiargs:MATCHconst   / funarg:MATCHconvert
tiargs:MATCHconst   / funarg:MATCHconst
tiargs:MATCHconst   / funarg:MATCHexact
tiargs:MATCHexact   / funarg:MATCHconvert
tiargs:MATCHexact   / funarg:MATCHconst
tiargs:MATCHexact   / funarg:MATCHexact

Additionally, when comparing normal function and template function matching,
tiargs MATCH level is treated as equal to funargs level.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #22 from timon.g...@gmx.ch 2013-03-01 11:48:00 PST ---
(In reply to comment #21)
 (In reply to comment #20)
  (In reply to comment #19)
   (In reply to comment #17)
   ...
   
   In IFTI, the match level for template arguments and for function 
   arguments are
   distinguished. The former is prior than the latter, so there is 3 * 3 + 1 
   match
   level in IFTI.
   
 For tiargs: exact or const or convert  (3)
 For funargs: exact or const or convert  (* 3)
 noatch (+ 1)
   ...
  
  It can be seen that way. They are ordered from worst to best like this:
 
 More precisely:
 
 MATCHnomatch
 tiargs:MATCHconvert / funarg:MATCHconvert
 tiargs:MATCHconvert / funarg:MATCHconst
 tiargs:MATCHconvert / funarg:MATCHexact
 tiargs:MATCHconst   / funarg:MATCHconvert
 tiargs:MATCHconst   / funarg:MATCHconst
 tiargs:MATCHconst   / funarg:MATCHexact
 tiargs:MATCHexact   / funarg:MATCHconvert
 tiargs:MATCHexact   / funarg:MATCHconst
 tiargs:MATCHexact   / funarg:MATCHexact
 
 Additionally, when comparing normal function and template function matching,
 tiargs MATCH level is treated as equal to funargs level.

Ah, now I see what you mean. You are matching foo!tiargs(funargs).

I was talking about resolving template vs. non-template overloads in the
foo(funargs) setting.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-03-01 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #23 from Kenji Hara k.hara...@gmail.com 2013-03-01 18:17:08 PST 
---
(In reply to comment #22)
 Ah, now I see what you mean. You are matching foo!tiargs(funargs).
 
 I was talking about resolving template vs. non-template overloads in the
 foo(funargs) setting.

I'm talking about both. You can think type parameters deduction and function
arguments matching separately. For example:

void foo(T)(T) {}
void foo(T:int)(T) {}

With first overload version,
Phase 1: T is deduced to int. == MATCHconvert.
Phase 2: 1 matches T (==already deduced to int). == MATCHexact.

With second overload version,
Phase 1: T is deduced to int and is specialized to int. == MATCHexact.
Phase 2: 1 matches T (==already deduced to int). == MATCHexact.

Finally, foo(T)(T) is less specialized than foo(T:int)(T).

I explain more complicated case.

void bar(int, int) {}
void bar(T)(T, int) {}
bar(1, 1L);

With first overload version,
Phase 1: normal function is treated as having empty template parameter list, so
 matching is always exact == MATCHexact
Phase 2: int - 1 == MATCHexact, int - 1L == MATCHconvert. == MATCHconvert

With second overload version,
Phase 1: T - typeof(int). == MATCHconvert
Phase 2: T - 1 == MATCHexact, int - 1L == MATCHconvert == MATCHconvert

From the comparison of Phase 1 result, bar(int, int) is more specialized than
bar(T)(T, int) for function arguments (1, 1L).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-28 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #16 from Kenji Hara k.hara...@gmail.com 2013-02-28 20:46:30 PST 
---
(In reply to comment #13)
 // vs specialized parameter
 int f4(int a) { return 1; }
 int f4(T:int)(T b) { return 2; }

 static assert(f4(1)==1);

Just only this is wrong. f4(T:int) is specialized to int argument, so f4(1)
could match both normal function version and template version *with the same
extent*. Then it will be ambiguous.

 static assert(f4(1L)==1);

Ok. f4(T:int) cannot instantiate with T==long, so first version will be called.


(In reply to comment #15)
 (In reply to comment #14)
  ...
  
  static assert(f6(1L) == 1);
  static assert(f6(ulong.max) == 2); // (a) ???
  
 
 No match.
 
  ulong ul = runtime();
  static assert(f6(ul) == 2);// (b) ???
  
 
 No match.

Both (a) and (b) should be no match, but with my experimental change, (a)
wrongly matches to int. I found an another bug in there, and filed it as bug
9617.


Current test case results with my pull request:
https://github.com/D-Programming-Language/dmd/pull/1409

is:

int f1(int a, double=10) { return 1; }
int f1(int a, string=) { return 2; }

int f2(T:int)(T b, double=10) { return 1; }
int f2(T:int)(T b, string=) { return 2; }

// vs deduced parameter
int f3(int a) { return 1; }
int f3(T)(T b) { return 2; }

// vs specialized parameter
int f4(int a) { return 1; }
int f4(T:int)(T b) { return 2; }

// vs deduced parameter + template constraint (1)
int f5(int a) { return 1; }
int f5(T)(T b) if (is(T == int)) { return 2; }

// vs deduced parameter + template constraint (2)
int f6(int a) { return 1; }
int f6(T)(T b) if (is(T : int)) { return 2; }

// vs nallowing conversion
int f7(ubyte a) { return 1; }
int f7(T)(T b) if (is(T : int)) { return 2; }

void main()
{
static assert(!__traits(compiles, f1(1)));  // ambiguous
static assert(!__traits(compiles, f1(1L))); // ambiguous

static assert(!__traits(compiles, f2(1)));  // ambiguous
static assert(!__traits(compiles, f2(1L))); // no match

assert(f3(1) == 1);
assert(f3(1L) == 2);

static assert(!__traits(compiles, f4(1)));
assert(f4(1L) == 1);

assert(f5(1) == 1);
assert(f5(1L) == 1);

assert(f6(1) == 1);
assert(f6(1L) == 1);
static assert(!__traits(compiles, f6(ulong.max))); // no match
  // needs to fix bug 9617
ulong ulval = 1;
static assert(!__traits(compiles, f6(ulval))); // no match

assert(f7(200u) == 2);
assert(f7(400u) == 2);
uint uival = 400;   // TDPL-like range knowledge lost here.
assert(f7(uival) == 2);
a = 200;// Ditto.
assert(f7(uival) == 2);
}


I welcome more complicated test case.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


monarchdo...@gmail.com changed:

   What|Removed |Added

 CC||monarchdo...@gmail.com


--- Comment #14 from monarchdo...@gmail.com 2013-02-27 04:39:08 PST ---
(In reply to comment #13)
 I have implemented it in accordance with TDPL, and the following behaviour
 results:
 
 // vs deduced parameter + template constraint (2)
 int f6(int a) { return 1; }
 int f6(T)(T b) if (is(T : int)) { return 2; }
 
 void main(){
 static assert(f6(1)==1);
 static assert(f6(1L)==1);
 }

How does that work though, because here, you statically know that 1L will fit
in your int. But what about:

static assert(f6(1L) == 1);
static assert(f6(ulong.max) == 2); // (a) ???

ulong ul = runtime();
static assert(f6(ul) == 2);// (b) ???

How would these resolve?

I am not really comfortable with the fact that a call can statically resolve to
two different functions depending on the static information of the *value* of a
parameter:

int f7(ubyte a) { return 1; }
int f7(T)(T b) if (is(T : int)) { return 2; }

void main(){
static assert(f6(200u)==1); //Calls first
static assert(f6(400u)==2); //Calls second (!?)

//Run-time variable with TDPL-like range knowledge
uint a = 400;
static assert(f6(a) == 2); //Calls second  ?
a = 200;
static assert(f6(a) == 1); //But now calls first !?
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #15 from timon.g...@gmx.ch 2013-02-27 06:29:43 PST ---
(In reply to comment #14)
 ...
 
 static assert(f6(1L) == 1);
 static assert(f6(ulong.max) == 2); // (a) ???
 

No match.

 ulong ul = runtime();
 static assert(f6(ul) == 2);// (b) ???
 

No match.

 How would these resolve?
 
 I am not really comfortable with the fact that a call can statically resolve 
 to
 two different functions depending on the static information of the *value* of 
 a
 parameter:
 

Well, that is how the language is specified.


int f8(byte){ return 1; }
int f8(long){ return 2; }

void main(){
static assert(f8(1)==1); // calls first
static assert(f8(256)==2); // calls second
int x=1;
f8(x); // calls second
}

 int f7(ubyte a) { return 1; }
 int f7(T)(T b) if (is(T : int)) { return 2; }
 
 void main(){
 static assert(f6(200u)==1); //Calls first

No, calls second.

 static assert(f6(400u)==2); //Calls second (!?)
 

Yes.

 //Run-time variable with TDPL-like range knowledge
 uint a = 400;

Knowledge lost here.

 static assert(f6(a) == 2); //Calls second  ?
 a = 200;

Ditto.

 static assert(f6(a) == 1); //But now calls first !?
 }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-25 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


timon.g...@gmx.ch changed:

   What|Removed |Added

 CC||timon.g...@gmx.ch


--- Comment #13 from timon.g...@gmx.ch 2013-02-25 02:15:54 PST ---
(In reply to comment #12)
 ...
 
 Therefore, I'd ask question again to Walter: how does above cases behave?

I have implemented it in accordance with TDPL, and the following behaviour
results:

int f1(int a, double=10) { return 1; }
int f1(int a, string=) { return 2; }

int f2(T:int)(T b, double=10) { return 1; }
int f2(T:int)(T b, string=) { return 2; }

// vs deduced parameter
int f3(int a) { return 1; }
int f3(T)(T b) { return 2; }

// vs specialized parameter
int f4(int a) { return 1; }
int f4(T:int)(T b) { return 2; }

// vs deduced parameter + template constraint (1)
int f5(int a) { return 1; }
int f5(T)(T b) if (is(T == int)) { return 2; }

// vs deduced parameter + template constraint (2)
int f6(int a) { return 1; }
int f6(T)(T b) if (is(T : int)) { return 2; }

void main(){
f1(1);  // error: ambiguous
f1(1L); // error: ambiguous

f2(1);  // error: ambiguous
f2(1L); // error: no match

static assert(f3(1)==1);
static assert(f3(1L)==2);

static assert(f4(1)==1);
static assert(f4(1L)==1);

static assert(f5(1)==1);
static assert(f5(1L)==1);

static assert(f6(1)==1);
static assert(f6(1L)==1);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Kenji Hara k.hara...@gmail.com changed:

   What|Removed |Added

   Keywords|pull|


--- Comment #10 from Kenji Hara k.hara...@gmail.com 2013-02-24 21:32:10 PST 
---
(In reply to comment #9)
 https://github.com/D-Programming-Language/dmd/pull/1409

By implementing it, I found some corner cases. How should these behave?

int f1(int a, double=10) { return 1; }
int f1(int a, string=) { return 2; }

int f2(T:int)(T b, double=10) { return 1; }
int f2(T:int)(T b, string=) { return 2; }

// vs deduced parameter
int f3(int a) { return 1; }
int f3(T)(T b) { return 2; }

// vs specialized parameter
int f4(int a) { return 1; }
int f4(T:int)(T b) { return 2; }

// vs deduced parameter + template constraint (1)
int f5(int a) { return 1; }
int f5(T)(T b) if (is(T == int)) { return 2; }

// vs deduced parameter + template constraint (2)
int f6(int a) { return 1; }
int f6(T)(T b) if (is(T : int)) { return 2; }

void main()
{
f1(1);  // ambiguous error
f1(1L); // ambiguous error

f2(1);  // ambiguous error
f2(1L); // ambiguous error

f3(1);  // ?
f3(1L); // ?

f4(1);  // ?
f4(1L); // ?

f5(1);  // ?
f5(1L); // ?

f6(1);  // ?
f6(1L); // ?
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #11 from Walter Bright bugzi...@digitalmars.com 2013-02-24 
21:54:47 PST ---
(In reply to comment #10)
 f3(1);  // 1
 f3(1L); // 2
 
 f4(1);  // ambiguous
 f4(1L); // ambiguous
 
 f5(1);  // 1
 f5(1L); // 1
 
 f6(1);  // 1
 f6(1L); // 2
 }

The more specialized overload always wins.

The constraint is not considered when evaluating which is more specialized.
(Because in general we cannot evaluate that.) The constraint only determines if
an overload is to be considered - it does not determine ordering.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2013-02-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #12 from Kenji Hara k.hara...@gmail.com 2013-02-24 22:30:26 PST 
---
(In reply to comment #11)
 The more specialized overload always wins.
 
 The constraint is not considered when evaluating which is more specialized.
 (Because in general we cannot evaluate that.) The constraint only determines 
 if
 an overload is to be considered - it does not determine ordering.

Thanks for quickly answer. So, the resolution result of f5 and f6 should be
same as f3, because they are identical when hide their constraints. Right?

But, there is still questionable. How to calculate The more specialized
overload between function template and non-template one? For example, try to
consider case for f3(1). That is:

1. Normal function version f3(int) will match exactly to one int argument.
2. Function template version will deduce T - int, and then instantiated
function f3!(int) == void f3(int) will match _exactly_ to one int argument.

But, in general, template version is less specialized than non-template
version. So, there is something necessary for ordering.

---
Consider one another case for f4(1L). That is:

1. Normal function will match to one long argument with conversion
(MATCHconvert).
2. Function template version will deduce T - long and then instantiated
function f4!long will match exactly to one long argument.

Which is specialized? In general, template version would be intended to pick up
non-exact matching for generic cases. But, as far as I infer from current dmd
implementation, f4(1L) will be ambiguous (template type parameter deduction
without specialization always be MATCHconvert).

Therefore, I'd ask question again to Walter: how does above cases behave?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2012-12-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Kenji Hara k.hara...@gmail.com changed:

   What|Removed |Added

   Keywords||pull


--- Comment #9 from Kenji Hara k.hara...@gmail.com 2012-12-27 01:34:31 PST ---
https://github.com/D-Programming-Language/dmd/pull/1409

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2012-08-25 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Simen Kjaeraas simen.kja...@gmail.com changed:

   What|Removed |Added

 CC||simen.kja...@gmail.com


--- Comment #6 from Simen Kjaeraas simen.kja...@gmail.com 2012-08-25 05:53:56 
PDT ---
This bug causes problems with @disabled default constructors.

Given:

struct Foo {
@disable this();
this( T )( T a ) {
}
}

This bug triggers.

Given instead:

struct Bar {
@disable this( )( );
this( T )( T a ) {
}
}

The default constructor is not disabled.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2012-08-25 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Jonathan M Davis jmdavisp...@gmx.com changed:

   What|Removed |Added

 CC||jmdavisp...@gmx.com


--- Comment #7 from Jonathan M Davis jmdavisp...@gmx.com 2012-08-25 11:18:39 
PDT ---
 This bug causes problems with @disabled default constructors.

From what I can tell, @disable this() doesn't work _at all_: bug# 7021

I don't think that this bug has anything to do with it.

And I wouldn't expect @disable this()(); to work anyway, because the function
that you're trying to disable doesn't exist. It would have to be instantiatied
to exist, and it's not possible to call a default constructor on a struct,
since they're not legal in the first place, so it can't be instantiated.
@disable this()(); should probably result in an error.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2012-08-25 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #8 from Simen Kjaeraas simen.kja...@gmail.com 2012-08-25 12:19:25 
PDT ---
(In reply to comment #7)
  This bug causes problems with @disabled default constructors.
 
 From what I can tell, @disable this() doesn't work _at all_: bug# 7021

@disable this() does work in some cases:

struct Foo {
@disable this( );
}

struct Bar {
Foo f;
this( int n ) {
// Error: constructor Bar.this field f must be initialized in
constructor
}
}

void main( ) {
Foo f; // Error: variable main.d initializer required for type Foo
}

However, if you need a templated constructor, this goes out the window, for the
reasons outlined above.


 I don't think that this bug has anything to do with it.

Yes and no. The problems of @disable this are exacerbated by this bug.


 And I wouldn't expect @disable this()(); to work anyway, because the function
 that you're trying to disable doesn't exist. It would have to be instantiatied
 to exist, and it's not possible to call a default constructor on a struct,
 since they're not legal in the first place, so it can't be instantiated.
 @disable this()(); should probably result in an error.

Nor would I, but when faced with the error that templated and non-templated
functions cannot form an overload set together, that is the logical thing to
try, and it doesn't work either.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2012-01-21 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


Andrej Mitrovic andrej.mitrov...@gmail.com changed:

   What|Removed |Added

 CC||dsim...@yahoo.com


--- Comment #5 from Andrej Mitrovic andrej.mitrov...@gmail.com 2012-01-21 
18:22:11 PST ---
*** Issue 2972 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2011-12-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528


yebblies yebbl...@gmail.com changed:

   What|Removed |Added

   Keywords||rejects-valid
 CC||yebbl...@gmail.com
   Platform|x86 |All
Summary|[tdpl] templates should not |[tdpl] overloading template
   |conflict with non-templates |and non-template functions
 OS/Version|Windows |All
   Severity|enhancement |major


--- Comment #3 from yebblies yebbl...@gmail.com 2011-12-25 03:37:21 EST ---
From Andrei's comment in 7134:

This TDPL code does not compile:

class A {
   // Non-overridable method
   A opBinary(string op)(A rhs) {
  // Forward to an overridable function
  return opBinary(op, rhs);
   }
   // Overridable method, dispatch string at runtime
   A opBinary(string op, A rhs) {
  switch (op) {
 case +:
break;
 case -:
break;
  }
   }
}

Overloading template and non-template functions must be implemented.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1528] [tdpl] overloading template and non-template functions

2011-12-24 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1528



--- Comment #4 from Andrei Alexandrescu and...@metalanguage.com 2011-12-24 
09:15:52 PST ---
Thanks for consolidating!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---