scala/scala3

Inconsistencies in reporting deprecations with creator applications, aliases

Opened this issue · 1 comments

lrytz commented

Scala 3.4.2

There are a few spurious deprecations (warn!) and a few missing ones (no!).

@deprecated class C(x: Int); object C
class D @deprecated() (x: Int); object D

@deprecated case class E(x: Int)
case class F @deprecated() (x: Int) // warn! - two spurious warnings from synthetic code

class T:
  type AC = C  // warn
  val AC = C   // no
  type AD = D  // no
  val AD = D   // no
  type AE = E  // warn
  val AE = E   // no
  type AF = F  // no
  val AF = F   // no

  def t1 = new C(1)    // warn
  def t2 = C(1)        // warn
  def t3(x: C) = 1     // warn
  def t4 = C.toString  // no
  def t5 = new AC(1)   // no
  def t6 = AC(1)       // warn! - spurious warning, should be the same as t5
  def t7(x: AC) = 1    // no
  def t8 = AC.toString // no

  def u1 = new D(1)    // warn
  def u2 = D(1)        // warn
  def u3(x: D) = 1     // no
  def u4 = D.toString  // no
  def u5 = new AD(1)   // warn
  def u6 = AD(1)       // warn
  def u7(x: AD) = 1    // no
  def u8 = AD.toString // no

  def v1 = new E(1)    // warn
  def v2 = E(1)        // warn
  def v3(x: E) = 1     // warn
  def v4 = E.toString  // warn! - spurious warning on toString only? no warning on hashCode.
  def v5 = new AE(1)   // no
  def v6 = AE(1)       // warn! - spurious warning, should be the same as v5
  def v7(x: AE) = 1    // no
  def v8 = AE.toString // warn! - same bug as v4?

  def w1 = new F(1)    // warn
  def w2 = F(1)        // no! - missing warning, should be the same as w1
  def w3(x: F) = 1     // no
  def w4 = F.toString  // no
  def w5 = new AF(1)   // warn
  def w6 = AF(1)       // no! - missing warning, should be the same as w5
  def w7(x: AF) = 1    // no
  def w8 = AF.toString // no
lrytz commented

There was a discussion about what should ideally happen on the Scala 2 PR: scala/scala#10792 (comment).

To summarize, given @deprecated case class C(x: Int):

  • Currently the synthetic companion object is not deprecated; no warning for calling C.hashCode
  • It was considered too easy to miss the deprecation, so a warning was added when using C.apply to make sure C(1) warns
  • In general, deprecations should not propagate through type / value aliases. A warning is issued when defining type CC = C, but not when using CC in new CC(1).
  • The warning issued for using C.apply also shows up when using an alias (val CC = C; CC.apply(1) – example v6 in the bug report above). That is an issue, it was just fixed in Scala 2 (#10792).

Maybe instead of intercepting the apply call and warn if the companion class is deprecated, the annotation should be propagated to the synthetic compaion by default.

  • @deprecated case class C(x: Int) => the synthetic companion object C is deprecated
  • case class C @deprecated (x: Int) => the synthetic apply method in the companion object C is deprecated

Doing that change could affect many projects.