diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-05 10:52:13 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-05 17:20:56 +0200 |
commit | a326e86d7d8389e8049a77b2cd75458f4573e294 (patch) | |
tree | c1daf83a17f692a722bf03eea84b8fb429e4579d /src/dotty/tools/dotc/typer/Typer.scala | |
parent | dbb4b3f7923427af4ba6e04f258309421d5ee1ab (diff) | |
download | dotty-a326e86d7d8389e8049a77b2cd75458f4573e294.tar.gz dotty-a326e86d7d8389e8049a77b2cd75458f4573e294.tar.bz2 dotty-a326e86d7d8389e8049a77b2cd75458f4573e294.zip |
Type checking function trees and closures.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index ffd4b2ce1..ea1fa3729 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -412,38 +412,36 @@ class Typer extends Namer with Applications with Implicits { val protoFormals: List[Type] = pt match { case _ if pt.typeSymbol == defn.FunctionClass(params.length) => pt.typeArgs take params.length - case MethodType(_, paramTypes) => + case SAMType(meth) => + val MethodType(_, paramTypes) = meth.info paramTypes case _ => params map Function.const(WildcardType) } - val inferredParams = - for ((param, formal) <- (params, protoFormals).zipped) - if (param.tpt.isEmpty && isFullyDefined(formal)) - cpy.ValDef(param, param.mods, param.name, untpd.TypeTree(formal), param.rhs) - else - param - - ??? + val inferredParams: List[untpd.ValDef] = + for ((param, formal) <- params zip protoFormals) yield + if (!param.tpt.isEmpty) param + else { + val paramType = + if (isFullyDefined(formal)) formal + else errorType(s"missing parameter type", param.pos) + cpy.ValDef(param, param.mods, param.name, untpd.TypeTree(paramType), param.rhs) + } + typed(desugar.makeClosure(inferredParams, tree.body), pt) } def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context) = { val env1 = tree.env map (typed(_)) val meth1 = typed(tree.meth) - pt match { - case SAMType(meth) if !defn.isFunctionType(pt) => - ??? - case _ => - val ownType = meth1.tpe.widen match { - case mt: MethodType if !mt.isDependent => - closureType(mt) - case mt: MethodType => - errorType(s"cannot turn dependent method types into closures", tree.pos) - case tp => - errorType(s"internal error: closing over non-method $tp", tree.pos) - } - cpy.Closure(tree, env1, meth1).withType(ownType) + val ownType = meth1.tpe.widen match { + case mt: MethodType if !mt.isDependent => + mt.toFunctionType + case mt: MethodType => + errorType(s"internal error: cannot turn dependent method type $mt into closure", tree.pos) + case tp => + errorType(s"internal error: closing over non-method $tp", tree.pos) } + cpy.Closure(tree, env1, meth1, EmptyTree).withType(ownType) } def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = { @@ -704,6 +702,17 @@ class Typer extends Namer with Applications with Implicits { if (ctx.mode.isExpr) { if (pt.typeSymbol == defn.UnitClass) return tpd.Block(tree :: Nil, Literal(Constant())) + tree match { + case Closure(Nil, id @ Ident(nme.ANON_FUN), _) + if defn.isFunctionType(tree.tpe) && !defn.isFunctionType(pt) => + pt match { + case SAMType(meth) + if tree.tpe <:< meth.info.toFunctionType && isFullyDefined(pt, forceIt = false) => + return cpy.Closure(tree, Nil, id, TypeTree(pt)).withType(pt) + case _ => + } + case _ => + } val adapted = inferView(tree, pt) if (adapted ne EmptyTree) return adapted } |