summaryrefslogtreecommitdiff
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
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
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
-rw-r--r--test/files/neg/bug608.check8
-rw-r--r--test/files/neg/bug608.scala24
-rw-r--r--test/files/pos/t2624.scala4
5 files changed, 37 insertions, 24 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)
diff --git a/test/files/neg/bug608.check b/test/files/neg/bug608.check
index 4e8eb4d709..a8e32e4c10 100644
--- a/test/files/neg/bug608.check
+++ b/test/files/neg/bug608.check
@@ -1,6 +1,6 @@
bug608.scala:16: error: type mismatch;
- found : (a) => a
- required: (ha) => ?
- = g(f(x).bimap(id))
- ^
+ found : hs{type a = ha}
+ required: hs{type s = hs; type a = ha}
+ = g(f(x).bimap(id))
+ ^
one error found
diff --git a/test/files/neg/bug608.scala b/test/files/neg/bug608.scala
index 24f515651a..34dc4c0352 100644
--- a/test/files/neg/bug608.scala
+++ b/test/files/neg/bug608.scala
@@ -1,17 +1,17 @@
trait CrashDueToTypeError {
- def id[a](x :a) :a = x
+ def id[a](x :a) :a = x
- trait Bifunctor {
- type a; // content
- type s <: Bifunctor
+ trait Bifunctor {
+ type a; // content
+ type s <: Bifunctor
- // uncomment this-vvvvvvvvvvvvvvvvvvvvvvvvvvvv, and it compiles
- def bimap[c](f :a=>c) :s{/*type s=Bifunctor.this.s;*/type a=c; }
- }
+ // uncomment this-vvvvvvvvvvvvvvvvvvvvvvvvvvvv, and it compiles
+ def bimap[c](f :a=>c) :s{/*type s=Bifunctor.this.s;*/type a=c; }
+ }
- def hylo[hs <: Bifunctor,ha,hb,hc]
- (f :hb=>hs{type s=hs; type a=ha},
- g :hs{type s=hs; type a=ha}=>hc)(x :hb)
- :hc
- = g(f(x).bimap(id))
+ def hylo[hs <: Bifunctor,ha,hb,hc]
+ (f :hb=>hs{type s=hs; type a=ha},
+ g :hs{type s=hs; type a=ha}=>hc)(x :hb)
+ :hc
+ = g(f(x).bimap(id))
}
diff --git a/test/files/pos/t2624.scala b/test/files/pos/t2624.scala
new file mode 100644
index 0000000000..76f0e30369
--- /dev/null
+++ b/test/files/pos/t2624.scala
@@ -0,0 +1,4 @@
+object Test {
+ List(1).map(identity(_))
+ List(1).map(identity) // this didn't typecheck before the fix
+}