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

Allow using classOf with object type #9279

Merged
merged 1 commit into from Nov 10, 2020

Conversation

octonato
Copy link
Contributor

@octonato octonato commented Oct 26, 2020

This is a fix for scala/bug#2453.

It makes it possible to write the following:

object Bar 

val cls = classOf[Bar.type]

@scala-jenkins scala-jenkins added this to the 2.13.5 milestone Oct 26, 2020
@SethTisue
Copy link
Member

(iirc there is a passage in the spec that will need to be updated)

@SethTisue

This comment has been minimized.

@SethTisue
Copy link
Member

@odersky you aren't opposed to this on principle, by any chance?

Copy link
Contributor Author

@octonato octonato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left I few comments to motivate the change.

@@ -4752,7 +4752,7 @@ trait Types
/** def isNonValueType(tp: Type) = !isValueElseNonValue(tp) */

def isNonRefinementClassType(tpe: Type) = tpe match {
case SingleType(_, sym) => sym.isModuleClass
case SingleType(_, sym) => sym.isModuleOrModuleClass
Copy link
Contributor Author

@octonato octonato Oct 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the end, this seems to be suspiciously simple fix. Not sure if that has other implications though.

Comment on lines +4 to +7
trait Foo {
@AnnotationWithClassType(cls = classOf[Bar.type])
def function: Any = ???
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this compile test because the issue shows up when using a Java annotation that requires a class. But of course, the impl allows many other usages.

When I faced that issue for the first time, I tried to used it as follows:

trait Foo {
  @AnnotationWithClassType(cls = Bar.getClass)
  def function: Any = ???
}

which gives the following error:

Foo.scala:5: error: annotation argument needs to be a constant; found: Bar.getClass()
  @AnnotationWithClassType(cls = Bar.getClass)

@octonato

This comment has been minimized.

@octonato

This comment has been minimized.

@som-snytt
Copy link
Contributor

som-snytt commented Oct 26, 2020

How about classOf[23], who are second-year students now?

I just worked around this:

scala> object X
object X

scala> classOf[X.type]
                ^
       error: class type required but X.type found

scala> def f[A: reflect.ClassTag] = implicitly[reflect.ClassTag[A]].runtimeClass
def f[A](implicit evidence$1: scala.reflect.ClassTag[A]): Class[_]

scala> f[X.type]
val res1: Class[_] = class X$

Edit: I see the macro version in the linked ticket.

@SethTisue SethTisue added the release-notes worth highlighting in next release notes label Oct 26, 2020
@dwijnand
Copy link
Member

@octonato
Copy link
Contributor Author

def f[A: reflect.ClassTag] = implicitly[reflect.ClassTag[A]].runtimeClass

This won't work with Java annotation for the same reason that @AnnotationWithClassType(cls = Bar.getClass) doesn't work.

object Bar

object Companion {
  def classOf[A: reflect.ClassTag] = implicitly[reflect.ClassTag[A]].runtimeClass
}

trait Foo {
  @AnnotationWithClassType(cls = Companion.classOf[Bar.type])
  def function: Any = ???
}

gives:

Foo.scala:9: error: annotation argument needs to be a constant; found: Companion.classOf[Bar.type]((ClassTag.apply[Bar.type](classOf[Bar$]): scala.reflect.ClassTag[Bar.type]))
  @AnnotationWithClassType(cls = Companion.classOf[Bar.type])

Copy link
Member

@dwijnand dwijnand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So short and sweet!

Making isNonRefinementClassType return true for SingleType's of module symbols doesn't sound like a problem to me. Hopefully it's good for the test suite too. Needs a rebase on #9046 #9280 (or 2.13.x once that's merged).

@octonato
Copy link
Contributor Author

I don't get why it needs a rebase on #9046. Did you pasted here the right issue number?

Btw, the tests are failing for an unrelated compilation issue.

[error] /home/travis/build/scala/scala/src/compiler/scala/tools/nsc/transform/Constructors.scala:477:25: Unused import
[error]       import scala.util.Try
[error]                         ^
[error] one error found
[error] (compiler / Compile / compileIncremental) Compilation failed

Is 2.13.x branch broken? Or maybe your intention was to link here the PR that fix 2.13 branch?

@octonato
Copy link
Contributor Author

I guess this was the PR you wanted to link: #9280

@octonato
Copy link
Contributor Author

@dwijnand, this is rebased with #9280.
Let's what TravisCI will tell us.

@octonato
Copy link
Contributor Author

TravisCI failed with some other unrelated reason. I will try again in a few days (after rebasing on 2.13).

Also, before adding more time on this, I would like to know if the solution is sound.

@dwijnand
Copy link
Member

Also, before adding more time on this, I would like to know if the solution is sound.

It looks good to me, so it has a reasonable chance to be merged.

@SethTisue
Copy link
Member

SethTisue commented Nov 9, 2020

codewise LGTM but I need to dig deeper into whether a spec change is needed. will do soon nah, spec is fine

@smarter any objection to making the corresponding change to Scala 3?

@smarter
Copy link
Member

smarter commented Nov 9, 2020

It already works in dotty :).

@SethTisue SethTisue modified the milestones: 2.13.5, 2.13.4 Nov 9, 2020
@SethTisue SethTisue self-assigned this Nov 9, 2020
@SethTisue SethTisue merged commit 53bb32b into scala:2.13.x Nov 10, 2020
@SethTisue
Copy link
Member

SethTisue commented Nov 10, 2020

thank you Renato!

you get a special prize for closing such a low bug number! (*)

(* there is no actual prize)

@octonato octonato deleted the rgc/fix-classOf-object branch November 10, 2020 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-notes worth highlighting in next release notes
Projects
None yet
6 participants