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

Cannot reference aliased imports #33

Open
smithjessk opened this issue Aug 11, 2016 · 3 comments
Open

Cannot reference aliased imports #33

smithjessk opened this issue Aug 11, 2016 · 3 comments

Comments

@smithjessk
Copy link
Collaborator

Commit: 51b6213

The following compiles and runs as expected:

import scala.collection.mutable.{ Seq => mSeq }
val collection = mSeq(1, 2, 3)
collection.update(2, 4)

However, canonicalization fails when an aliased import (e.g. mSeq) is referenced inside a coroutine body. For example, this snippet:

import org.coroutines._
import scala.collection.mutable.{ Seq => mSeq }
val c = coroutine { () => 
  val collection = mSeq(1, 2, 3)
  collection.update(2, 4)
}

produces this error:

error: exception during macro expansion:
scala.reflect.macros.TypecheckException: object mSeq is not a member of package scala.collection.mutable
    at scala.reflect.macros.contexts.Typers$$anonfun$typecheck$2$$anonfun$apply$1.apply(Typers.scala:34)
    at scala.reflect.macros.contexts.Typers$$anonfun$typecheck$2$$anonfun$apply$1.apply(Typers.scala:28)
    at scala.reflect.macros.contexts.Typers$$anonfun$3.apply(Typers.scala:24)
    at scala.reflect.macros.contexts.Typers$$anonfun$3.apply(Typers.scala:24)
    at scala.reflect.macros.contexts.Typers$$anonfun$withContext$1$1.apply(Typers.scala:25)
    at scala.reflect.macros.contexts.Typers$$anonfun$withContext$1$1.apply(Typers.scala:25)
    at scala.reflect.macros.contexts.Typers$$anonfun$1.apply(Typers.scala:23)
    at scala.reflect.macros.contexts.Typers$$anonfun$1.apply(Typers.scala:23)
    at scala.reflect.macros.contexts.Typers$class.withContext$1(Typers.scala:25)
    at scala.reflect.macros.contexts.Typers$$anonfun$typecheck$2.apply(Typers.scala:28)
    at scala.reflect.macros.contexts.Typers$$anonfun$typecheck$2.apply(Typers.scala:28)
    at scala.reflect.internal.Trees$class.wrappingIntoTerm(Trees.scala:1691)
    at scala.reflect.internal.SymbolTable.wrappingIntoTerm(SymbolTable.scala:16)
    at scala.reflect.macros.contexts.Typers$class.withWrapping$1(Typers.scala:26)
    at scala.reflect.macros.contexts.Typers$class.typecheck(Typers.scala:28)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
    at org.coroutines.AstCanonicalization$class.canonicalizeTree(AstCanonicalization.scala:453)
    at org.coroutines.Synthesizer.canonicalizeTree(Synthesizer.scala:15)
    at org.coroutines.Synthesizer.synthesize(Synthesizer.scala:310)
    at org.coroutines.Coroutine$.synthesize(Coroutine.scala:307)

       val c = coroutine { () =>

I will investigate this issue more.

@smithjessk
Copy link
Collaborator Author

smithjessk commented Aug 11, 2016

The same error occurs when the import statement is inside the coroutine body.

In both cases, untypedtaflambda becomes the following:

(() => {
  val x$macro$275 = scala.collection.mutable.mSeq;
  val x$macro$276 = x$macro$275.apply[Int](1, 2, 3);
  val collection = x$macro$276;
  val x$macro$277 = collection.update(2, 4);
  val x$macro$278 = collection.apply(0);
  val x$macro$279 = coroutines.this.`package`.yieldval[Int](x$macro$278);
  val x$macro$280 = collection.apply(1);
  val x$macro$281 = coroutines.this.`package`.yieldval[Int](x$macro$280);
  val x$macro$282 = collection.apply(2);
  val x$macro$283 = coroutines.this.`package`.yieldval[Int](x$macro$282);
  x$macro$283
})

Weirdly, the original body (with the import inside it) is

{
  import scala.collection.mutable.{Seq=>mSeq};
  val collection = scala.collection.mutable.Seq.apply[Int](1, 2, 3);
  collection.update(2, 4);
  coroutines.this.`package`.yieldval[Int](collection.apply(0));
  coroutines.this.`package`.yieldval[Int](collection.apply(1));
  coroutines.this.`package`.yieldval[Int](collection.apply(2))
}

scala.collection.mutable.Seq gets rewritten to scala.collection.mutable.mSeq.

@smithjessk
Copy link
Collaborator Author

smithjessk commented Aug 11, 2016

Inside the canonicalization case for selection, r == scala.collection.mutable and member == mSeq. The previous case matched was for the application of scala.collection.mutable.Seq.apply. Inside this case, r == scala.collection.mutable.Seq. Thus, the renaming of Seq to mSeq takes place in the deconstruction of the selection of Seq from scala.collection.mutable.

This is confirmed by seeing that tree == scala.collection.mutable.Seq. The problem is in the destructuring.

One fix for this problem is to maintain a map between aliased imports and their non-aliased equivalents. Whenever we see a selection that references an aliased import, we replace it with the equivalent.

I will also investigate the quasiquote guide to see if there is an approach that would not rename Seq to mSeq.

@axel22
Copy link
Member

axel22 commented Aug 14, 2016

Nice catch.
Unless you have a fix ready, I would not worry about this one now, as it's
not a common use-case.

On Thu, Aug 11, 2016 at 8:06 PM, Jess Smith [email protected]
wrote:

Inside the canonicalization case

val (rdecls, rident) = canonicalize(r)

for selection, r == scala.collection.mutable and member == mSeq. The previous
case
val (rdecls, rident) = canonicalize(r)

matched was for the application of scala.collection.mutable.Seq.apply.
Inside this case, r == scala.collection.mutable.Seq. Thus, the renaming
of Seq to mSeq takes place in the deconstruction
case q"$r.$member" if !tree.symbol.isPackage =>

of the selection of Seq from scala.collection.mutable.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#33 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJQ3lSJZve4mzBZuYNukOrohzn5VUwZks5qe2S0gaJpZM4JiPLN
.

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

No branches or pull requests

2 participants