Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Critical
-
Resolution: Unresolved
-
Affects Version/s: X10 2.1.2
-
Fix Version/s: X10 2.3.2
-
Component/s: X10 Compiler: Front-end
-
Labels:None
-
Number of attachments :
Description
Here's what Vijay wrote about method resolution:
1. List all the exact methods that could possibly be used (generic type
inferencing performed; implicit coercions not performed; if DYNAMIC_CHECKS
is on, then constraints need not match exactly)2. Determine the most specific ones.
3. If there is one; this is the method, stop.
4. If there are more than one, declare an ambiguity error and stop.
5. Repeat steps 1-4, this time with implicit coercions performed.
6. If method is not found, declare no method found and stop.
That doesn't seem to be what X10 is doing.
class Res2 {
interface Surface {}
public static class Ace implements Surface {
public static operator (Byte) : Ace = new Ace();
}
def m(x:Int) = {Console.OUT.println("Int x=" + x + " type=" + x.typeName());return 1;}
def m(x:Surface) = {Console.OUT.println("Surface x=" + x + " type=" + x.typeName());return 3;}
def example() {
assert m(100) == 1 : "Int";
// An Ace is a Surface, unambiguous best choice
assert m(new Ace()) == 3 : "Ace";
assert m(1y) == 3 : "Byte";
}
public static def main(argv:Array[String](1)) {
(new Res2()).example();
Console.OUT.println("That's all!");
}
}
There are implicit coercions from Byte to Int and Ace, so, by the above rules, this ought to be a static error. Instead, it's not; X10 silently picks the Byte->Int coercion:
x10c Res2.x10
~/x10/tmp: x10 Res2
Int x=100 type=x10.lang.Int
Surface x=Res2.Ace@32bf7190 type=Res2.Ace
Int x=1 type=x10.lang.Int
x10.lang.AssertionError: Byte
at Res2.example(Res2.java:130)
at Res2.main(Res2.java:154)
at Res2$$Main.runtimeCallback(Res2.java:144)
at x10.runtime.impl.java.Runtime$$Closure$Main.$apply(Runtime.java:92)
at x10.lang.Runtime$$Closure$146.$apply(Runtime.java:3966)
at x10.lang.Activity.run(Activity.java:590)
at x10.lang.Runtime$Worker.loop(Runtime.java:1087)
at x10.lang.Runtime$Worker.$apply(Runtime.java:1022)
at x10.lang.Runtime$Pool.$apply(Runtime.java:1540)
at x10.lang.Runtime.start(Runtime.java:2237)
at x10.runtime.impl.java.Runtime.$apply(Runtime.java:132)
at x10.runtime.impl.java.Thread.run(Thread.java:48)
~/x10/tmp:
Here's a similar program, differing only in that the method m looks for an instance of class Ace rather than interface Surface:
class Res3 {
interface Surface {}
public static class Ace implements Surface {
public static operator (Byte) : Ace = new Ace();
}
def m(x:Int) = {Console.OUT.println("Int x=" + x + " type=" + x.typeName());return 1;}
def m(x:Ace) = {Console.OUT.println("Ace x=" + x + " type=" + x.typeName());return 3;}
def example() {
assert m(100) == 1 : "Int";
assert m(new Ace()) == 3 : "Ace";
assert m(1y) == 3 : "Byte";
}
public static def main(argv:Array[String](1)) {
(new Res3()).example();
Console.OUT.println("That's all!");
}
}
This doesn't compile, but the error message doesn't seem to indicate that it's failing to compile for the right reason:
x10c Res3.x10
/Users/bard/x10/tmp/Res3.x10:13: Method m(x: x10.lang.Int): x10.lang.IntUnknown macro: {self==1}in Res3
Unknown macro: {self==Res3#this}cannot be called with arguments (x10.lang.Byte
); Invalid Parameter.
Expected type: x10.lang.Int
Found type: x10.lang.ByteUnknown macro: {self==1}1 error.
~/x10/tmp:
Issue Links
- is depended upon by
-
XTENLANG-2971
Umbrella language/front-end JIRA for X10 2.4
-
- is related to
-
XTENLANG-2480
Type bounds do not play nice with coercions
-
- relates to
-
XTENLANG-1692
Operator resolution is wrong
-
And, in another variation on the same theme, the following code
ought to notice that a Place can be coerced into an Ace, which
is a kind of Surface, and so m applies.
class Res { public static interface Surface {} public static class Ace implements Surface { public static operator (Place) : Ace = new Ace(); } def m(x:Surface) = 3; def example() { assert m(here) == 3 : "Place"; } public static def main(argv:Array[String](1)) { (new Res()).example(); Console.OUT.println("That's all!"); } }But no: