@@ -76,17 +76,17 @@ class A extends C[A] with D
76
76
class B extends C [B ] with D with E
77
77
```
78
78
79
- The join of ` A | B ` is ` C[A | B] with D `
79
+ The join of ` A | B ` is ` C[A | B] & D `
80
80
81
81
## Type inference
82
82
83
- When inferring the result type of a definition (` val ` , ` var ` , or ` def ` ), if the
84
- type we are about to infer is a union type, we replace it by its join.
83
+ When inferring the result type of a definition (` val ` , ` var ` , or ` def ` ) and the
84
+ type we are about to infer is a union type, then we replace it by its join.
85
85
Similarly, when instantiating a type argument, if the corresponding type
86
86
parameter is not upper-bounded by a union type and the type we are about to
87
87
instantiate is a union type, we replace it by its join. This mirrors the
88
88
treatment of singleton types which are also widened to their underlying type
89
- unless explicitly specified. and the motivation is the same: inferring types
89
+ unless explicitly specified. The motivation is the same: inferring types
90
90
which are "too precise" can lead to unintuitive typechecking issues later on.
91
91
92
92
Note: Since this behavior limits the usability of union types, it might
@@ -127,6 +127,14 @@ trait B { def hello: String }
127
127
def test (x : A | B ) = x.hello // error: value `hello` is not a member of A | B
128
128
```
129
129
130
+ On the otherhand, the following would be allowed
131
+ ``` scala
132
+ trait C { def hello : String }
133
+ trait A extends C with D
134
+ trait B extends C with E
135
+
136
+ def test (x : A | B ) = x.hello // ok as `hello` is a member of the join of A | B which is C
137
+
130
138
## Exhaustivity checking
131
139
132
140
If the selector of a pattern match is a union type , the match is considered
0 commit comments