diff options
author | Martin Odersky <odersky@gmail.com> | 2016-07-22 00:12:03 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-22 00:12:03 +0200 |
commit | 5968e9f6154cc8642fc3f6cef636a12104dd7a26 (patch) | |
tree | 3212c84169743fd8cea703fe97ab0f2a40782b4b | |
parent | 80a65f4b2512bdf1dc46144bea1c000d39319872 (diff) | |
download | dotty-5968e9f6154cc8642fc3f6cef636a12104dd7a26.tar.gz dotty-5968e9f6154cc8642fc3f6cef636a12104dd7a26.tar.bz2 dotty-5968e9f6154cc8642fc3f6cef636a12104dd7a26.zip |
Fix parameterized typedefs with lambdas as rhs
Previously the compiler crashed when faced with a parameterized typedef
that has a lambda as rhs. We fix this by refining the condition when
not to abstract in typeDefsig.
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 14 | ||||
-rw-r--r-- | tests/pos/nestedLambdas.scala | 9 |
2 files changed, 15 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 3b193d2db..666047db2 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -934,15 +934,11 @@ class Namer { typer: Typer => } def typeDefSig(tdef: TypeDef, sym: Symbol, tparamSyms: List[TypeSymbol])(implicit ctx: Context): Type = { - val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree] - //val toParameterize = tparamSyms.nonEmpty && !isDerived - //val needsLambda = sym.allOverriddenSymbols.exists(_ is HigherKinded) && !isDerived - def abstracted(tp: Type): Type = - if (tparamSyms.nonEmpty && !tp.isHK) tp.LambdaAbstract(tparamSyms) - //else if (toParameterize) tp.parameterizeWith(tparamSyms) + def abstracted(tp: Type, canAbstract: Boolean): Type = + if (tparamSyms.nonEmpty && canAbstract) tp.LambdaAbstract(tparamSyms) else tp - val dummyInfo = abstracted(TypeBounds.empty) + val dummyInfo = abstracted(TypeBounds.empty, canAbstract = true) sym.info = dummyInfo // Temporarily set info of defined type T to ` >: Nothing <: Any. // This is done to avoid cyclic reference errors for F-bounds. @@ -954,7 +950,9 @@ class Namer { typer: Typer => // // The scheme critically relies on an implementation detail of isRef, which // inspects a TypeRef's info, instead of simply dealiasing alias types. - val rhsType = abstracted(typedAheadType(tdef.rhs).tpe) + + val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree] + val rhsType = abstracted(typedAheadType(tdef.rhs).tpe, canAbstract = !isDerived) val unsafeInfo = rhsType match { case bounds: TypeBounds => bounds case alias => TypeAlias(alias, if (sym is Local) sym.variance else 0) diff --git a/tests/pos/nestedLambdas.scala b/tests/pos/nestedLambdas.scala new file mode 100644 index 000000000..0e186d193 --- /dev/null +++ b/tests/pos/nestedLambdas.scala @@ -0,0 +1,9 @@ +class Test { + + type T = [X] -> [Y] -> (X, Y) + + type A[X] = [Y] -> (X, Y) + + type B[X] = (X, X) + +} |