File tree 4 files changed +80
-10
lines changed
compiler/src/dotty/tools/dotc/core
4 files changed +80
-10
lines changed Original file line number Diff line number Diff line change @@ -194,12 +194,16 @@ object TypeOps:
194
194
*/
195
195
def orDominator (tp : Type )(using Context ): Type = {
196
196
197
- /** a faster version of cs1 intersect cs2 */
198
- def intersect (cs1 : List [ClassSymbol ], cs2 : List [ClassSymbol ]): List [ClassSymbol ] = {
199
- val cs2AsSet = new util.HashSet [ClassSymbol ](128 )
200
- cs2.foreach(cs2AsSet += _)
201
- cs1.filter(cs2AsSet.contains)
202
- }
197
+ /** a faster version of cs1 intersect cs2 that treats bottom types correctly */
198
+ def intersect (cs1 : List [ClassSymbol ], cs2 : List [ClassSymbol ]): List [ClassSymbol ] =
199
+ if cs1.head == defn.NothingClass then cs2
200
+ else if cs2.head == defn.NothingClass then cs1
201
+ else if cs1.head == defn.NullClass && ! ctx.explicitNulls && cs2.head.derivesFrom(defn.ObjectClass ) then cs2
202
+ else if cs2.head == defn.NullClass && ! ctx.explicitNulls && cs1.head.derivesFrom(defn.ObjectClass ) then cs1
203
+ else
204
+ val cs2AsSet = new util.HashSet [ClassSymbol ](128 )
205
+ cs2.foreach(cs2AsSet += _)
206
+ cs1.filter(cs2AsSet.contains)
203
207
204
208
/** The minimal set of classes in `cs` which derive all other classes in `cs` */
205
209
def dominators (cs : List [ClassSymbol ], accu : List [ClassSymbol ]): List [ClassSymbol ] = (cs : @ unchecked) match {
Original file line number Diff line number Diff line change @@ -3148,10 +3148,7 @@ object Types {
3148
3148
/** Replace or type by the closest non-or type above it */
3149
3149
def join (using Context ): Type = {
3150
3150
if (myJoinPeriod != ctx.period) {
3151
- myJoin =
3152
- if tp1 frozen_<:< tp2 then tp2
3153
- else if tp2 frozen_<:< tp1 then tp1
3154
- else TypeOps .orDominator(this )
3151
+ myJoin = TypeOps .orDominator(this )
3155
3152
core.println(i " join of $this == $myJoin" )
3156
3153
assert(myJoin != this )
3157
3154
myJoinPeriod = ctx.period
Original file line number Diff line number Diff line change
1
+
2
+ class A {
3
+ def get (): Int = 0
4
+ }
5
+
6
+ class B extends A {}
7
+
8
+ class C extends A {}
9
+
10
+ def test1 = {
11
+ val s : String | Null = ???
12
+ val l = s.length
13
+
14
+ val a : A | Null = new A
15
+ a.get()
16
+
17
+ val bc : B | C = new B
18
+ bc.get()
19
+
20
+ val bcn : B | (C | Null ) = new C
21
+ bcn.get()
22
+
23
+ val bnc : (B | Null ) | C = null
24
+ bnc.get()
25
+
26
+ val abcn : A | B | C | Null = new A
27
+ abcn.get()
28
+ }
29
+
30
+ def test2 = {
31
+ val s : String | Nothing = ???
32
+ val l = s.length
33
+
34
+ val a : A | Nothing = new A
35
+ a.get()
36
+
37
+ val bc : B | C = new B
38
+ bc.get()
39
+
40
+ val bcn : B | (C | Nothing ) = new C
41
+ bcn.get()
42
+
43
+ val bnc : (B | Nothing ) | C = new B
44
+ bnc.get()
45
+
46
+ val abcn : A | B | C | Nothing = new A
47
+ abcn.get()
48
+ }
Original file line number Diff line number Diff line change
1
+ object Main :
2
+ class Null
3
+ type Optional [A ] = A | Null
4
+
5
+ val maybeInt : Optional [Int ] = 1
6
+
7
+ // simplest typeclass
8
+ trait TC [F [_]]
9
+
10
+ // given instances for our Optional and standard Option[_]
11
+ given g1 : TC [Optional ] = ???
12
+ given g2 : TC [Option ] = ???
13
+
14
+ def summonTC [F [_], A ](f : F [A ])(using TC [F ]): Unit = ???
15
+
16
+ summonTC(Option (42 )) // OK
17
+
18
+ summonTC[Optional , Int ](maybeInt) // OK
19
+
20
+ summonTC(maybeInt)
21
+
You can’t perform that action at this time.
0 commit comments