Description
Can the Kernel Instantiation node throw?
It would throw if type bounds are checked at instantiation, and potentially every generic method would need different instantiation code.
@leafpetersen said:
Yeah, good question, this has been nagging at me. The only situation in which there is an implied dynamic check on type arguments in a static invocation is when the bound of a type parameter itself involves a covariant type parameter from an outer class:
class A<T> {
void foo<S extends T> (S x) {};
}
class B extends A<int> {
void foo<S extends int> (S x) {x.isEven; }
}
A<Object> a = new B();
void Function(Object) foo = a.foo; // Throws?
a.foo<Object>("hello"); // Throws
a.foo<Object>(3); // Still throws
foo("hello"); // Throws?
So the question is which of the two places should throw?
My assumption has been that implementations would put the check in the body of the method, and so the "convenient" place to throw is at the actual call site, not the instantiation site. This is what DDC does.
It's probably slightly nicer to the user to throw at the instantiation site, but this is a pretty corner case example.
Thoughts from the implementations? Things I'm missing? Lasse, Erik, thoughts?