diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 8 | ||||
-rw-r--r-- | test/files/pos/t8138.scala | 24 | ||||
-rw-r--r-- | test/files/pos/t8152-performance.scala | 13 |
4 files changed, 49 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 430129aaff..e61b35a621 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -878,11 +878,13 @@ abstract class UnCurry extends InfoTransform case Packed(param, tempVal) => (param, tempVal) }.unzip - val rhs1 = localTyper.typedPos(rhs.pos) { - // Patch the method body to refer to the temp vals - val rhsSubstituted = rhs.substituteSymbols(packedParams map (_.symbol), tempVals map (_.symbol)) - // The new method body: { val p$1 = p.asInstanceOf[<dependent type>]; ...; <rhsSubstituted> } - Block(tempVals, rhsSubstituted) + val rhs1 = if (tempVals.isEmpty) rhs else { + localTyper.typedPos(rhs.pos) { + // Patch the method body to refer to the temp vals + val rhsSubstituted = rhs.substituteSymbols(packedParams map (_.symbol), tempVals map (_.symbol)) + // The new method body: { val p$1 = p.asInstanceOf[<dependent type>]; ...; <rhsSubstituted> } + Block(tempVals, rhsSubstituted) + } } (allParams :: Nil, rhs1) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 081f7a8696..fea234dd14 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -909,11 +909,13 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // case DeBruijnIndex(_, _) => case SingleType(pre, sym) => validateVariance(pre, variance) + case TypeRef(_, sym, _) if sym.isAliasType => + // okay to ignore pre/args here. In 2.10.3 we used to check them in addition to checking + // the normalized type, which led to exponential time type checking, see pos/t8152-performance.scala + validateVariance(tp.normalize, variance) case TypeRef(pre, sym, args) => // println("validate "+sym+" at "+relativeVariance(sym)) - if (sym.isAliasType/* && relativeVariance(sym) == AnyVariance*/) - validateVariance(tp.normalize, variance) - else if (sym.variance != NoVariance) { + if (sym.variance != NoVariance) { val v = relativeVariance(sym) if (v != AnyVariance && sym.variance != v * variance) { //Console.println("relativeVariance(" + base + "," + sym + ") = " + v);//DEBUG diff --git a/test/files/pos/t8138.scala b/test/files/pos/t8138.scala new file mode 100644 index 0000000000..b980930955 --- /dev/null +++ b/test/files/pos/t8138.scala @@ -0,0 +1,24 @@ + +class U { + trait Transformer { + def transform(a: Tree): Tree = ??? + } + trait Tree +} + +object Test { + def m(u: U) = { + class C extends u.Transformer { + override def transform(t: u.Tree): u.Tree = { + null match { + case _ => + // crashes in GenICode: + // error: Unknown type: <notype>, <notype> [class scala.reflect.internal.Types$NoType$, class scala.reflect.internal.Types$NoType$] TypeRef? false + (y: Any) => super.transform(???) + null + } + ??? + } + } + } +} diff --git a/test/files/pos/t8152-performance.scala b/test/files/pos/t8152-performance.scala new file mode 100644 index 0000000000..b6d2ecd823 --- /dev/null +++ b/test/files/pos/t8152-performance.scala @@ -0,0 +1,13 @@ +class HListBench { + + class A[H, T] + + type B[H, T] = A[H, T] + + // was okay + type T1 = A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, A[Int, Nothing]]]]]]]]]]]]]]]]]]]]]]]]]]]] + + // Took over a minute to validate variance in 2.10.3! + type T2 = B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, B[Int, Nothing]]]]]]]]]]]]]]]]]]]]]]]]]]]] + +}
\ No newline at end of file |