Skip to content

Commit

Permalink
Allow refineUsingParent to infer GADT bounds
Browse files Browse the repository at this point in the history
Not doing so makes the type var interpolation between typer and the
match space analysis different, which can result in false positive and
negative exhaustivity and reachability warnings
  • Loading branch information
dwijnand committed Jul 26, 2022
1 parent 19eff87 commit d9659a9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
18 changes: 17 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,16 @@ object TypeOps:

val childTp = if (child.isTerm) child.termRef else child.typeRef

inContext(ctx.fresh.setExploreTyperState().setFreshGADTBounds) {
val ctx1 = ctx.fresh.setExploreTyperState().setFreshGADTBounds
val ctx2 = parent match
case _: RefinedType =>
ctx1
// patmat/t9657
// When running Bicycle.type <:< Vehicle { A = P }
// TypeComparer is happy to infer GADT bounds P >: Pedal.type <: Petrol.type & Pedal.type
// Despite the fact that Bicycle is an object, and thus final, so its type A can only be Pedal.type.
case _ => ctx1.addMode(Mode.GadtConstraintInference)
inContext(ctx2) {
instantiateToSubType(childTp, parent).dealias
}
}
Expand Down Expand Up @@ -829,6 +838,13 @@ object TypeOps:
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
val protoTp1 = inferThisMap.apply(tp1).appliedTo(tvars)

val getAbstractSymbols = new TypeAccumulator[List[Symbol]]:
def apply(xs: List[Symbol], tp: Type) = tp.dealias match
case tp: TypeRef if !tp.symbol.isClass => foldOver(tp.symbol :: xs, tp)
case tp => foldOver(xs, tp)
val syms2 = getAbstractSymbols(Nil, tp2).reverse
if syms2.nonEmpty then ctx.gadt.addToConstraint(syms2)

// If parent contains a reference to an abstract type, then we should
// refine subtype checking to eliminate abstract types according to
// variance. As this logic is only needed in exhaustivity check,
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/dotty/tools/vulpix/ParallelTesting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
) extends TestSource {
def sourceFiles: Array[JFile] = files.filter(isSourceFile)

override def toString() = outDir.toString
override def toString() = sourceFiles match { case Array(f) => f.getPath case _ => outDir.getPath }
}

/** A test source whose files will be compiled separately according to their
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ object Test {
def err2[A, B](value: Foo[A, B], a: A => Int): B = value match {
case b: Bar[B] => // spurious // error
b.x
case _ => ??? // avoid fatal inexhaustivity warnings suppressing the uncheckable warning
}

def fail[A, B](value: Foo[A, B], a: A => Int): B = value match {
case b: Bar[Int] => // error
b.x
case _ => ??? // avoid fatal inexhaustivity warnings suppressing the uncheckable warning
}
}

0 comments on commit d9659a9

Please sign in to comment.