From 8f3e32781e9112e1567b9a5a78c52acd55b3506a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 2 Mar 2015 14:52:16 +0100 Subject: Avoiding dependent method types in closures The previous logic for avoiding dependent method types in closures had a hole. The problem arose when the expected return type of a closure was a type variable. Then, the that type variable would be taken as the declared result type of the closure without (at first) checking the body. The type variable would not yet be bounded and therefore would not represent a dependent method type. Afterwards when typechecking the closure the type variable woul dbe bounded and instantiated. But at that time, all checking and possibly avoiding of depenencies has already happened. We solve the problem by typing the body of a closure during Namer whenever the expected type is not fully defined. Doing so uncovered a problem that anonymus function were seen as the target of returns (tehy shoul be skipped instead). Thsi problem is fixed by a patch to SymDenotations#isSourceMethod. --- src/dotty/tools/dotc/typer/Namer.scala | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Namer.scala') diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 8293b0239..947d46ee0 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -653,13 +653,20 @@ class Namer { typer: Typer => lhsType orElse WildcardType } } - - val pt = mdef.tpt match { - case _: untpd.DerivedTypeTree => WildcardType - case TypeTree(untpd.EmptyTree) => inferredType - case _ => WildcardType + + val tptProto = mdef.tpt match { + case _: untpd.DerivedTypeTree => + WildcardType + case TypeTree(untpd.EmptyTree) => + inferredType + case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) => + typedAheadExpr(mdef.rhs, tpt.tpe) + typr.println(i"determine closure result type to be ${tpt.tpe}") + WildcardType + case _ => + WildcardType } - paramFn(typedAheadType(mdef.tpt, pt).tpe) + paramFn(typedAheadType(mdef.tpt, tptProto).tpe) } /** The type signature of a DefDef with given symbol */ -- cgit v1.2.3