scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Can't match classOf after typechecking with quasiquotes #8384

Closed scabug closed 6 years ago

scabug commented 10 years ago

Due to change in the shape of classOf tree after typechecking one can't match it:

scala> showRaw(q"classOf[Int]")
TypeApply(Ident(TermName("classOf")), List(Ident(TypeName("Int"))))

scala> showRaw(typecheck(q"classOf[Int]").sr)
Literal(Constant(Int))

We also can't really implement syntactic abstraction over this without referential transparency as untyped classOf tree might or might not become a type literal depending on definitions in scope:

scala> showRaw(typecheck(q"def classOf[T] = (); classOf[Int]"))
Block(List(
  DefDef(Modifiers(), TermName("classOf"), List(TypeDef(Modifiers(PARAM), TypeName("T"), List(), TypeTree().setOriginal(TypeBoundsTree(TypeTree(), TypeTree())))), List(), TypeTree(), Literal(Constant(())))), 
  TypeApply(Ident(TermName("classOf")), List(TypeTree().setOriginal(Select(Ident(scala), scala.Int)))))
scabug commented 10 years ago

Imported From: https://issues.scala-lang.org/browse/SI-8384?orig=1 Reporter: @densh Affected Versions: 2.11.0

scabug commented 10 years ago

@soc said: Would any of this be different if classOf was a macro?

scabug commented 10 years ago

@xeno-by said: Yes, I think so. We have MacroExpansionAttachment that allows us to correlate macro expansions and their originals, so we could theoretically pull this off.

Another question is whether we want quasiquotes to match originals or expansions. I can see arguments for both approaches. Denys, wdyt?

scabug commented 10 years ago

@densh said: Quasiquotes already match TypeTree originals albeit not consistently (plan to fix it soon).

I 'm not sure that matching macro originals by default is a good idea though.

scabug commented 10 years ago

@densh said: Workaround:

typecheck(q"classOf[Int]") match {
  case q"${const: Constant}" if const.value.isInstanceOf[Type] =>
  println(const.asInstanceOf[Type].value)
}
scabug commented 10 years ago

@soc said: What happens if classOf[X] doesn't result in a Constant?

scabug commented 10 years ago

@densh said: Can you give an example? I had an impression that it was always represented as constant.

SethTisue commented 6 years ago

closing all quasiquotes tickets; see https://github.com/scala/bug/issues/10755