Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The expected way to deprecate an implicit class doesn't work #10152

Open
scabug opened this issue Jan 17, 2017 · 8 comments
Open

The expected way to deprecate an implicit class doesn't work #10152

scabug opened this issue Jan 17, 2017 · 8 comments

Comments

@scabug
Copy link

scabug commented Jan 17, 2017

Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions for evaluation. Or try :help.

scala> @deprecated("Foo is deprecated", "1.0.0")
     | implicit class Foo(i: Int) { def bar = i }
defined class Foo

scala> 1.bar // Expect a warning. Actually no warning
res0: Int = 1
@scabug
Copy link
Author

scabug commented Jan 17, 2017

Imported From: https://issues.scala-lang.org/browse/SI-10152?orig=1
Reporter: @Atry
Affected Versions: 2.12.1
See #8685

@scabug
Copy link
Author

scabug commented Jan 17, 2017

@som-snytt said:
The linked issue is also about synthetics getting the annotation.

Explicit def is not allowed:

scala> @deprecated("nope","forever") def C(i: Int) = new C(i) ; implicit class C(i: Int) { def doubled = i * 2 }
<console>:12: error: method C is defined twice;
  the conflicting method C was defined at line 12:42
       @deprecated("nope","forever") def C(i: Int) = new C(i) ; implicit class C(i: Int) { def doubled = i * 2 }
                                                                               ^

@Atry
Copy link

Atry commented Jun 15, 2017

@(deprecated @companionMethod) works.

Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.

scala> import scala.annotation.meta._
import scala.annotation.meta._

scala> @(deprecated @companionMethod)("Foo is deprecated", "1.0.0")implicit class Foo(i: Int) { def bar = i }
defined class Foo

scala> 1.bar
<console>:16: warning: method Foo is deprecated (since 1.0.0): Foo is deprecated
       1.bar
       ^
res0: Int = 1

Not sure if it is the expected usage

@som-snytt
Copy link

The workaround does not cover "don't warn if enclosing element is deprecated"; we need the annotation on the class:

scala> @(deprecated @companionMethod)("Nope","") implicit class C(@deprecated("Ugh","") val c: Int) extends AnyVal { def bumped = c + 1 }
                                                                                                                                  ^
       warning: value c in class C is deprecated: Ugh
                                                                ^
       warning: value c in class C is deprecated: Ugh
defined class C

scala> @(deprecated @companionMethod)("Nope","") class C(@deprecated("Ugh","") val c: Int) extends AnyVal { def bumped = c + 1 }
defined class C

@SethTisue
Copy link
Member

SethTisue commented Dec 9, 2020

volunteer to fix this? this is a pretty darn bad bug, IMO

note that you don't even have to invoke the implicit conversion, there is no deprecation warning regardless:

scala 2.13.4> @deprecated("","") class C(x: AnyRef) { def foo = 3 }
class C

scala 2.13.4> (new C(new AnyRef)).foo
                   ^
              warning: class C is deprecated:
val res16: Int = 3

scala 2.13.4> @deprecated("","") implicit class C(x: AnyRef) { def foo = 3 }
class C

scala 2.13.4> new C(new AnyRef)
val res18: C = C@36358417

@SethTisue SethTisue modified the milestones: Backlog, 2.13.5 Dec 9, 2020
@SethTisue SethTisue self-assigned this Feb 1, 2021
@SethTisue
Copy link
Member

I'm going to look into this.

@dwijnand
Copy link
Member

dwijnand commented Feb 1, 2021

scala> @(deprecated @companionMethod)("bye", "forever") @(deprecated @companionClass)("dead", "now") implicit class Foo(i: Int) { def bar = i }
class Foo

scala> 1.bar
       ^
       warning: method Foo is deprecated (since forever): bye
val res0: Int = 1

scala> new Foo(1).bar
           ^
       warning: class Foo is deprecated (since now): dead
val res1: Int = 1

Personally I think @deprecated should emit both, but as per the docs, the fix is making it work like @companionClass.

@SethTisue SethTisue changed the title No way to deprecate an implicit class The expected way to deprecate an implicit class doesn't work Feb 1, 2021
@som-snytt
Copy link

It changed from "no way to deprecate an implicit class" to "many unexpected ways" to do it.

@SethTisue SethTisue modified the milestones: 2.13.5, 2.13.6 Feb 9, 2021
@dwijnand dwijnand modified the milestones: 2.13.6, 2.13.7 May 10, 2021
@SethTisue SethTisue modified the milestones: 2.13.7, 2.13.8 Oct 21, 2021
@SethTisue SethTisue modified the milestones: 2.13.8, 2.13.9 Dec 15, 2021
@SethTisue SethTisue modified the milestones: 2.13.9, 2.13.10 Apr 25, 2022
@SethTisue SethTisue removed this from the 2.13.10 milestone Sep 23, 2022
@SethTisue SethTisue added this to the Backlog milestone Sep 23, 2022
@SethTisue SethTisue removed their assignment Sep 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants