Need to reconsider fine points of instantiating a generic type in a way that makes method overloading ambiguous


The manual explains what should happen when an instantiation of a generic
class makes method overloading ambiguous. This explanation
("complain-on-call"), while sensible, will require us to massively rework our
C++ back end implementation. So, Bard and Igor propose we switch to a somewhat
different approach, "complain-on-instantiation".

Both concepts concern ambiguous overloadings. If we have a type C[T] with
methods def m(x:T)=1; and def m(x:Int)=2;, then C[Int] has two
methods with the same signature.

"complain-on-call" says that it is illegal to use an ambiguous method. So
we could create an instance of C[Int], but not call it's m method.

"complain-on-instantiation" says that it is illegal to use a type with
ambiguous methods. So we can't even create an instance of C[Int].

  • Complain-on-instantiation is more restrictive than complain-on-call. So, if
    we make this change in 2.2, we can go to complain-on-call later if we want

  • But it's not much more restrictive. Bard hasn't, as of the time of
    writing, come up with any plausible example where complain-on-call allows
    something sensible but complain-on-instantiation doesn't.

  • Complain-on-instantiation can be checked in the front end, which ought to be
    easier and less troublesome than the back-end matters that complain-on-call

(The original motivation for complain-on-call is worth mentioning here.
Originally Bard had written something far more restrictive in the spec –
something that was restrictive enough to exclude some vaguely useful cases.
When this was pointed out, Bard went to the other extreme, of allowing as many
calls as possible. This decision was discussed very casually, but nobody
thought deeply about it until now. In particular, the material in the spec as
of today is not there because anyone needs that behavior in particular, or
because we have any reason to think it is right – it simply seemed like a
good idea at the time. So making this change is unlikely to have much
software-engineering impact.)

Here's what the spec says now. This is complain-on-call:

A class definition may include methods which are ambiguous in some
generic instantiation. (It is a compile-time error if the methods are
ambiguous in every generic instantiation, but excluding class
definitions which are are ambiguous in some instantiation would exclude
useful cases.) It is a compile-time error to use an ambiguous method

The following class definition is acceptable. However, the marked method
calls are ambiguous, and hence not acceptable.

The call t12.m(2) could refer to either the 1 or 2
definition of m, so it is not allowed.
The call t14.m(true) could refer to either the 1 or 4
definition, so it, too, is not allowed.

The call t13.m("ferret") refers only to the 1 definition. If
the 1 definition were absent, type argument inference would make it
refer to the 3 definition. However, X10 will choose a fully-specified
call if there is one, before trying type inference, so this call unambiguously
refers to 1.

This test case has been failing for a while.

Under the proposed new rules, the types Two[Int,Any] and
Two[Boolean,Boolean] will become illegal. The errors will be caught at the
val t12 and val t14 lines. Two[String,Any] will remain legal.






Imported User 59




Fix versions

Affects versions