Skip to content

Commit 1f00e4a

Browse files
authored
Fall back to direct subtype comparison at the end in dropIfSuper and dropIfSub (#20523)
Improve compiling in #20516. We need to be careful to check branches of AndTypes and OrTypes in correct order, see discussion in issue #20516. Fall back to direct subtype comparison at the end in dropIfSuper and dropIfSub. We may need to improve subtype checking for large intersections further to be able to fully test the example.
2 parents eb2ea26 + ba82f73 commit 1f00e4a

File tree

2 files changed

+211
-14
lines changed

2 files changed

+211
-14
lines changed

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

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,36 +2535,28 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25352535
/** If some (&-operand of) `tp` is a supertype of `sub` replace it with `NoType`.
25362536
*/
25372537
private def dropIfSuper(tp: Type, sub: Type): Type =
2538-
2539-
def isSuperOf(sub: Type): Boolean = sub match
2540-
case AndType(sub1, sub2) => isSuperOf(sub1) || isSuperOf(sub2)
2541-
case sub: TypeVar if sub.isInstantiated => isSuperOf(sub.instanceOpt)
2542-
case _ => isSubTypeWhenFrozen(sub, tp)
2543-
2538+
// We need to be careful to check branches of AndTypes and OrTypes in correct order,
2539+
// see discussion in issue #20516.
25442540
tp match
25452541
case tp @ AndType(tp1, tp2) =>
25462542
recombine(dropIfSuper(tp1, sub), dropIfSuper(tp2, sub), tp)
25472543
case tp: TypeVar if tp.isInstantiated =>
25482544
dropIfSuper(tp.instanceOpt, sub)
25492545
case _ =>
2550-
if isSuperOf(sub) then NoType else tp
2546+
if isSubTypeWhenFrozen(sub, tp) then NoType else tp
25512547
end dropIfSuper
25522548

25532549
/** If some (|-operand of) `tp` is a subtype of `sup` replace it with `NoType`. */
25542550
private def dropIfSub(tp: Type, sup: Type, canConstrain: Boolean): Type =
2555-
2556-
def isSubOf(sup: Type): Boolean = sup match
2557-
case OrType(sup1, sup2) => isSubOf(sup1) || isSubOf(sup2)
2558-
case sup: TypeVar if sup.isInstantiated => isSubOf(sup.instanceOpt)
2559-
case _ => isSubType(tp, sup, whenFrozen = !canConstrain)
2560-
2551+
// We need to be careful to check branches of AndTypes and OrTypes in correct order,
2552+
// see discussion in issue #20516.
25612553
tp match
25622554
case tp @ OrType(tp1, tp2) =>
25632555
recombine(dropIfSub(tp1, sup, canConstrain), dropIfSub(tp2, sup, canConstrain), tp)
25642556
case tp: TypeVar if tp.isInstantiated =>
25652557
dropIfSub(tp.instanceOpt, sup, canConstrain)
25662558
case _ =>
2567-
if isSubOf(sup) then NoType else tp
2559+
if isSubType(tp, sup, whenFrozen = !canConstrain) then NoType else tp
25682560
end dropIfSub
25692561

25702562
/** There's a window of vulnerability between ElimByName and Erasure where some

tests/pos-deep-subtype/i20516.scala

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
object Main {
2+
trait A {}
3+
trait B {}
4+
trait C {}
5+
trait D {}
6+
trait E {}
7+
trait F {}
8+
trait G {}
9+
trait H {}
10+
trait I {}
11+
trait J {}
12+
trait K {}
13+
trait L {}
14+
trait M {}
15+
trait N {}
16+
trait O {}
17+
trait P {}
18+
trait Q {}
19+
trait R {}
20+
trait S {}
21+
trait T {}
22+
trait U {}
23+
trait V {}
24+
trait W {}
25+
trait X {}
26+
trait Y {}
27+
trait Z {}
28+
29+
type AlphabeticServices = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
30+
31+
type EnvOutA = B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
32+
type EnvOutB = A & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
33+
type EnvOutC = A & B & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
34+
type EnvOutD = A & B & C & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
35+
type EnvOutE = A & B & C & D & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
36+
type EnvOutF = A & B & C & D & E & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
37+
type EnvOutG = A & B & C & D & E & F & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
38+
type EnvOutH = A & B & C & D & E & F & G & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
39+
type EnvOutI = A & B & C & D & E & F & G & H & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
40+
type EnvOutJ = A & B & C & D & E & F & G & H & I & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
41+
type EnvOutK = A & B & C & D & E & F & G & H & I & J & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
42+
type EnvOutL = A & B & C & D & E & F & G & H & I & J & K & M & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
43+
type EnvOutM = A & B & C & D & E & F & G & H & I & J & K & L & N & O & P & Q & R & S & T & U & V & W & X & Y & Z
44+
type EnvOutN = A & B & C & D & E & F & G & H & I & J & K & L & M & O & P & Q & R & S & T & U & V & W & X & Y & Z
45+
type EnvOutO = A & B & C & D & E & F & G & H & I & J & K & L & M & N & P & Q & R & S & T & U & V & W & X & Y & Z
46+
type EnvOutP = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & Q & R & S & T & U & V & W & X & Y & Z
47+
type EnvOutQ = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & R & S & T & U & V & W & X & Y & Z
48+
type EnvOutR = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & S & T & U & V & W & X & Y & Z
49+
type EnvOutS = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & T & U & V & W & X & Y & Z
50+
type EnvOutT = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & U & V & W & X & Y & Z
51+
type EnvOutU = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & V & W & X & Y & Z
52+
type EnvOutV = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & W & X & Y & Z
53+
type EnvOutW = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & X & Y & Z
54+
type EnvOutX = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & Y & Z
55+
type EnvOutY = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Z
56+
type EnvOutZ = A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R & S & T & U & V & W & X & Y
57+
58+
trait Reader[-E, A] {
59+
def map[B](f: A => B): Reader[E, B] = ???
60+
def flatMap[E2 <: E, B](f: A => Reader[E2, B]): Reader[E2, B] = ???
61+
}
62+
63+
def e1: Reader[EnvOutA, Unit] = ???
64+
def e2: Reader[EnvOutB, Unit] = ???
65+
def e3: Reader[EnvOutC, Unit] = ???
66+
def e4: Reader[EnvOutD, Unit] = ???
67+
def e5: Reader[EnvOutE, Unit] = ???
68+
def e6: Reader[EnvOutF, Unit] = ???
69+
def e7: Reader[EnvOutG, Unit] = ???
70+
def e8: Reader[EnvOutH, Unit] = ???
71+
def e9: Reader[EnvOutI, Unit] = ???
72+
def e10: Reader[EnvOutJ, Unit] = ???
73+
def e11: Reader[EnvOutK, Unit] = ???
74+
def e12: Reader[EnvOutL, Unit] = ???
75+
def e13: Reader[EnvOutM, Unit] = ???
76+
def e14: Reader[EnvOutN, Unit] = ???
77+
def e15: Reader[EnvOutO, Unit] = ???
78+
def e16: Reader[EnvOutP, Unit] = ???
79+
def e17: Reader[EnvOutQ, Unit] = ???
80+
def e18: Reader[EnvOutR, Unit] = ???
81+
def e19: Reader[EnvOutS, Unit] = ???
82+
def e20: Reader[EnvOutT, Unit] = ???
83+
def e21: Reader[EnvOutU, Unit] = ???
84+
def e22: Reader[EnvOutV, Unit] = ???
85+
def e23: Reader[EnvOutW, Unit] = ???
86+
def e24: Reader[EnvOutX, Unit] = ???
87+
def e25: Reader[EnvOutY, Unit] = ???
88+
def e26: Reader[EnvOutZ, Unit] = ???
89+
90+
def program: Reader[AlphabeticServices, Unit] = for {
91+
//1
92+
_ <- e1
93+
_ <- e2
94+
_ <- e3
95+
_ <- e4
96+
_ <- e5
97+
_ <- e6
98+
_ <- e7
99+
_ <- e8
100+
_ <- e8
101+
_ <- e9
102+
_ <- e10
103+
_ <- e11
104+
_ <- e12
105+
_ <- e13
106+
_ <- e14
107+
_ <- e15
108+
_ <- e16
109+
_ <- e17
110+
_ <- e18
111+
_ <- e19
112+
_ <- e20
113+
_ <- e21
114+
_ <- e22
115+
_ <- e23
116+
_ <- e24
117+
_ <- e25
118+
_ <- e26
119+
// 2
120+
_ <- e1
121+
_ <- e2
122+
_ <- e3
123+
_ <- e4
124+
_ <- e5
125+
_ <- e6
126+
_ <- e7
127+
_ <- e8
128+
_ <- e8
129+
_ <- e9
130+
_ <- e10
131+
_ <- e11
132+
_ <- e12
133+
_ <- e13
134+
_ <- e14
135+
_ <- e15
136+
_ <- e16
137+
_ <- e17
138+
_ <- e18
139+
_ <- e19
140+
_ <- e20
141+
_ <- e21
142+
_ <- e22
143+
_ <- e23
144+
_ <- e24
145+
_ <- e25
146+
_ <- e26
147+
// TODO: optimize the subtype checking for large intersection types further
148+
//3
149+
// _ <- e1
150+
// _ <- e2
151+
// _ <- e3
152+
// _ <- e4
153+
// _ <- e5
154+
// _ <- e6
155+
// _ <- e7
156+
// _ <- e8
157+
// _ <- e8
158+
// _ <- e9
159+
// _ <- e10
160+
// _ <- e11
161+
// _ <- e12
162+
// _ <- e13
163+
// _ <- e14
164+
// _ <- e15
165+
// _ <- e16
166+
// _ <- e17
167+
// _ <- e18
168+
// _ <- e19
169+
// _ <- e20
170+
// _ <- e21
171+
// _ <- e22
172+
// _ <- e23
173+
// _ <- e24
174+
// _ <- e25
175+
// _ <- e26
176+
// 4
177+
// _ <- e1
178+
// _ <- e2
179+
// _ <- e3
180+
// _ <- e4
181+
// _ <- e5
182+
// _ <- e6
183+
// _ <- e7
184+
// _ <- e8
185+
// _ <- e8
186+
// _ <- e9
187+
// _ <- e10
188+
// _ <- e11
189+
// _ <- e12
190+
// _ <- e13
191+
// _ <- e14
192+
// _ <- e15
193+
// _ <- e16
194+
// _ <- e17
195+
// _ <- e18
196+
// _ <- e19
197+
// _ <- e20
198+
// _ <- e21
199+
// _ <- e22
200+
// _ <- e23
201+
// _ <- e24
202+
// _ <- e25
203+
// _ <- e26
204+
} yield ()
205+
}

0 commit comments

Comments
 (0)