-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Tweak tparam unification to work with lambda cleanup #22031
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
0c94920
53bbae8
4ca6008
4c9f92a
4053656
302a382
68045d3
d28109f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,24 @@ object ProtoTypes { | |
for tvar <- newctx.typerState.ownedVars do | ||
inContext(newctx): | ||
if !tvar.isInstantiated then | ||
tvar.instantiate(fromBelow = false) // any direction | ||
// Filter out any tvar that instantiating would further constrain the current constraint | ||
// Similar to filterByDeps in interpolateTypeVars. | ||
// Also, filter out any tvar that is the instantiation another tvar | ||
// (that we're not also trying to instantiate) | ||
// For example, in tests/pos/i21981.scala | ||
// when testing the compatibility of `.map2[?K]` on receiver `map0[?B]` | ||
// the tvars for B and K unified, instantiating `B := K`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check case class Inv[T](x: T)
class Contra[-ContraParam](x: ContraParam)
trait Ops[F[_], A]:
def map0[B](f0: A => Contra[B]): F[B] = ???
trait Functor1[G[_]]
trait Functor2[H[_]]
trait Ref[I[_], +E]
class Test:
given [J[_]](using J: Functor1[J]): Functor2[J] with
extension [K](jk: J[Contra[K]])
def map2[L](f2: K => L): J[L] = ???
def t1[
M[_[t]],
N[_],
](using N: Functor1[N]): Unit =
val x3: Ops[N, M[[t] =>> Ref[N, t]]] = ???
val x2: N[(M[N], M[[t] =>> Ref[N, t]])] = x3
.map0 { refs => Contra[Contra[(Nothing, M[[t] =>> Ref[N, t]])]](???) }
.map2 { case (not, refs) => (???, refs) } Now this could probably be fixed by checking |
||
// so we can't instantiate away `K` as it would incorrectly define `B`. | ||
val excluded = ctx.typerState.ownedVars.filter(!_.isInstantiated) | ||
var isInst = false | ||
ctx.typerState.constraint.foreachTypeVar: tvar1 => | ||
isInst ||= !excluded.contains(tvar1) && tvar1.instanceOpt == tvar | ||
dwijnand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
val aboveOK = !isInst && !ctx.typerState.constraint.dependsOn(tvar, excluded, co = true) | ||
val belowOK = !isInst && !ctx.typerState.constraint.dependsOn(tvar, excluded, co = false) | ||
if aboveOK then | ||
tvar.instantiate(fromBelow = false) | ||
else if belowOK then | ||
tvar.instantiate(fromBelow = true) | ||
|
||
// commit any remaining changes in typer state | ||
newctx.typerState.commit() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
trait Ops[F[_], A]: | ||
def map0[B](f0: A => B): F[B] = ??? | ||
|
||
trait Functor1[G[_]] | ||
|
||
trait Functor2[H[_]]: | ||
extension [C1, C2](hc: H[(C1, C2)]) | ||
def map2[D](f1: (C1, C2) => D): H[D] | ||
|
||
trait Ref[I[_], +E] | ||
|
||
final class Cov[+F] | ||
|
||
class Test: | ||
given [J[_]](using J: Functor1[J]): Functor2[J] with | ||
extension [K1, K2](jk: J[(K1, K2)]) | ||
def map2[L](f2: (K1, K2) => L): J[L] = ??? | ||
|
||
def t1[ | ||
M[_[t]], | ||
N[_], | ||
](using N: Functor1[N]): Unit = | ||
|
||
val x3: Ops[N, M[[t] =>> Ref[N, t]]] = ??? | ||
|
||
val x2: N[(M[N], M[[t] =>> Ref[N, t]])] = x3 | ||
.map0 { refs => (???, refs) } | ||
.map2 { case (not, refs) => (???, refs) } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
object internal: | ||
trait Functor[F[_]] { | ||
extension [T](ft: F[T]) def map[T1](f: T => T1): F[T1] | ||
} | ||
|
||
object cats: | ||
trait Functor[F[_]] | ||
object Functor: | ||
trait Ops[F[_], A]: | ||
def map[B](f: A => B): F[B] = ??? | ||
def toAllFunctorOps[F[_], A](target: F[A])(using Functor[F]): Ops[F, A] = ??? | ||
|
||
given [F[_]](using cf: cats.Functor[F]): internal.Functor[F] with { | ||
extension [T](ft: F[T]) def map[T1](f: T => T1): F[T1] = ??? | ||
} | ||
|
||
trait Ref[F[_], +T] | ||
class MemoizingEvaluator[Input[_[_]], Output[_[_]], F[_]: cats.Functor] { | ||
type OptionRef[T] = Ref[F, Option[T]] | ||
|
||
def sequence[CaseClass[_[_]], G[_], H[_]](instance: CaseClass[[t] =>> G[H[t]]]): G[CaseClass[H]] = ??? | ||
def collectValues(input: Input[F]): F[(Input[F], Input[OptionRef])] = { | ||
val refsF: Input[[t] =>> F[OptionRef[t]]] = ??? | ||
for { | ||
refs <- cats.Functor.toAllFunctorOps(sequence[Input, F, OptionRef](refsF)) | ||
updating = ??? | ||
} yield (updating, refs) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
trait Ops[F[_], A]: | ||
def map0[B](f0: A => B): F[B] = ??? | ||
|
||
trait Functor1[G[_]] | ||
|
||
trait Functor2[H[_]]: | ||
extension [C](hc: H[C]) | ||
def map2[D](f1: C => D): H[D] | ||
|
||
trait Ref[I[_], +E] | ||
|
||
final class Cov[+F] | ||
|
||
class Test: | ||
given [J[_]](using J: Functor1[J]): Functor2[J] with | ||
extension [K](jk: J[K]) | ||
def map2[L](f2: K => L): J[L] = ??? | ||
|
||
def t1[ | ||
M[_[t]], | ||
N[_], | ||
](using N: Functor1[N]): Unit = | ||
|
||
val x3: Ops[N, M[[t] =>> Ref[N, t]]] = ??? | ||
|
||
val x2: N[(M[N], M[[t] =>> Ref[N, t]])] = x3 | ||
.map0 { refs => (???, refs) } | ||
.map2 { case (not, refs) => (???, refs) } |
Uh oh!
There was an error while loading. Please reload this page.