class Cell { public A value; public Cell (A v) { value = v; } public static Cell allocate (B x) { return new Cell(x); } } class Pair { public A fst; public B snd; public Pair (A x, B y) { fst = x; snd = y; } public static Pair duplicate (C x) { return new Pair(x,x); } } class Loophole { public static String loophole (Byte y) { Pair,Cell> p = Pair.duplicate(Cell.allocate(null)); // compile-time error p.snd.value = y; return p.fst.value; } public static String permitted (String x) { Pair,Cell> p = Pair.duplicate(Cell.allocate((String)null)); p.fst.value = x; return p.snd.value; } }