Problem with implicit casts? #739
brian
11 Sep 2009
Promoted to ticket #739 and assigned to brian
Yeap, that is a definitely a bug - the compiler should catch that and perform an implicit cast.
brian
5 Nov 2009
Ticket cancelled
Ok, I dug into this and I don't think there is a problem.
The compiler is correctly inserting a coerce opcode. For example:
static Void foo(Obj x := 3) { echo(x) }
Will compile into:
foo (sys::Obj x) -> sys::Void [const public static]
[Param 0] x -> sys::Obj
0: LoadInt 3
3: Coerce sys::Int => sys::Obj
[Code]
0: LoadVar 0
3: CallStatic sys::Obj.echo(sys::Obj?) -> sys::Void
6: Return
In this particular case, casting a list doesn't actually change the type of the original list. So your can use Obj[,] where a Foo[] is expected. But the original list never changes its type. So you fix to change the default parameter to Foo[] is the right solution.
IvanI
11 Sep 2009
Hello, Today I found the problem with mismatching actual object field type with field definition from class.
Here is an example:
class Foo {
new make(Foo[] foos := [,]) {this.foos = foos} Foo[] foos Int i := 1 public static Void main() { echo(Foo().foos.type) //prints sys::Obj?[] echo(Foo([Foo()]).foos.type) //prints sys::Obj[] }}
After changing constructor parameter to
Foo[] foos := Foo[,]everything works as expected. I think there should be either a compile error (like default parameter value does not match to parameter type), or implicit cast to Foo[], but this does not happen.As a result, there is a problem with object equality.
For example, we override sys::Obj.equals method like this:
override Bool equals(Obj? that) {
}
And then have code like this:
public static Void main() {
foos := [Foo(), Foo()] a := Foo(foos) b := Foo() b.foos.addAll(a.foos) echo("(a == b) = ${a == b}") //false!}