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

incorrect reification for pattern matching anonymous partial function #6619

Open
scabug opened this issue Nov 6, 2012 · 7 comments
Open
Milestone

Comments

@scabug
Copy link

scabug commented Nov 6, 2012

Given:

scala> val cm = reflect.runtime.currentMirror
cm: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@569083c1 of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)] and parent being scala.tools.nsc.util.ScalaClassLoader$URLClassLoader@29ba204d of type class scala.tools.nsc.util.ScalaClassLoader$URLClassLoader with classpath [file:/Library/Java/JavaVirtualMachines/1.6.0_37-b06-434.jdk/Contents/Classes/classes.jar,file:/Library/Java/JavaVirtualMachines/1.6.0_37-b06-434.jdk/Contents/Classes/ui.jar,file:/Library/Java/JavaVirtualMachines/1.6.0_37-b06-434.jdk/Contents/Classes/jsse.jar,file:/Library/Java/JavaVirtualMachines/1.6.0_37-b06-434.jdk/Contents/Classes/jce.jar,file:/Library/Java/JavaVirtualMachines/1.6.0_37-b06-434.jdk/Contents/Class...
scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> val tb = cm.mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@7f5d84e0

This works:

scala> val tree = cm.universe.reify { { case 0 => 0 }: Function[Int, Int] }.tree
tree: cm.universe.Tree = 
(((x0$1) => x0$1 match {
  case 0 => 0
}): Function[Int, Int])

scala> tb.compile(tree)
res17: () => Any = <function0>

But this doesn't:

scala> val tree = cm.universe.reify { { case 0 => 0 }: PartialFunction[Int, Int] }.tree
tree: cm.universe.Tree = 
({
  final <synthetic> class $anonfun extends  {
    def <init>() = {
      super.<init>();
      ()
    };
    final override def applyOrElse[A1, B1](x$1, default) = x$1: @unchecked match {
      case 0 => 0
    };
    final def isDefinedAt(x$1) = x$1: @unchecked match {
      case 0 => true
    }
  };
  new <type ?>()
}: PartialFunction[Int, Int])
       

scala> 
       tb.compile(tree)
scala.tools.reflect.ToolBoxError: reflective compilation has failed: 

missing parameter type
class Any is abstract; cannot be instantiated
	at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:318)
	at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:251)
	at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:415)
	at .<init>(<console>:12)
	at .<clinit>(<console>)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)
@scabug
Copy link
Author

scabug commented Nov 6, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6619?orig=1
Reporter: @retronym
Affected Versions: 2.10.0-RC1

@scabug
Copy link
Author

scabug commented Nov 6, 2012

@retronym said (edited on Nov 6, 2012 9:43:13 AM UTC):
Actually, the problem is somewhere reify. I'll bet this is a duplicate of another "cannot reify ..." bug, but I can't find the one.

{
  final <synthetic> class $anonfun extends  {
    def <init>(): anonymous class $anonfun = {
      $anonfun.super.<init>();
      ()
    };
    final override private def applyOrElse[A1 >: Any <: Any, B1 >: Any <: Any](x$1: <error>, default: <error>): Any = x$1: @unchecked match {
      case (x @ _) => x
    };
    final private def isDefinedAt(x$1: <error>): Boolean = x$1: @unchecked match {
      case (x @ _) => true
    }
  };
  new Any()
}
{
  val $u: Test.this.cm.universe.type = Test.this.cm.universe;
  val $m: $u.Mirror = Test.this.cm.universe.runtimeMirror(this.getClass.getClassLoader);
  $u.Expr.apply[PartialFunction[Int,Int]]($m, {
    final class $treecreator1 extends TreeCreator {
      def <init>() = {
        super.<init>();
        ()
      };
      def apply[U >: Nothing <: Universe with Singleton]($m$untyped: Mirror[U]): U#Tree = {
        val $u: U = $m$untyped.universe;
        val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
        $u.Typed($u.Typed($u.Block(scala.collection.immutable.List.apply($u.ClassDef($u.Modifiers($u.build.flagsFromBits(2097184L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTypeName("$anonfun"), scala.collection.immutable.List.apply(), $u.Template(scala.collection.immutable.List.apply(), $u.build.emptyValDef, scala.collection.immutable.List.apply($u.DefDef($u.Modifiers($u.build.flagsFromBits(0L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("<init>"), scala.collection.immutable.List.apply(), scala.collection.immutable.List.apply(scala.collection.immutable.List.apply()), $u.TypeTree(), $u.Block(scala.collection.immutable.List.apply($u.Apply($u.Select($u.Super($u.This($u.newTypeName("")), $u.newTypeName("")), $u.newTermName("<init>")), scala.collection.immutable.List.apply())), $u.Literal($u.Constant(())))), $u.DefDef($u.Modifiers($u.build.flagsFromBits(98L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("applyOrElse"), scala.collection.immutable.List.apply($u.TypeDef($u.Modifiers($u.build.flagsFromBits(8208L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTypeName("A1"), scala.collection.immutable.List.apply(), $u.TypeBoundsTree($u.TypeTree(), $u.TypeTree())), $u.TypeDef($u.Modifiers($u.build.flagsFromBits(8208L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTypeName("B1"), scala.collection.immutable.List.apply(), $u.TypeBoundsTree($u.TypeTree(), $u.TypeTree()))), scala.collection.immutable.List.apply(scala.collection.immutable.List.apply($u.ValDef($u.Modifiers($u.build.flagsFromBits(17592188149760L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("x$1"), $u.TypeTree(), $u.EmptyTree), $u.ValDef($u.Modifiers($u.build.flagsFromBits(2105344L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("default"), $u.TypeTree(), $u.EmptyTree))), $u.TypeTree(), $u.Match($u.Annotated($u.Apply($u.Select($u.New($u.build.Ident($m.staticClass("scala.unchecked"))), $u.newTermName("<init>")), scala.collection.immutable.List.apply()), $u.Ident($u.newTermName("x$1"))), scala.collection.immutable.List.apply($u.CaseDef($u.Bind($u.newTermName("x"), $u.Ident($u.newTermName("_"))), $u.EmptyTree, $u.Ident($u.newTermName("x")))))), $u.DefDef($u.Modifiers($u.build.flagsFromBits(96L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("isDefinedAt"), scala.collection.immutable.List.apply(), scala.collection.immutable.List.apply(scala.collection.immutable.List.apply($u.ValDef($u.Modifiers($u.build.flagsFromBits(17592188149760L), $u.newTypeName(""), scala.collection.immutable.List.apply()), $u.newTermName("x$1"), $u.TypeTree(), $u.EmptyTree))), $u.TypeTree(), $u.Match($u.Annotated($u.Apply($u.Select($u.New($u.build.Ident($m.staticClass("scala.unchecked"))), $u.newTermName("<init>")), scala.collection.immutable.List.apply()), $u.Ident($u.newTermName("x$1"))), scala.collection.immutable.List.apply($u.CaseDef($u.Bind($u.newTermName("x"), $u.Ident($u.newTermName("_"))), $u.EmptyTree, $u.Literal($u.Constant(true)))))))))), $u.Apply($u.Select($u.New($u.TypeTree()), $u.newTermName("<init>")), scala.collection.immutable.List.apply())), $u.TypeTree()), $u.AppliedTypeTree($u.build.Ident($m.staticClass("scala.PartialFunction")), scala.collection.immutable.List.apply($u.build.Ident($m.staticClass("scala.Int")), $u.build.Ident($m.staticClass("scala.Int")))))
      }
    };
    new $treecreator1()
  })($u.TypeTag.apply[PartialFunction[Int,Int]]($m, {
    final class $typecreator2 extends TypeCreator {
      def <init>() = {
        super.<init>();
        ()
      };
      def apply[U >: Nothing <: Universe with Singleton]($m$untyped: Mirror[U]): U#Type = {
        val $u: U = $m$untyped.universe;
        val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
        $u.TypeRef($u.ThisType($m.staticPackage("scala").asModule.moduleClass), $m.staticClass("scala.PartialFunction"), scala.collection.immutable.List.apply($m.staticClass("scala.Int").asType.toTypeConstructor, $m.staticClass("scala.Int").asType.toTypeConstructor))
      }
    };
    new $typecreator2()
  }))
}

@scabug
Copy link
Author

scabug commented Nov 6, 2012

@adriaanm said:
looks like the patmat phase hasn't run, right?

@scabug
Copy link
Author

scabug commented Nov 6, 2012

@adriaanm said:
there might be an issue where patmat checks it's not running after uncurry

@scabug
Copy link
Author

scabug commented Nov 6, 2012

@xeno-by said:
Actually I'm a bit unsettled about the x$1: <error> part

@scabug
Copy link
Author

scabug commented Dec 2, 2012

@xeno-by said:
Duplicate of #6187

@scabug
Copy link
Author

scabug commented Jul 15, 2013

Olivier Chafik (ochafik) said (edited on Jul 15, 2013 1:37:59 PM UTC):
Reopening because this is still broken in 2.11.0-M4, and it is not really a duplicate of #6187 (which fix states that "we are not able to reify partial functions yet":
scala/scala#2011).

The issue here is the parent class (AbstractPartialFunction[A, B]) that disappears in the class definition of the reified partial class (or maybe the fact that that class is synthesized instead of keeping the Match in the reified tree, I have no clue which is best).

Quick way to reproduce:

scala
:power
reify({ case 0 => 0 }: Function1[Int, Int])
reify({ case 0 => 0 }: PartialFunction[Int, Int])

@scabug scabug added this to the Backlog milestone Apr 7, 2017
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

2 participants