Skip to content

Commit f36967c

Browse files
authored
Merge pull request #15710 from dotty-staging/fix-15564
Avoid references to unbound parameters in applied type patterns
2 parents 1b299b3 + ae7a1d2 commit f36967c

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

+27-1
Original file line numberDiff line numberDiff line change
@@ -2004,8 +2004,34 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20042004
wrongNumberOfTypeArgs(tpt1.tpe, tparams, args, tree.srcPos)
20052005
args = args.take(tparams.length)
20062006
}
2007+
2008+
// If type constructor is not a class type, we need to eliminate
2009+
// any references to other parameter types of the underlying hk lambda
2010+
// in order not to get orphan parameters. Test case in pos/i15564.scala.
2011+
// Note 1: It would be better to substitute actual arguments for corresponding
2012+
// formal paramaters, but it looks very hard to do this at the point where
2013+
// a bound type variable is created.
2014+
// Note 2: If the type constructor is a class type, no sanitization is needed
2015+
// since we can refer to the other paraeters with dependent types C[...]#X.
2016+
def sanitizeBounds(bounds: Type, tycon: Type): Type =
2017+
def underlyingLambda(tp: Type): Type = tp match
2018+
case tp: HKTypeLambda => tp
2019+
case tp: TypeProxy => underlyingLambda(tp.superType)
2020+
case _ => NoType
2021+
val tl = underlyingLambda(tycon)
2022+
val widenMap = new TypeOps.AvoidMap:
2023+
def toAvoid(tp: NamedType) = false
2024+
override def apply(tp: Type): Type = tp match
2025+
case tp: TypeParamRef if tp.binder == tl => emptyRange
2026+
case _ => super.apply(tp)
2027+
widenMap(bounds)
2028+
20072029
def typedArg(arg: untpd.Tree, tparam: ParamInfo) = {
2008-
def tparamBounds = tparam.paramInfoAsSeenFrom(tpt1.tpe.appliedTo(tparams.map(_ => TypeBounds.empty)))
2030+
def tparamBounds =
2031+
val bounds =
2032+
tparam.paramInfoAsSeenFrom(tpt1.tpe.appliedTo(tparams.map(_ => TypeBounds.empty)))
2033+
if tparam.isInstanceOf[Symbol] then bounds
2034+
else sanitizeBounds(bounds, tpt1.tpe)
20092035
val (desugaredArg, argPt) =
20102036
if ctx.mode.is(Mode.Pattern) then
20112037
(if (untpd.isVarPattern(arg)) desugar.patternVar(arg) else arg, tparamBounds)

tests/pos/i15564.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
type Var[TV]
2+
type Set[TS, D <: Var[TS], V <: TS]
3+
type Foo[FX <: GX, GX]
4+
5+
type Get[S] = S match {
6+
case Set[t, d, v] => v
7+
}
8+
9+
def get(s: Any) = s match
10+
case _: Set[t, d, v] => ??? : v
11+
case _: Foo[a, b] => ???

0 commit comments

Comments
 (0)