New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ambiguous method overloading compiles, but should not #2628
Comments
Imported From: https://issues.scala-lang.org/browse/SI-2628?orig=1 |
@lrytz said: foo.bar(10)(2.0f) overloading resolution is done on the application |
@nilskp said:
Could you point me to the exact place in the spec?
Is there a particular reason for this? (I assume there is, so I'm fishing for the reason). |
@lrytz said:
Nightly build: http://www.scala-lang.org/node/212/pdfs, Section 6.25.3
Simplicity I guess (in both, spec and implementation) |
@odersky said: |
@nilskp said: bar(5): Unit
val u1: Unit = bar(5)
bar(5)(2f): Unit
val u2: Unit = bar(5)(2f) |
@adriaanm said: |
@nilskp said:
But if I don't partially apply, they are.
Both fail. Please try before closing again. These are the two errors I get: bar(5): Unit // ambiguous reference to overloaded definition, both method bar in object Foo of type (i: Int)(f: Float)Unit and method bar in object Foo of type (i: Int)Unit match argument types (Int)
bar(5): Float => Unit // not a legal formal parameter
bar(5): (Float => Unit) // ambiguous reference to overloaded definition, both method bar in object Foo of type (i: Int)(f: Float)Unit and method bar in object Foo of type (i: Int)Unit match argument types (Int) |
@adriaanm said: Martin: I tried out various combinations of argument types, and could refer to the overload with one argument list (except not in the given example -- see below for one where I did manage), but never to the one with two. scala> object Foo {
| def bar(i: Int) = println(i)
| def bar(i: Int) (f: Float) = println(i*f)
| }
defined module Foo
scala> Foo.bar(5): (Float => Unit)
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (i: Int)(f: Float)Unit
and method bar in object Foo of type (i: Int)Unit
match argument types (Int)
Foo.bar(5): (Float => Unit)
^
scala> object x{def a(i: String): Option[String] = Some("a"); def a(i: String)(b: List[String]): Int = 1}
defined module x
scala> x.a("a"): Option[String]
res10: Option[String] = Some(a)
scala> def f(xs: List[String]): Int = x.a("a")(xs)
<console>:5: error: ambiguous reference to overloaded definition,
both method a in object x of type (i: String)(b: List[String])Int
and method a in object x of type (i: String)Option[String]
match argument types (java.lang.String)
def f(xs: List[String]): Int = x.a("a")(xs)
^
|
@odersky said: |
@nilskp said:
That would be fine if there was some way to call the second method. There is not (that I know of, short of using reflection). scala> object Foo {def bar(i:Int):Float=i;def bar(i:Int)(f:Float)=i*f;}
defined module Foo
scala> Foo.bar(5)
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (Int)(Float)Float
and method bar in object Foo of type (Int)Float
match argument types (Int)
Foo.bar(5)
^
scala> Foo.bar(5)(3.2f)
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (Int)(Float)Float
and method bar in object Foo of type (Int)Float
match argument types (Int)
Foo.bar(5)(3.2f)
^
scala> Foo.bar(5): Float
res2: Float = 5.0
scala> Foo.bar(5)(3.2f): Float
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (Int)(Float)Float
and method bar in object Foo of type (Int)Float
match argument types (Int)
Foo.bar(5)(3.2f): Float
^
scala> Foo.bar(5) _
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (Int)(Float)Float
and method bar in object Foo of type (Int)Float
match argument types (Int)
Foo.bar(5) _
^
scala> Foo.bar(5): (Float=>Float)
<console>:6: error: ambiguous reference to overloaded definition,
both method bar in object Foo of type (Int)(Float)Float
and method bar in object Foo of type (Int)Float
match argument types (Int)
Foo.bar(5): (Float=>Float)
^ It does not seem right that one can define methods that simply cannot be called. I would much prefer that both methods could be called, since they do not appear ambiguous to me Foo.bar(5) // Unambiguously calls the single parm variant
Foo.bar(5) _ // Unambiguously calls the double parm variant partially
Foo.bar(5)(2f) // Unambiguously calls the double parm variant. Short of that, it seems that the same ambiguity rules should be applied to defs, preventing creation of methods that are impossible to reference. |
@odersky said: |
@nilskp said: |
The following compiles, yet neither method is callable due to ambiguity (although I have yet to be pointed to where in the spec that is considered ambiguous).
The text was updated successfully, but these errors were encountered: