Java, 102 95 89 88 78 bytes
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>a=new B<>();}
This terminates with a StackOverflowError
which happens because the generic resolution system can't decide a root against which to resolve the other generics.
Credits where due.
What happens here?
A<T>
is just there to have a 1-letter parent. It's generic. I could have used List
, but the imports and repetition of 4 letters are too long.
B<T>
declares a basic generic.
B extends A
is required to have a hierarchy between B
and A
.
extends A<A>
creates a self reference on A<T>
.
A<? super B>
triggers the lookup for generics on A<T>
B<B<T>>
creates a self-reference on B<T>
.
A<...> a=new B<>()
forces the usage of the generics, instead of simply the definition of those, forcing the resolution when compiling B
, and not afterwards.
A<?super B
creates a non-self-reference, so we have both a reference to one type and to another in the generics of A
.
B<A>
creates a non-self-reference, so we have both a reference to one type and to another in the generics of B
.
Now, the type A
has generics type A
and B
, but which is to be chosen? Forget about self, let's try to resolve B
. Ping.
Okay, B
has generics type A
and B
, but which is to be chosen? Forget about self, let's try to resolve A
. Pong.
This kind of recursion can't really be avoided because there are legitimate cases like A<B<A<B<A<B<Object>>>>>>
: for example a JSON object: List<Map<String,Map<String,List<Map<String,List<String>>>>>>
.
Compilation result
$ javac NoCompile.java
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2587)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2592)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
On my system, the stack trace stops after showing 1024 lines, which are actually the 4 same lines repeated 256 times, thus proving an infinite recursion. I'll spare you that whole trace.
Savings
- 102 → 95 bytes: replaced
interface
+implements
with class
+extends
.
- 95 → 89 bytes: replaced
Long
with A
(twice).
- 89 → 88 bytes: used diamond operator (
new B<A>()
→ new B<>()
) .
- 88 → 78 bytes: moved the variable declaration to a class member, thanks to VoteToClose.
Java
: define an annotation processor(ideone snippet) which you'll use when invokingjavac
with its-processor
option. It makes the compilation of any class hang forever. \$\endgroup\$