Skip to content

Commit 8308388

Browse files
authored
Fix condition when to compare a captured ref (#12142)
Fixes #12141
1 parent c2538e8 commit 8308388

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,15 +1438,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
14381438
*/
14391439
def compareCaptured(arg1: TypeBounds, arg2: Type) = tparam match {
14401440
case tparam: Symbol =>
1441-
if (leftRoot.isStable || (ctx.isAfterTyper || ctx.mode.is(Mode.TypevarsMissContext))
1442-
&& leftRoot.member(tparam.name).exists) {
1441+
if (leftRoot.isStable || ctx.isAfterTyper || ctx.mode.is(Mode.TypevarsMissContext))
1442+
&& leftRoot.isValueType
1443+
&& leftRoot.member(tparam.name).exists
1444+
then
14431445
val captured = TypeRef(leftRoot, tparam)
14441446
try isSubArg(captured, arg2)
14451447
catch case ex: TypeError =>
14461448
// The captured reference could be illegal and cause a
14471449
// TypeError to be thrown in argDenot
14481450
false
1449-
}
14501451
else if (v > 0)
14511452
isSubType(paramBounds(tparam).hi, arg2)
14521453
else if (v < 0)

tests/pos/i12141.scala

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
case class Test1(); case class Test2(); case class Test3();
2+
case class Test4(); case class Test5(); case class Test6();
3+
4+
sealed abstract class DSL {
5+
def cont [P1 >: this.type <: DSL, P2 <: DSL](continuation: => P2) =
6+
Continue[P1, P2](() => this, () => continuation)
7+
}
8+
case class Continue [P1 <: DSL, P2 <: DSL](p1: () => P1, p2: () => P2) extends DSL
9+
10+
trait More[-A] {}
11+
case class Out[C <: More[A], A](c: C, v: A) extends DSL
12+
case class Nop() extends DSL
13+
14+
val decision1:Boolean = true;
15+
val decision2:Boolean = false;
16+
17+
type P[
18+
ChanA <: More[Test1|Test2],
19+
ChanB <: More[Test3|Test4],
20+
ChanC <: More[Test5|Test6]] =
21+
((Out[ChanA,Test1] Continue ((Out[ChanB,Test3] Continue Nop)|(Out[ChanB,Test4] Continue Nop))) //works if remove first 'Continue Nop'
22+
| (Out[ChanA,Test2] Continue ((Out[ChanC,Test5] Continue Nop)|(Out[ChanC,Test6] Continue Nop))))
23+
24+
25+
def p( chanA: More[Test1|Test2], chanB: More[Test3|Test4], chanC: More[Test5|Test6])
26+
:P[chanA.type,chanB.type,chanC.type] ={
27+
if(decision1){
28+
Out(chanA,Test1()) cont {
29+
if(decision2){
30+
Out(chanB,Test3()) cont Nop() //works if replace with 'Out(chanB,Test3())'
31+
}
32+
else{
33+
Out(chanB,Test4()) cont Nop()
34+
}
35+
}
36+
}
37+
else{
38+
Out(chanA,Test2()) cont {
39+
if(decision2){
40+
Out(chanC,Test5()) cont Nop()
41+
}
42+
else{
43+
Out(chanC,Test6()) cont Nop()
44+
}
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)