Skip to content

Commit

Permalink
Fix #13757: Explicitly disallow higher-kinded scrutinees of match typ…
Browse files Browse the repository at this point in the history
…es. (#17322)
  • Loading branch information
sjrd authored Apr 20, 2023
2 parents abf9a25 + 0ba35e6 commit e8ea8cf
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) = ""
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
16 changes: 16 additions & 0 deletions tests/neg/i13757-match-type-anykind.scala
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit e8ea8cf

Please sign in to comment.