Skip to content

Fix #3823: Unpickle type holes #3833

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

Merged
merged 4 commits into from
Jan 17, 2018
Merged

Conversation

nicolasstucki
Copy link
Contributor

No description provided.

@@ -136,7 +136,7 @@ class ReifyQuotes extends MacroTransform {
else {
val trefs = importedTypes.toList
val typeDefs = for (tref <- trefs) yield {
val tag = New(defn.QuotedTypeType.appliedTo(tref), Nil)
val tag = New(defn.QuotedTypeType.appliedTo(tref), Nil) // FIXME: should be an implicitly inferred defn.QuotedTypeType.appliedTo(tref)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@odersky could you have a look at this one. I did not manage to use the MacroTransformWithImplicits and inferImplicitArg to get the implicit argument. I looked at b466e0a but it might be too outdated.

@nicolasstucki nicolasstucki added this to the 0.6 Tech Preview milestone Jan 16, 2018
def main(args: Array[String]): Unit = {
def f[T](x: Expr[T])(implicit t: Type[T]) = '{
val z = ~x
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This quote will be pickled as

type T = [[1| ]]
{
  val z: T = [[0| ]]
  ()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After ReifyQuotes the tree is

package <empty> {
  import dotty.tools.dotc.quoted.Runners._
  import scala.quoted._
  final lazy module val Test: Test$ = new Test$()
  @scala.annotation.internal.SourceFile("Foo.scala") final module class Test$()
     extends
   Object() { this: Test.type => 
    def main(args: Array[String]): Unit = 
      {
        def f[T >: Nothing <: Any](x: quoted.Expr[T])(implicit t: quoted.Type[T]
          )
        : scala.quoted.Expr[Unit] = 
          scala.runtime.quoted.Unpickler.unpickleExpr[Unit](
            scala.collection.immutable.Nil.::[String](
              
                "\\¡«\037\0203\0200\00\00\00\00\00\00\00\00\00\00\00\00\016\02M0£\01\0204ASTs\01\0206_root_\01\0201\'\01\0203Any\01\0205scala\01\0201z\01\0201T\020\0200¢6\0201\0201\0236\0202u\02036\0204\0214\0226\0214\0211\02\0201\0206\02055\0230ÿ\0201\0200\0203\0211\020\0205ÿ\0201\02012\0235\025\025"
              
            )
          , [x,new scala.quoted.Type[T]() : Any])
        println(
          f[Int](
            scala.runtime.quoted.Unpickler.unpickleExpr[Int](
              scala.collection.immutable.Nil.::[String](
                
                  "\\¡«\037\0203\0200\00\00\00\00\00\00\00\00\00\00\00\00\n%fð\0235\01\0204ASTs\01\0206_root_\01\0201\'\01\0203Any\01\0205scala\0200\0216\0200\02146\0201\0201\0210\0202u\02036\0204<\0202\025"
                
              )
            , [ : Any])
          )(quoted.Type.IntTag).show(
            dotty.tools.dotc.quoted.Runners.runner[Unit]
          )
        )
      }
  }
}

Note that the arguments for the holes are x and new scala.quoted.Type[T]() hence when unpickling we get an instance of scala.quoted.Type with an erased T. Instead of new scala.quoted.Type[T]() we should have t.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have

def f[T](x: Expr[T])(implicit t: Type[T]) = '{
   val z: ~t= ~x
}

then the hole receives the t and works as expected.

Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM

case PackageDef(_, (vdef: ValDef) :: Nil) => vdef.rhs
case PackageDef(_, (tdef: TypeDef) :: Nil) => tdef.rhs
case PackageDef(_, (vdef: ValDef) :: Nil) =>
if (vdef.name == "quote".toTermName) vdef.rhs
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a dollar to the name? It's unambiguous now, but if we sometimes in the future would add toplevel ValDefs to Scala someone could write val quote = ....

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be safe as this will only be contained in expressions Expr[T] and expressions do not have packages (hence not top level vals). Regardless the name with $ is better as it shows that it is a synthetic construct.

* or
* `<type tree>` ==> `package _root_ { type ' = <tree tree> }`
* `<type tree>` ==> `package _root_ { val typeQuote: Any = null.asInstanceOf[<tree>] }`
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, probably safer to write e.g. $typeQuote.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants