Closed
Description
The following macro definition and usage shows a problematic interaction between resetLocalAttrs and partial functions.
Usage:
def m[T](t: T): List[List[T]] =
demo( List((t,true)) collect { case (x,true) => x } )
Definition:
def demo[T](t: T): List[T] = macro macroImpl[T]
def macroImpl[T: c.AbsTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] =
{
val r = c.universe.reify { List(t.splice) }
c.Expr[List[T]]( c.resetLocalAttrs(r.tree) )
}
The error is:
class Any is abstract; cannot be instantiated
demo( List((t,true)) collect { case (x,true) => x })
^
The tree before and after calling resetLocalAttrs:
Before:
immutable.this.List.apply(immutable.this.List.apply[(T, Boolean)](scala.Tuple2.apply[T, Boolean](t, true)).collect[T, List[T]]({
@SerialVersionUID(0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[(T, Boolean),T] with Serializable {
def <init>(): anonymous class $anonfun = {
$anonfun.super.<init>();
()
};
final override def applyOrElse[A1 >: Nothing <: (T, Boolean), B1 >: T <: Any](x$1: A1, default: A1 => B1): B1 = (x$1: A1 @unchecked) match {
case (_1: T, _2: Boolean)(T, Boolean)((x @ _), true) => x
};
final def isDefinedAt(x$1: (T, Boolean)): Boolean = (x$1: (T, Boolean) @unchecked) match {
case (_1: T, _2: Boolean)(T, Boolean)((x @ _), true) => true
}
};
new anonymous class $anonfun()
})(immutable.this.List.canBuildFrom[T]))
After:
immutable.this.List.apply(immutable.this.List.apply[(T, Boolean)](scala.Tuple2.apply[T, Boolean](t, true)).collect[T, List[T]]({
final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[(T, Boolean),T] with Serializable {
def <init>() = {
super.<init>();
()
};
final override def applyOrElse[A1 <: (T, Boolean), B1 >: T](x$1, default) = (x$1: <type ?>) match {
case (_1: T, _2: Boolean)(T, Boolean)((x @ _), true) => x
};
final def isDefinedAt(x$1: (T, Boolean)): Boolean = (x$1: (T, Boolean) @unchecked) match {
case (_1: T, _2: Boolean)(T, Boolean)((x @ _), true) => true
}
};
new <type ?>()
})(immutable.this.List.canBuildFrom[T]))