Skip to content

Commit 302a382

Browse files
committed
Keep deps so "dependsOn" is correct
1 parent 4053656 commit 302a382

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
419419
case prevEntry: TypeBounds =>
420420
adjustBounds(prevEntry, add = false)
421421
case _ =>
422-
dropDeps(srcParam) // srcParam is instantiated, so its dependencies can be dropped
422+
if entry != null && entry.exists then
423+
// srcParam is instantiated, but keep dependencies to respond to "dependsOn"
424+
adjustBounds(entry.bounds, add = true)
423425
this
424426
end adjustDeps
425427

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,9 @@ object ProtoTypes {
7777
if !tvar.isInstantiated then
7878
// Filter out any tvar that instantiating would further constrain the current constraint
7979
// Similar to filterByDeps in interpolateTypeVars.
80-
// Also, filter out any tvar that is in the instantiation of another tvar
81-
// (that we're not also trying to instantiate)
82-
// For example, in tests/pos/i21981.scala
83-
// when testing the compatibility of `.map2[?K]` on receiver `map0[?B]`
84-
// the tvars for B and K unified, instantiating `B := K`,
85-
// so we can't instantiate away `K` as it would incorrectly define `B`.
8680
val excluded = ctx.typerState.ownedVars.filter(!_.isInstantiated)
87-
var isInst = false
88-
ctx.typerState.constraint.foreachTypeVar: tvar1 =>
89-
isInst ||= !excluded.contains(tvar1) && tvar1.instanceOpt == tvar
90-
val aboveOK = !isInst && !ctx.typerState.constraint.dependsOn(tvar, excluded, co = true)
91-
val belowOK = !isInst && !ctx.typerState.constraint.dependsOn(tvar, excluded, co = false)
81+
val aboveOK = !ctx.typerState.constraint.dependsOn(tvar, excluded, co = true)
82+
val belowOK = !ctx.typerState.constraint.dependsOn(tvar, excluded, co = false)
9283
if aboveOK then
9384
tvar.instantiate(fromBelow = false)
9485
else if belowOK then

tests/pos/i21981.contrak.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
case class Inv[T](x: T)
2+
class Contra[-ContraParam](x: ContraParam)
3+
4+
trait Ops[F[_], A]:
5+
def map0[B](f0: A => Contra[B]): F[B] = ???
6+
7+
trait Functor1[G[_]]
8+
9+
trait Functor2[H[_]]
10+
11+
trait Ref[I[_], +E]
12+
13+
class Test:
14+
given [J[_]](using J: Functor1[J]): Functor2[J] with
15+
extension [K](jk: J[Contra[K]])
16+
def map2[L](f2: K => L): J[L] = ???
17+
18+
def t1[
19+
M[_[t]],
20+
N[_],
21+
](using N: Functor1[N]): Unit =
22+
23+
val x3: Ops[N, M[[t] =>> Ref[N, t]]] = ???
24+
25+
val x2: N[(M[N], M[[t] =>> Ref[N, t]])] = x3
26+
.map0 { refs => Contra[Contra[(Nothing, M[[t] =>> Ref[N, t]])]](???) }
27+
.map2 { case (not, refs) => (???, refs) }

0 commit comments

Comments
 (0)