I'm writing code for a command shell that looks like this:
interface Context<C extends Context<C>> {}
interface RecursiveContext<C extends RecursiveContext<C>> extends Context<C> {
Shell<C> getShell();
default Result execute(Command cmd) { return getShell().execute(cmd, this); }
}
interface Shell<C extends Context<C>> {
C newContext();
Result execute(Command cmd, C context);
}
I'm getting an error in the default method saying
The method execute(Command, C) in the type Shell<C> is not applicable for the arguments (Command, RecursiveContext<C>)
I expect this to work, since the Shell<C> getShell() is guaranteed to be able to accept C in its execute call and because this is in fact guaranteed to be a subtype of the same self-bound type C, but the compiler does not seem to agree with me. Where's the mismatch, and is it safe to perform a cast in the default method? If this is not safe, can you provide a counterexample of type mismatch?
I've also tried introducing an intermediate type in the shell <D extends C> execute(Command, D), but that doesn't seem to change anything.
(Most of the suggested questions involve a raw-type intermediate step, but I don't think that I've missed that.)