Skip to content

Commit 18e6a95

Browse files
committed
Tweak lambda/tvar cleanup, to avoid mis-instantiating
1 parent 5dda2a3 commit 18e6a95

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

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

+2-11
Original file line numberDiff line numberDiff line change
@@ -436,17 +436,8 @@ trait ConstraintHandling {
436436

437437
val level1 = nestingLevel(p1)
438438
val level2 = nestingLevel(p2)
439-
val p1Wins = if level1 == level2 then
440-
// If the nesting levels match, then we would prefer to unify to the outer most parameter.
441-
// For instance in pos/i21981, while running `normalizedCompatible` against `.map2`,
442-
// we want to unify to B over K, to allow easily removing K by just instantiating it.
443-
def preferP1(ctx: Context): Boolean =
444-
val c = ctx.typerState.constraint
445-
!c.contains(p2) || c.contains(p1) && preferP1(ctx.outer)
446-
preferP1(ctx)
447-
else level1 <= level2
448-
val pKept = if p1Wins then p1 else p2
449-
val pRemoved = if p1Wins then p2 else p1
439+
val pKept = if level1 <= level2 then p1 else p2
440+
val pRemoved = if level1 <= level2 then p2 else p1
450441

451442
val down = constraint.exclusiveLower(p2, p1)
452443
val up = constraint.exclusiveUpper(p1, p2)

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,15 @@ object ProtoTypes {
7575
for tvar <- newctx.typerState.ownedVars do
7676
inContext(newctx):
7777
if !tvar.isInstantiated then
78-
tvar.instantiate(fromBelow = false) // any direction
78+
// Filter out any tvar that instantiating would further constrain the current constraint
79+
// Similar to filterByDeps in interpolateTypeVars.
80+
val excluded = ctx.typerState.ownedVars.filter(!_.isInstantiated)
81+
val aboveOK = !ctx.typerState.constraint.dependsOn(tvar, excluded, co = true)
82+
val belowOK = !ctx.typerState.constraint.dependsOn(tvar, excluded, co = false)
83+
if aboveOK then
84+
tvar.instantiate(fromBelow = true)
85+
else if belowOK then
86+
tvar.instantiate(fromBelow = false)
7987

8088
// commit any remaining changes in typer state
8189
newctx.typerState.commit()

tests/pos/i21981.alt.scala

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
trait Ops[F[_], A]:
2+
def map0[B](f0: A => B): F[B] = ???
3+
4+
trait Functor1[G[_]]
5+
6+
trait Functor2[H[_]]:
7+
extension [C1, C2](hc: H[(C1, C2)])
8+
def map2[D](f1: (C1, C2) => D): H[D]
9+
10+
trait Ref[I[_], +E]
11+
12+
final class Cov[+F]
13+
14+
class Test:
15+
given [J[_]](using J: Functor1[J]): Functor2[J] with
16+
extension [K1, K2](jk: J[(K1, K2)])
17+
def map2[L](f2: (K1, K2) => L): J[L] = ???
18+
19+
def t1[
20+
M[_[t]],
21+
N[_],
22+
](using N: Functor1[N]): Unit =
23+
24+
val x3: Ops[N, M[[t] =>> Ref[N, t]]] = ???
25+
26+
val x2: N[(M[N], M[[t] =>> Ref[N, t]])] = x3
27+
.map0 { refs => (???, refs) }
28+
.map2 { case (not, refs) => (???, refs) }

tests/pos/i21981.orig.scala

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
object internal:
2+
trait Functor[F[_]] {
3+
extension [T](ft: F[T]) def map[T1](f: T => T1): F[T1]
4+
}
5+
6+
object cats:
7+
trait Functor[F[_]]
8+
object Functor:
9+
trait Ops[F[_], A]:
10+
def map[B](f: A => B): F[B] = ???
11+
def toAllFunctorOps[F[_], A](target: F[A])(using Functor[F]): Ops[F, A] = ???
12+
13+
given [F[_]](using cf: cats.Functor[F]): internal.Functor[F] with {
14+
extension [T](ft: F[T]) def map[T1](f: T => T1): F[T1] = ???
15+
}
16+
17+
trait Ref[F[_], +T]
18+
class MemoizingEvaluator[Input[_[_]], Output[_[_]], F[_]: cats.Functor] {
19+
type OptionRef[T] = Ref[F, Option[T]]
20+
21+
def sequence[CaseClass[_[_]], G[_], H[_]](instance: CaseClass[[t] =>> G[H[t]]]): G[CaseClass[H]] = ???
22+
def collectValues(input: Input[F]): F[(Input[F], Input[OptionRef])] = {
23+
val refsF: Input[[t] =>> F[OptionRef[t]]] = ???
24+
for {
25+
refs <- cats.Functor.toAllFunctorOps(sequence[Input, F, OptionRef](refsF))
26+
updating = ???
27+
} yield (updating, refs)
28+
}
29+
}

0 commit comments

Comments
 (0)