diff --git a/bench/profiles/exhaustivity.yml b/bench/profiles/exhaustivity.yml index 0591bb0c4d56..68b480a095aa 100644 --- a/bench/profiles/exhaustivity.yml +++ b/bench/profiles/exhaustivity.yml @@ -47,6 +47,12 @@ charts: - key: exhaustivity-i12358 label: bootstrapped + - name: "exhaustivity i13565" + url: https://github.com/lampepfl/dotty/blob/master/tests/pos/i13565.scala + lines: + - key: exhaustivity-i13565 + label: bootstrapped + scripts: patmatexhaust: @@ -73,5 +79,8 @@ scripts: exhaustivity-i12358: - measure -wi 20 -i 40 -f 3 -- $PROG_HOME/dotty/tests/patmat/i12358.scala + exhaustivity-i13565: + - measure 20 40 3 $PROG_HOME/dotty/tests/pos/i13565.scala + config: pr_base_url: "https://github.com/lampepfl/dotty/pull/" diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 45e811e6d91c..7fc2ef886c52 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -531,6 +531,11 @@ class SpaceEngine(using Context) extends SpaceLogic { else convertConstantType(tp1, tp2) } + private val isSubspaceCache = mutable.HashMap.empty[(Space, Space, Context), Boolean] + + override def isSubspace(a: Space, b: Space)(using Context): Boolean = + isSubspaceCache.getOrElseUpdate((a, b, ctx), super.isSubspace(a, b)) + /** Is `tp1` a subtype of `tp2`? */ def isSubType(tp1: Type, tp2: Type): Boolean = trace(i"$tp1 <:< $tp2", debug, show = true) { if tp1 == constantNullType && !ctx.explicitNulls then tp2 == constantNullType diff --git a/tests/pos/i13565.scala b/tests/pos/i13565.scala new file mode 100644 index 000000000000..00b7e393a016 --- /dev/null +++ b/tests/pos/i13565.scala @@ -0,0 +1,67 @@ +package ips.clang + +sealed trait PrimaryExpression extends PostfixExpression +sealed trait PostfixExpression extends UnaryExpression +sealed trait UnaryExpression extends CastExpression +sealed trait CastExpression extends MultiplicativeExpression +sealed trait MultiplicativeExpression extends AdditiveExpression +sealed trait AdditiveExpression extends ShiftExpression +sealed trait ShiftExpression extends RelationalExpression +sealed trait RelationalExpression extends EqualityExpression +sealed trait EqualityExpression extends PrecAndExpression +sealed trait PrecAndExpression extends PrecExclusiveOrExpression +sealed trait PrecExclusiveOrExpression extends PrecInclusiveOrExpression +sealed trait PrecInclusiveOrExpression extends PrecLogicalAndExpression +sealed trait PrecLogicalAndExpression extends PrecLogicalOrExpression +sealed trait PrecLogicalOrExpression extends PrecConditionalExpression +sealed trait PrecConditionalExpression extends PrecAssigmentExpression +sealed trait PrecAssigmentExpression extends Expression +sealed trait Expression +sealed trait BinaryExpression { def op: String; def frs: Expression; def snd: Expression } + +type TypeName = String +case class Identifier(value: String) extends PrimaryExpression +case class IntConstant(value: Int) extends PrimaryExpression +case class CharConstant(value: Char) extends PrimaryExpression +case class StringLiteral(value: String) extends PrimaryExpression +case class WrappedExpression(value: Expression) extends PrimaryExpression +case class ArrayIndexExpression(base: PostfixExpression, index: Expression) extends PostfixExpression +case class FunctionCallExpression(fun: PostfixExpression, arguments: List[PrecAssigmentExpression]) extends PostfixExpression +case class DotSelectExpression(qualifier: PostfixExpression, select: Identifier) extends PostfixExpression +case class ArrowSelectExpression(qualifier: PostfixExpression, select: Identifier) extends PostfixExpression +case class PostfixIncrementExpression(base: PostfixExpression) extends PostfixExpression +case class PostfixDecrementExpression(base: PostfixExpression) extends PostfixExpression +case class CompoundLiteral(typeName: TypeName, initializers: List[Int]) extends PostfixExpression +case class PrefixIncrementExpression(base: UnaryExpression) extends UnaryExpression +case class PrefixDecrementExpression(base: UnaryExpression) extends UnaryExpression +case class UnaryOperatorExpression(op: String, argument: CastExpression) extends UnaryExpression +case class SizeofConstExpression(expression: UnaryExpression) extends UnaryExpression +case class SizeofTypeExpression(typeName: TypeName) extends UnaryExpression +case class Cast(typeName: TypeName, argument: CastExpression) extends CastExpression +case class MultiplicativeBinaryExpression(op: String, frs: MultiplicativeExpression, snd: CastExpression) extends MultiplicativeExpression with BinaryExpression +case class AdditiveBinaryExpression(op: String, frs: MultiplicativeExpression, snd: CastExpression) extends MultiplicativeExpression with BinaryExpression +case class ShiftBinaryExpression(op: String, frs: MultiplicativeExpression, snd: CastExpression) extends MultiplicativeExpression with BinaryExpression +case class RelationalBinaryExpression(op: String, frs: RelationalExpression, snd: ShiftExpression) extends RelationalExpression with BinaryExpression +case class EqualityBinaryExpression(op: String, frs: RelationalExpression, snd: ShiftExpression) extends EqualityExpression with BinaryExpression +case class AndBinaryExpression(op: String, frs: PrecAndExpression, snd: EqualityExpression) extends PrecAndExpression with BinaryExpression +case class ExclusiveOrBinaryExpression(op: String, frs: PrecExclusiveOrExpression, snd: PrecAndExpression) extends PrecExclusiveOrExpression with BinaryExpression +case class InclusiveOrBinaryExpression(op: String, frs: PrecExclusiveOrExpression, snd: PrecAndExpression) extends PrecInclusiveOrExpression with BinaryExpression +case class LogicalAndBinaryExpression(op: String, frs: PrecLogicalAndExpression, snd: PrecInclusiveOrExpression) extends PrecLogicalAndExpression with BinaryExpression +case class LogicalOrBinaryExpression(op: String, frs: PrecLogicalAndExpression, snd: PrecInclusiveOrExpression) extends PrecLogicalOrExpression with BinaryExpression +case class ConditionalExpression(cond: PrecLogicalOrExpression, frs: Expression, snd: PrecConditionalExpression) extends PrecConditionalExpression +case class AssigmentExpression(op: String, frs: UnaryExpression, snd: PrecAssigmentExpression) extends PrecAssigmentExpression +case class CommaExpression(frs: Expression, snd: Expression) extends Expression +case class AltCommaExpression(frs: Expression, snd: Expression) extends Expression + +// each AdditionalUnaryExpressionX increase compilation time +sealed trait AdditionalUnaryExpression1 extends UnaryExpression +sealed trait AdditionalUnaryExpression2 extends UnaryExpression +sealed trait AdditionalUnaryExpression3 extends UnaryExpression +sealed trait AdditionalUnaryExpression4 extends UnaryExpression +sealed trait AdditionalUnaryExpression5 extends UnaryExpression + +class LongCompilation: + // this match used to take 2m30 to compile, with 1 cache it now takes 5s (30x speedup, aka 3000%) + def toCastExpression(expr: Expression): CastExpression = expr match + case x: CastExpression => x + case _ => WrappedExpression(expr)