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

Erase arguments of phantom type #2399

Merged

Conversation

nicolasstucki
Copy link
Contributor

This commit removes arguments and parameter of phantom type from all applications.
Arguments are evaluated before the application in case they have side effects.

def foo(i: Int, p: SomePhantom) = ???

foo(42, { println("hello"); getSomePhantom })

becomes

def foo(i: Int) = ???

val x$0 = 42
val x$1 = { println("hello"); getSomePhantom }
foo(x$0)

Note that now def foo(i: Int) and def foo(i: Int, p: SomePhantom) erase to the same signature.

Tests for this commit where added in Extra tests for Phantoms 1, they where back ported as the semantics and runtime is not affected.

@nicolasstucki nicolasstucki requested a review from odersky May 8, 2017 21:49
@nicolasstucki nicolasstucki force-pushed the implement-phantom-types-part-2 branch 6 times, most recently from bacfeba to de3a1c8 Compare May 18, 2017 11:50
@nicolasstucki nicolasstucki force-pushed the implement-phantom-types-part-2 branch from d273d89 to 2a25799 Compare June 1, 2017 06:49
@nicolasstucki nicolasstucki force-pushed the implement-phantom-types-part-2 branch from 2a25799 to e8fb429 Compare June 9, 2017 09:58
*
* - Parameters/arguments are erased to ErasedPhantom. The next step will remove the parameters
* from the method definitions and calls (implemented in branch implement-phantom-types-part-2).
* - Parameters/arguments are erased removed from the function definition/call in `PhantomArgumentEval`.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: erased removed

@@ -400,12 +400,15 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
case tp: MethodType =>
def paramErasure(tpToErase: Type) =
erasureFn(tp.isJava, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
val formals = tp.paramInfos.mapConserve(paramErasure)
val (names, formals0) =
if (tp.paramInfos.forall(!_.isPhantom)) (tp.paramNames, tp.paramInfos)
Copy link
Contributor

Choose a reason for hiding this comment

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

!tp.paramInfos.exists(_.isPhantom)

val formals = tp.paramInfos.mapConserve(paramErasure)
val (names, formals0) =
if (tp.paramInfos.forall(!_.isPhantom)) (tp.paramNames, tp.paramInfos)
else tp.paramNames.iterator.zip(tp.paramInfos.iterator).filterNot(_._2.isPhantom).toList.unzip
Copy link
Contributor

Choose a reason for hiding this comment

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

You can probably drop .iterator.

@@ -474,7 +477,7 @@ object Erasure extends TypeTestsCasts{
.withType(defn.ArrayOf(defn.ObjectType))
args0 = bunchedArgs :: Nil
}
val args1 = args0.zipWithConserve(mt.paramInfos)(typedExpr)
val args1 = args0.filterConserve(arg => !wasPhantom(arg.typeOpt)).zipWithConserve(mt.paramInfos)(typedExpr)
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a comment why we know that argument.isPhantom if and only if parameter.isPhantomj

}

/** Collects all args (and possibly the function) as synthetic vals and replaces them in the tree by the reference to
* the lifted its val.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo?

/* Tree transform */

override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = tree.tpe match {
case _: MethodType => tree // Do the transformation higher in the tree if needed
Copy link
Contributor

Choose a reason for hiding this comment

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

tree.tpe.widen

private def transformApplication(tree: Tree, mkTree: (Tree, List[ValDef]) => Tree)(implicit ctx: Context): Tree = tree match {
case tree: Apply =>
def mkNewApply(newFun: Tree, accSynthVals: List[ValDef]) = {
val (synthVals, synthValRefs) = tree.args.map(mkSynthVal).unzip
Copy link
Contributor

Choose a reason for hiding this comment

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

insert: .filterNot(tpd.isPureExpr)

case _ =>
def mkNewBlock(newApply: Tree, synthVals: List[ValDef]) = Block(synthVals, newApply)
if (!hasPhantomArgs(tree)) tree
else transformApplication(tree, mkNewBlock)
Copy link
Contributor

Choose a reason for hiding this comment

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

Change logic to:

  1. If function has impure phantom args, lift out all args using EtaExpansion.liftApp.

@nicolasstucki nicolasstucki force-pushed the implement-phantom-types-part-2 branch from 3802539 to 0975c68 Compare June 23, 2017 13:47
@nicolasstucki
Copy link
Contributor Author

All requested changes have been taken care of.

This commit removes arguments and parameter of phantom type from all applications.
Arguments are evaluated before the application in case they have side effects.

```
def foo(i: Int, p: SomePhantom) = ???

foo(42, { println("hello"); getSomePhantom })
```

becomes

```
def foo(i: Int) = ???

val x$0 = 42
val x$1 = { println("hello"); getSomePhantom }
foo(x$0)
```

Note that now `def foo(i: Int)` and def `foo(i: Int, p: SomePhantom)` erase to the same signature.

Tests for this commit where added in `Extra tests for Phantoms 1`, they where back ported as the semantics and runtime is not affected.
Phantom `var`s where disallowed.
@nicolasstucki nicolasstucki force-pushed the implement-phantom-types-part-2 branch from 0975c68 to 975cee5 Compare July 17, 2017 08:25
@nicolasstucki
Copy link
Contributor Author

Rebased

@nicolasstucki nicolasstucki merged commit d121ad5 into scala:master Jul 18, 2017
@nicolasstucki nicolasstucki mentioned this pull request Jul 20, 2017
@allanrenucci allanrenucci deleted the implement-phantom-types-part-2 branch December 14, 2017 19:23
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