@@ -77,13 +77,22 @@ object ProtoTypes {
77
77
if ! tvar.isInstantiated then
78
78
// Filter out any tvar that instantiating would further constrain the current constraint
79
79
// Similar to filterByDeps in interpolateTypeVars.
80
+ // Also, filter out any tvar that is the instantiation 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`.
80
86
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 belowOK then
84
- tvar.instantiate(fromBelow = true )
85
- else if aboveOK then
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 )
92
+ if aboveOK then
86
93
tvar.instantiate(fromBelow = false )
94
+ else if belowOK then
95
+ tvar.instantiate(fromBelow = true )
87
96
88
97
// commit any remaining changes in typer state
89
98
newctx.typerState.commit()
0 commit comments