Skip to content

Instantly share code, notes, and snippets.

@melix
Created March 14, 2013 22:00
Show Gist options
  • Save melix/5165645 to your computer and use it in GitHub Desktop.
Save melix/5165645 to your computer and use it in GitHub Desktop.
Why runtime checks are required for reified generics
First, create:
foo/Echo.ceylon:
class Echo() {
shared void echo(Array<String> list) { print(list); }
}
foo/Echo2.ceylon
import foo {Echo}
class Echo2() {
Echo echo = Echo();
Array<String> list = array { "Hello", "World" };
echo.echo(list);
}
compile them:
$ ceylon compile --src . foo/*.ceylon
run:
$ ceylon run --run=foo.Echo2 default
{ Hello, World }
Now change Array<String> to Array<Integer> in Echo.ceylon. Compile *this file* again:
$ ceylon compile --src . foo/Echo.ceylon
Run:
$ ceylon run --run=foo.Echo2 default
{ Hello, World }
Should have failed, but did not, because Echo2 was linked to the method at compile time the first time, and the JVM doesn't know about generics, so the method exists, but doesn't do any runtime check. Even if ceylon performs compile-time checks, they can be easily worked around.
Compile the whole in a row:
$ ceylon compile --src . foo/*.ceylon
foo/Echo2.ceylon:6: error: argument must be assignable to parameter list of echo: Array<String> is not assignable to Array<Integer>
echo.echo(list);
^
1 error
Note: Created module default
ceylon compile: There was 1 error
So it shows that a simple API change is needed to break reified generics if no runtime checks are done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment