summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-11-25 09:20:26 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-11-25 09:20:26 +0000
commitb059cbd155aec675b40a2a54f18bb127f17fcf37 (patch)
tree9d02d0067ac0b40518d24126e3cbd3eb68ea69cb /src
parent6f4a561df2973cd48241ff4389e3ddf137c141f5 (diff)
downloadscala-b059cbd155aec675b40a2a54f18bb127f17fcf37.tar.gz
scala-b059cbd155aec675b40a2a54f18bb127f17fcf37.tar.bz2
scala-b059cbd155aec675b40a2a54f18bb127f17fcf37.zip
closed #2624: instantiate type params after eta...
closed #2624: instantiate type params after eta expansion of polymorphic method does not blow the stack on pos/t0674 (previous private fix did typed(tree); instantiate(tree) instead of instantiate(typed(tree))) fixed check file for neg/bug608 -- got better error message
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
2 files changed, 17 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index d11f263677..f46043025a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -181,7 +181,7 @@ trait Infer {
case MethodType(params, restpe) if (!restpe.isDependent) =>
if (util.Statistics.enabled) normM += 1
functionType(params map (_.tpe), normalize(restpe))
- case PolyType(List(), restpe) =>
+ case PolyType(List(), restpe) => // nullary method type
if (util.Statistics.enabled) normP += 1
normalize(restpe)
case ExistentialType(tparams, qtpe) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c3ca5d7e30..20571f6c6d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -829,15 +829,22 @@ trait Typers { self: Analyzer =>
case Block(_, tree1) => tree1.symbol
case _ => tree.symbol
}
- if (!meth.isConstructor &&
- //isCompatible(tparamsToWildcards(mt, context.undetparams), pt) &&
- isFunctionType(pt))/* &&
- (pt <:< functionType(mt.paramTypes map (t => WildcardType), WildcardType)))*/ { // (4.2)
+ if (!meth.isConstructor && isFunctionType(pt)) { // (4.2)
if (settings.debug.value) log("eta-expanding "+tree+":"+tree.tpe+" to "+pt)
checkParamsConvertible(tree.pos, tree.tpe)
- val tree1 = etaExpand(context.unit, tree)
- //println("eta "+tree+" ---> "+tree1+":"+tree1.tpe)
- typed(tree1, mode, pt)
+ val tree0 = etaExpand(context.unit, tree)
+ // println("eta "+tree+" ---> "+tree0+":"+tree0.tpe+" undet: "+context.undetparams+ " mode: "+Integer.toHexString(mode))
+
+ if(meth.typeParams.nonEmpty) {
+ // #2624: need to infer type arguments for eta expansion of a polymorphic method
+ // context.undetparams contains clones of meth.typeParams (fresh ones were generated in etaExpand)
+ // need to run typer on tree0, since etaExpansion sets the tpe's of its subtrees to null
+ // can't type with the expected type, as we can't recreate the setup in (3) without calling typed
+ // (note that (3) does not call typed to do the polymorphic type instantiation --
+ // it is called after the tree has been typed with a polymorphic expected result type)
+ instantiate(typed(tree0, mode, WildcardType), mode, pt)
+ } else
+ typed(tree0, mode, pt)
} else if (!meth.isConstructor && mt.params.isEmpty) { // (4.3)
adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt, original)
} else if (context.implicitsEnabled) {
@@ -2345,8 +2352,10 @@ trait Typers { self: Analyzer =>
if (targ == WildcardType) tparam.tpe else targ) //@M TODO: should probably be .tpeHK
def typedArgToPoly(arg: Tree, formal: Type): Tree = {
val lenientPt = formal.instantiateTypeParams(tparams, lenientTargs)
+ // println("typedArgToPoly(arg, formal): "+(arg, formal))
val arg1 = typedArg(arg, argMode(fun, mode), POLYmode, lenientPt)
val argtparams = context.extractUndetparams()
+ // println("typedArgToPoly(arg1, argtparams): "+(arg1, argtparams))
if (!argtparams.isEmpty) {
val strictPt = formal.instantiateTypeParams(tparams, strictTargs)
inferArgumentInstance(arg1, argtparams, strictPt, lenientPt)