From 0ba35e69973e7c53c537539c420f63b357a35cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Apr 2023 15:27:29 +0200 Subject: [PATCH] Fix #13757: Explicitly disallow higher-kinded scrutinees of match types. --- .../tools/dotc/reporting/ErrorMessageID.scala | 1 + .../dotty/tools/dotc/reporting/messages.scala | 5 +++++ compiler/src/dotty/tools/dotc/typer/Typer.scala | 5 ++++- tests/neg/i13757-match-type-anykind.scala | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i13757-match-type-anykind.scala diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index 1fe38ce5e801..b3d9b2c1dc49 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -192,6 +192,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case UnusedNonUnitValueID // errorNumber 176 case ConstrProxyShadowsID // errorNumber 177 case MissingArgumentListID // errorNumber: 178 + case MatchTypeScrutineeCannotBeHigherKindedID // errorNumber: 179 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index fba08fd84d0c..1c3bd23de9c6 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -2878,3 +2878,8 @@ class UnusedNonUnitValue(tp: Type)(using Context) def kind = MessageKind.PotentialIssue def msg(using Context) = i"unused value of type $tp" def explain(using Context) = "" + +class MatchTypeScrutineeCannotBeHigherKinded(tp: Type)(using Context) + extends TypeMsg(MatchTypeScrutineeCannotBeHigherKindedID) : + def msg(using Context) = i"the scrutinee of a match type cannot be higher-kinded" + def explain(using Context) = "" diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 16b256e69059..bfd85a94cc4b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2214,8 +2214,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if (tree.bound.isEmpty && isFullyDefined(pt, ForceDegree.none)) TypeTree(pt) else typed(tree.bound) val sel1 = typed(tree.selector) + val sel1Tpe = sel1.tpe + if sel1Tpe.isLambdaSub then + report.error(MatchTypeScrutineeCannotBeHigherKinded(sel1Tpe), sel1.srcPos) val pt1 = if (bound1.isEmpty) pt else bound1.tpe - val cases1 = tree.cases.mapconserve(typedTypeCase(_, sel1.tpe, pt1)) + val cases1 = tree.cases.mapconserve(typedTypeCase(_, sel1Tpe, pt1)) assignType(cpy.MatchTypeTree(tree)(bound1, sel1, cases1), bound1, sel1, cases1) } diff --git a/tests/neg/i13757-match-type-anykind.scala b/tests/neg/i13757-match-type-anykind.scala new file mode 100644 index 000000000000..d8273e546dab --- /dev/null +++ b/tests/neg/i13757-match-type-anykind.scala @@ -0,0 +1,16 @@ +object Test: + type AnyKindMatchType1[X <: AnyKind] = X match // error: the scrutinee of a match type cannot be higher-kinded // error + case Option[a] => Int + + type AnyKindMatchType2[X <: AnyKind] = X match // error: the scrutinee of a match type cannot be higher-kinded + case Option => Int // error: Missing type parameter for Option + + type AnyKindMatchType3[X <: AnyKind] = X match // error: the scrutinee of a match type cannot be higher-kinded // error + case _ => Int + + type AnyKindMatchType4[X <: Option] = X match // error // error: the scrutinee of a match type cannot be higher-kinded // error + case _ => Int + + type AnyKindMatchType5[X[_]] = X match // error: the scrutinee of a match type cannot be higher-kinded // error + case _ => Int +end Test