aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ElimByName.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-10-11 14:09:08 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-10-12 10:46:57 +0200
commit35f46b4a0c2d290582981f67498ed77a4ae9b21d (patch)
treee5e16958d020e76196c773e103d5a80a8cca8613 /src/dotty/tools/dotc/transform/ElimByName.scala
parentf3d42cd1358ef6d317a6adb4ae4fc9a28cc01c7e (diff)
downloaddotty-35f46b4a0c2d290582981f67498ed77a4ae9b21d.tar.gz
dotty-35f46b4a0c2d290582981f67498ed77a4ae9b21d.tar.bz2
dotty-35f46b4a0c2d290582981f67498ed77a4ae9b21d.zip
ElimByName now handles casts to by-name-parameter TermRefs
A cast like expr.asInstanceOf[x.type] where x is a by-name parameter has to be mapped to expr.asInstanceOf[x.type].apply() See pos/t296.scala which would otherwise start failing when the pattern matcher is integrated.
Diffstat (limited to 'src/dotty/tools/dotc/transform/ElimByName.scala')
-rw-r--r--src/dotty/tools/dotc/transform/ElimByName.scala23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimByName.scala b/src/dotty/tools/dotc/transform/ElimByName.scala
index e656c8438..1d0307398 100644
--- a/src/dotty/tools/dotc/transform/ElimByName.scala
+++ b/src/dotty/tools/dotc/transform/ElimByName.scala
@@ -76,16 +76,29 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
cpy.Apply(tree)(tree.fun, args1)
}
- private def becomesFunction(symd: SymDenotation)(implicit ctx: Context) =
+ /** If denotation had an ExprType before, it now gets a function type */
+ private def exprBecomesFunction(symd: SymDenotation)(implicit ctx: Context) =
(symd is Param) || (symd is (ParamAccessor, butNot = Method))
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree = {
- val origDenot = originalDenotation(tree)
- if (becomesFunction(origDenot) && (origDenot.info.isInstanceOf[ExprType]))
+ /** Map `tree` to `tree.apply()` is `ftree` was of ExprType and becomes now a function */
+ private def applyIfFunction(tree: Tree, ftree: Tree)(implicit ctx: Context) = {
+ val origDenot = originalDenotation(ftree)
+ if (exprBecomesFunction(origDenot) && (origDenot.info.isInstanceOf[ExprType]))
tree.select(defn.Function0_apply).appliedToNone
else tree
}
+ override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ applyIfFunction(tree, tree)
+
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ case TypeApply(Select(_, nme.asInstanceOf_), arg :: Nil) =>
+ // tree might be of form e.asInstanceOf[x.type] where x becomes a function.
+ // See pos/t296.scala
+ applyIfFunction(tree, arg)
+ case _ => tree
+ }
+
def elimByNameParams(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: PolyType =>
tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimByNameParams(tp.resultType))
@@ -102,6 +115,6 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
}
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type =
- if (becomesFunction(sym)) transformParamInfo(tp)
+ if (exprBecomesFunction(sym)) transformParamInfo(tp)
else elimByNameParams(tp)
}