unsound refinement with inferred return type
gavinking opened this issue · 2 comments
gavinking commented
The typechecker should not accept this unsound code:
Iterable<Iterable<Element?,Absent2>,Absent1> transpose<Element,Absent1,Absent2>
(Iterable<Iterable<Element,Absent1>,Absent2> streams)
given Absent1 satisfies Null
given Absent2 satisfies Null
=> object satisfies Iterable<Iterable<Element?,Absent2>,Absent1> {
value iterators = streams.collect((stream) => stream.iterator());
iterator() => object satisfies Iterator<Iterable<Element?,Absent2>> {
shared actual function next() {
value elements = iterators.collect((it) => it.next());
return elements.every((it) => it is Finished) then finished
else elements.collect((it) => if (is Finished it) then null else it);
}
};
};
gavinking commented
OK, so this is a problem with typechecking return
in refined members with inferred type.
//OK
class X() {
shared actual function equals(Object x) => 1; //error
shared actual value string => 1; //error
}
//OK
class Y() {
equals(Object x) => 1; //error
string => 1; //error
}
//BAD
class Z() {
shared actual function equals(Object x) {
return 1; //NO ERROR!
}
shared actual value string {
return 1; //NO ERROR!
}
}
Ugh, that's really nasty. At least this is an undocumented feature. :-/
gavinking commented
Heh. So this bug exists in all released versions of Ceylon 1.3, and nobody ever noticed.