diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2009-11-25 09:20:26 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2009-11-25 09:20:26 +0000 |
commit | b059cbd155aec675b40a2a54f18bb127f17fcf37 (patch) | |
tree | 9d02d0067ac0b40518d24126e3cbd3eb68ea69cb /src/compiler | |
parent | 6f4a561df2973cd48241ff4389e3ddf137c141f5 (diff) | |
download | scala-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/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 23 |
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) |