Closed
Description
Compiler version
3.7
Minimized code
//> using options -Werror -Wunused:privates
case class BinaryFen(value: Array[Byte]) extends AnyVal:
def read: Unit =
val reader = new Iterator[Byte]:
val inner = value.iterator
override inline def hasNext: Boolean = inner.hasNext // nowarn
override inline def next: Byte = if hasNext then inner.next else 0.toByte // nowarn
if reader.hasNext then
val b: Byte = reader.next
println(b)
Output
-- [E198] Unused Symbol Warning: tests/warn/unused-inline-private.scala:9:45 ---
9 | override inline def hasNext: Boolean = inner.hasNext // nowarn
| ^
| unused private member
-- [E198] Unused Symbol Warning: tests/warn/unused-inline-private.scala:10:45 --
10 | override inline def next: Byte = if hasNext then inner.next else 0.toByte // nowarn
| ^
| unused private member
2 warnings found
Expectation
Quick println shows that it is reporting
PRIVATE method next$retainedBody
PRIVATE method hasNext$retainedBody
but it should exclude those special methods.
Worth adding that the lichess code probably does not do what was probably expected.
public final void read$extension(byte[]);
descriptor: ([B)V
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
Code:
stack=3, locals=4, args_size=2
0: new #9 // class BinaryFen$$anon$1
3: dup
4: aload_1
5: invokespecial #98 // Method BinaryFen$$anon$1."<init>":([B)V
8: astore_2
9: aload_2
10: invokeinterface #104, 1 // InterfaceMethod scala/collection/Iterator.hasNext:()Z
15: ifeq 39
18: aload_2
19: invokeinterface #107, 1 // InterfaceMethod scala/collection/Iterator.next:()Ljava/lang/Object;
24: invokestatic #111 // Method scala/runtime/BoxesRunTime.unboxToByte:(Ljava/lang/Object;)B
27: istore_3
28: getstatic #116 // Field scala/Predef$.MODULE$:Lscala/Predef$;
31: iload_3
32: invokestatic #120 // Method scala/runtime/BoxesRunTime.boxToByte:(B)Ljava/lang/Byte;
35: invokevirtual #124 // Method scala/Predef$.println:(Ljava/lang/Object;)V
38: return
39: return
It uses the unspecialized next
, which boxes the result of specialized next
, which unboxes the result of underlying inner.next
.
Also normally the anon iterator should extend AbstractIterator
.