Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #13757: Explicitly disallow higher-kinded scrutinees of match types. #17322

Merged
merged 1 commit into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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