Skip to content

Commit 9fde63d

Browse files
committed
Avoid infinite expansion in normaizeWildcardArgs
1 parent 7664e9d commit 9fde63d

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

compiler/src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,32 @@ class TypeApplications(val self: Type) extends AnyVal {
419419
* - interpolate, so that any (F-bounded) type parameters in the resulting bounds are avoided.
420420
* The resulting bounds are joined (via &) with corresponding type bound arguments.
421421
*/
422-
def normalizeWildcardArg(arg: Type, tparam: TypeParamInfo): Type = arg match {
422+
def normalizeWildcardArg(typParams: List[TypeSymbol])(arg: Type, tparam: TypeSymbol): Type = arg match {
423423
case TypeBounds(lo, hi) =>
424-
val v = tparam.paramVariance
425-
val avoidParams = new ApproximatingTypeMap {
424+
def avoidParams(seen: Set[Symbol], v: Int): ApproximatingTypeMap = new ApproximatingTypeMap {
426425
variance = if (v >= 0) 1 else -1
427426
def apply(t: Type) = t match {
428427
case t: TypeRef if typParams contains t.symbol =>
429-
val bounds = apply(t.info).bounds
430-
range(bounds.lo, bounds.hi)
428+
val lo = atVariance(-variance)(apply(t.info.loBound))
429+
val hi =
430+
if (seen.contains(t.symbol)) t.topType
431+
else avoidParams(seen + t.symbol, variance)(t.info.hiBound)
432+
range(lo, hi)
431433
case _ => mapOver(t)
432434
}
433435
}
436+
val v = tparam.paramVariance
434437
val pbounds = dealiased match {
435438
case dealiased @ TypeRef(prefix, _) =>
436439
val (concreteArgs, concreteParams) = // @!!! optimize?
437-
args.zip(typeParams.asInstanceOf[List[TypeSymbol]])
438-
.filter(!_._1.isInstanceOf[TypeBounds])
439-
.unzip
440-
avoidParams(
441-
tparam.paramInfo.asSeenFrom(prefix, tparam.asInstanceOf[TypeSymbol].owner)
442-
.subst(concreteParams, concreteArgs)).orElse(TypeBounds.empty)
440+
args.zip(typParams).filter(!_._1.isInstanceOf[TypeBounds]).unzip
441+
avoidParams(Set(tparam), v)(
442+
tparam.paramInfo.asSeenFrom(prefix, tparam.owner)
443+
.subst(concreteParams, concreteArgs))
443444
case _ =>
444445
TypeBounds.empty
445446
}
446-
//typr.println(i"normalize arg $arg for $tparam in $self app $args%, %, pbounds, = $pbounds")
447+
typr.println(i"normalize arg $arg for $tparam in $self app $args%, %, pbounds, = $pbounds")
447448
if (v > 0) hi & pbounds.hiBound
448449
else if (v < 0) lo | pbounds.loBound
449450
else arg & pbounds
@@ -500,9 +501,10 @@ class TypeApplications(val self: Type) extends AnyVal {
500501
case _ if typParams.isEmpty || typParams.head.isInstanceOf[LambdaParam] =>
501502
HKApply(self, args)
502503
case dealiased =>
503-
if (Config.newScheme)
504-
AppliedType(self, args.zipWithConserve(typParams)(normalizeWildcardArg))
505-
else
504+
if (Config.newScheme) {
505+
val tparamSyms = typParams.asInstanceOf[List[TypeSymbol]]
506+
AppliedType(self, args.zipWithConserve(tparamSyms)(normalizeWildcardArg(tparamSyms)))
507+
} else
506508
matchParams(dealiased, typParams, args)
507509
}
508510
}

tests/pos/boundspropagation.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ object test1 {
1111
}
1212
class Derived extends Base {
1313
def g(x: Any): Tree[N] = x match {
14-
case y: Tree[_] => y // now succeeds in dotc
14+
case y: Tree[_] => y.asInstanceOf
15+
// without the cast: fails in scalac and new dotc
16+
// used to succeed in dotc if type args are refinements
1517
}
1618
}
1719
}

0 commit comments

Comments
 (0)