Re: [macros] untypecheck seems to produce invalid code
Stefan Ollinger <[email protected]>
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <[email protected]> |
Here is another issue:
import scala.reflect.runtime.universe._
import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
def fooImpl(c: Context)(expr: c.Expr[Any]) = {
import c.universe._
val untypedExpr = c.Expr[Any](c.untypecheck(expr.tree.duplicate))
println(expr)
// Expr[Nothing]((({
// @SerialVersionUID(0) final <synthetic> class $anonfun extends
scala.runtime.AbstractPartialFunction[Any,Any] with Serializable {
// def <init>(): <$anon: Any => Any> = {
// $anonfun.super.<init>();
// ()
// };
// final override def applyOrElse[A1, B1 >: Any](x1: A1, default: A1
=> B1): B1 = ((x1.asInstanceOf[Any]: Any): Any @unchecked) match {
// case scala.util.control.NonFatal.unapply(<unapply-selector>)
<unapply> ((e @ _)) => ()
// case (defaultCase$ @ _) => default.apply(x1)
// };
// final def isDefinedAt(x1: Any): Boolean = ((x1.asInstanceOf[Any]:
Any): Any @unchecked) match {
// case scala.util.control.NonFatal.unapply(<unapply-selector>)
<unapply> ((e @ _)) => true
// case (defaultCase$ @ _) => false
// }
// };
// new $anonfun()
// }: PartialFunction[Any,Any]): PartialFunction[Any,Any]))
println(untypedExpr)
// Expr[Any]((({
// final <synthetic> class $anonfun extends
scala.runtime.AbstractPartialFunction[Any,Any] with Serializable {
// def <init>() = {
// super.<init>();
// ()
// };
// final override def applyOrElse[A1, B1 >: Any](x1: A1, default:
scala.this.Function1[A1, B1]) = ((x1.asInstanceOf[Any]: Any):
(x1.asInstanceOf[Any]: Any): @scala.unchecked) match {
// case scala.util.control.NonFatal.unapply(<unapply-selector>)
<unapply> ((e @ _)) => ()
// case (defaultCase$ @ _) => default.apply(x1)
// };
// final def isDefinedAt(x1: Any): Boolean = ((x1.asInstanceOf[Any]:
Any): (x1.asInstanceOf[Any]: Any): @scala.unchecked) match {
// case scala.util.control.NonFatal.unapply(<unapply-selector>)
<unapply> ((e @ _)) => true
// case (defaultCase$ @ _) => false
// }
// };
// new $anonfun()
// }: PartialFunction[Any,Any]): scala.PartialFunction[scala.Any,
scala.Any]))
untypedExpr
}
def foo(expr: => Any): Any = macro fooImpl
foo { ({ case scala.util.control.NonFatal(e) => }):PartialFunction[Any,
Any] }
// ReplGlobal.abort: unexpected UnApply
scala.util.control.NonFatal.unapply(<unapply-selector>) <unapply> ((e @ _))
//
// error: unexpected UnApply
scala.util.control.NonFatal.unapply(<unapply-selector>) <unapply> ((e @ _))
// scala.reflect.internal.FatalError: unexpected UnApply
scala.util.control.NonFatal.unapply(<unapply-selector>) <unapply> ((e @ _))
// at scala.reflect.internal.Reporting$class.abort(Reporting.scala:59)
// at
scala.tools.nsc.interpreter.IMain$$anon$1.scala$tools$nsc$interpreter$ReplGlobal$$super$abort(IMain.scala:237)
// at
scala.tools.nsc.interpreter.ReplGlobal$class.abort(ReplGlobal.scala:20)
// at scala.tools.nsc.interpreter.IMain$$anon$1.abort(IMain.scala:237)
// at
scala.tools.nsc.typechecker.Typers$Typer.typedInAnyMode$1(Typers.scala:5247)
// at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5259)
// at
scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5295)
// at
scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5322)
// at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5269)
// at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5273)
// at
scala.tools.nsc.interpreter.ReplGlobal$$anon$1$$anon$2.typed(ReplGlobal.scala:36)
// at
scala.tools.nsc.typechecker.Typers$Typer$$anonfun$113$$anonfun$apply$55.apply(Typers.scala:5408)
// at
scala.tools.nsc.typechecker.Typers$Typer$$anonfun$113.apply(Typers.scala:5408)
// at
scala.tools.nsc.typechecker.Typers$Typer$$anonfun$113.apply(Typers.scala:5408)
// at
scala.tools.nsc.typechecker.TypeDiagnostics$class.typingInPattern(TypeDiagnostics.scala:62)
// at
scala.tools.nsc.interpreter.ReplGlobal$$anon$1.typingInPattern(ReplGlobal.scala:23)
// at
scala.tools.nsc.typechecker.Typers$Typer.typedPattern(Typers.scala:5408)
// at
scala.tools.nsc.typechecker.Typers$Typer.typedCase(Typers.scala:2359)
// at
scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedCases$1.apply(Typers.scala:2399)
// at
scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedCases$1.apply(Typers.scala:2398)
// at scala.collection.immutable.List.loop$1(List.scala:172)
// at scala.collection.immutable.List.mapConserve(List.scala:188)
// at
scala.tools.nsc.typechecker.Typers$Typer.typedCases(Typers.scala:2398)
// ...
//
// That entry seems to have slain the compiler. Shall I replay
// your session? I can re-run each line except the last one.
Am Montag, 15. Juni 2015 15:59:37 UTC+2 schrieb Stefan Ollinger:
>
> Hey,
>
> See attached example. Is that a known bug or am I doing something wrong?
>
> Regards,
> Stefan
>
> ------
>
> import scala.reflect.runtime.universe._
> import scala.reflect.macros.blackbox.Context
> import scala.language.experimental.macros
>
> abstract class A {
> val is: Int
> }
>
> def fooImpl(c: Context)(expr: c.Expr[Any]) = {
> import c.universe._
>
> println(expr)
> // Expr[Nothing]({
> // final class $anon extends $line22.$read.$iw.$iw.$iw.$iw.$iw.$iw.A {
> // def <init>(): <$anon: A> = {
> // $anon.super.<init>();
> // ()
> // };
> // private[this] val is: Int = 100;
> // override <stable> <accessor> def is: Int = $anon.this.is
> // };
> // new $anon()
> // })
>
> val untypedExpr = c.Expr[Any](c.untypecheck(expr.tree.duplicate))
>
> println(untypedExpr) // this is invalid: override private[this] val is = 100;
> // Expr[Any]({
> // final class $anon extends $line22.$read.$iw.$iw.$iw.$iw.$iw.$iw.A {
> // def <init>() = {
> // super.<init>();
> // ()
> // };
> // override private[this] val is = 100;
> // override <stable> <accessor> def is: Int = $anon.this.is
> // };
> // new $anon()
> // })
>
> untypedExpr
> }
>
> def foo(expr: => Any): Any = macro fooImpl
>
> // 1. this does not work
> foo {
> new A {
> override val is = 100
> }
> }
>
> // <console>:18: error: value is overrides nothing
> // override val is = 100
>
> // 2. this works
> val tree = reify {
> new A {
> override val is = 100
> }
> }
>
> // tree: reflect.runtime.universe.Expr[A] =
> // Expr[A]({
> // final class $anon extends $read.A {
> // def <init>() = {
> // super.<init>();
> // ()
> // };
> // override val is = 100
> // };
> // new $anon()
> // })
>
>
--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.