diff options
author | Martin Odersky <odersky@gmail.com> | 2014-10-11 14:09:08 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-10-12 10:46:57 +0200 |
commit | 35f46b4a0c2d290582981f67498ed77a4ae9b21d (patch) | |
tree | e5e16958d020e76196c773e103d5a80a8cca8613 /src/dotty/tools/dotc/transform/ElimByName.scala | |
parent | f3d42cd1358ef6d317a6adb4ae4fc9a28cc01c7e (diff) | |
download | dotty-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.scala | 23 |
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) } |