The with
is not ignored.
The spec for new t
actually says that new Queue with Add30
is equivalent to:
{ class a extends Queue with Add30 ; new a }
Sure, but does it actually compile to that?
In fact:
scala> new Queue with Add30
res8: Queue with Add30 = $anon$1@aa21042
scala> :javap -prv -
Binary file res8 contains $line18.$read$$iw$$iw$
[snip]
private final $line12.$read$$iw$$iw$Queue res8;
flags: ACC_PRIVATE, ACC_FINAL
[snip]
public $line18.$read$$iw$$iw$();
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #19 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #21 // Field MODULE$:L$line18/$read$$iw$$iw$;
8: aload_0
9: new #23 // class $line18/$read$$iw$$iw$$anon$1
12: dup
13: invokespecial #24 // Method $line18/$read$$iw$$iw$$anon$1."<init>":()V
16: putfield #17 // Field res8:L$line12/$read$$iw$$iw$Queue;
19: return
So the resulting value is just a Queue
, but you're instantiating an anonymous subclass that trivially extends it. I'm too lazy (I mean busy) to try -optimize
.
You can turn the question around and ask why does with T with T
complain about trait T is inherited twice
? Can't linearization handle the redundancy?
I think the second case, where the a
disappears from the linearization, is for the case:
scala> class X
defined class X
scala> trait Y extends X
defined trait Y
scala> new X with Y
res15: X with Y = $anon$1@5af97169
where you're mixing in a Y
that already extends X
.
But now I must use the napkin (serviette) on which I was scribbling for its primary use case and go back to what I was doing before.