@@ -1166,87 +1166,33 @@ object Types {
1166
1166
* is approximated by constraining `A` to be =:= to `Int` and returning `ArrayBuffer[Int]`
1167
1167
* instead of `ArrayBuffer[? >: Int | A <: Int & A]`
1168
1168
*
1169
- * Hard unions inside soft ones are treated specially. For illustration assume we
1170
- * want to widen the type `(A | C) \/ (B | C)` where `\/` means soft union and `|`
1171
- * means hard union. In that case, the hard unions `A | C` and `B | C` are treated
1172
- * in an asymmetric way. Only the first parts `A` and `B` are joined and the rest
1173
- * is added again with a hard union to the result. So
1174
- *
1175
- * widenUnion[ (A | C) \/ (B | C) ]
1176
- * = widenUnion[ A \/ B ] | C | C
1177
- * = D | C | C
1178
- * = D | C
1179
- *
1180
- * In general, If a hard union A | B_1 | ... | B_n is part of of a soft union,
1181
- * only A forms part of the join, and B_1, ..., B_n are pushed out, just `C` is
1182
- * pushed out above. All types that are pushed out are recombined with the result
1183
- * of the join with a lub, but that lub yields again a hard union, not a soft one.
1184
- *
1185
1169
* Exception (if `-YexplicitNulls` is set): if this type is a nullable union (i.e. of the form `T | Null`),
1186
1170
* then the top-level union isn't widened. This is needed so that type inference can infer nullable types.
1187
1171
*/
1188
- def widenUnion (using Context ): Type = widen. match {
1172
+ def widenUnion (using Context ): Type = widen match
1189
1173
case tp @ OrNull (tp1): OrType =>
1190
1174
// Don't widen `T|Null`, since otherwise we wouldn't be able to infer nullable unions.
1191
1175
val tp1Widen = tp1.widenUnionWithoutNull
1192
1176
if (tp1Widen.isRef(defn.AnyClass )) tp1Widen
1193
1177
else tp.derivedOrType(tp1Widen, defn.NullType )
1194
1178
case tp =>
1195
1179
tp.widenUnionWithoutNull
1196
- }
1197
-
1198
- def widenUnionWithoutNull (using Context ): Type =
1199
-
1200
- // Split hard union `A | B1 | ... | Bn` into leftmost part `A` and list of
1201
- // pushed out parts `B1, ..., Bn`.
1202
- def splitAlts (tp : Type , follow : List [Type ]): (Type , List [Type ]) = tp match
1203
- case tp as OrType (lhs, rhs) if ! tp.isSoft =>
1204
- splitAlts(lhs, rhs :: follow)
1205
- case _ =>
1206
- (tp, follow)
1207
-
1208
- // Convert any soft unions in result of lub to hard ones */
1209
- def harden (tp : Type ): Type = tp match
1210
- case tp as OrType (tp1, tp2) if tp.isSoft =>
1211
- OrType (harden(tp1), harden(tp2), soft = false )
1212
- case _ =>
1213
- tp
1214
-
1215
- def recombine (tp1 : Type , tp2 : Type ) = harden(TypeComparer .lub(tp1, tp2))
1216
1180
1217
- inline val asymmetric = false
1218
-
1219
- widen match
1220
- case tp @ OrType (lhs, rhs) =>
1221
- if asymmetric then
1222
- if tp.isSoft then
1223
- val (lhsCore, lhsExtras) = splitAlts(lhs.widenUnionWithoutNull, Nil )
1224
- val (rhsCore, rhsExtras) = splitAlts(rhs.widenUnionWithoutNull, Nil )
1225
- val core = TypeComparer .lub(lhsCore, rhsCore, canConstrain = true ) match
1226
- case union : OrType => union.join
1227
- case res => res
1228
- rhsExtras.foldLeft(lhsExtras.foldLeft(core)(recombine))(recombine)
1229
- else
1230
- val lhs1 = lhs.widenUnionWithoutNull
1231
- val rhs1 = rhs.widenUnionWithoutNull
1232
- if (lhs1 eq lhs) && (rhs1 eq rhs) then tp else recombine(lhs1, rhs1)
1233
- else if tp.isSoft then
1234
- TypeComparer .lub(lhs.widenUnionWithoutNull, rhs.widenUnionWithoutNull, canConstrain = true ) match
1235
- case union : OrType => union.join
1236
- case res => res
1237
- else
1238
- tp.derivedOrType(lhs.widenUnionWithoutNull, rhs.widenUnionWithoutNull)
1239
- case tp @ AndType (tp1, tp2) =>
1240
- tp derived_& (tp1.widenUnionWithoutNull, tp2.widenUnionWithoutNull)
1241
- case tp : RefinedType =>
1242
- tp.derivedRefinedType(tp.parent.widenUnion, tp.refinedName, tp.refinedInfo)
1243
- case tp : RecType =>
1244
- tp.rebind(tp.parent.widenUnion)
1245
- case tp : HKTypeLambda =>
1246
- tp.derivedLambdaType(resType = tp.resType.widenUnion)
1247
- case tp =>
1248
- tp
1249
- end widenUnionWithoutNull
1181
+ def widenUnionWithoutNull (using Context ): Type = widen match
1182
+ case tp @ OrType (lhs, rhs) if tp.isSoft =>
1183
+ TypeComparer .lub(lhs.widenUnionWithoutNull, rhs.widenUnionWithoutNull, canConstrain = true ) match
1184
+ case union : OrType => union.join
1185
+ case res => res
1186
+ case tp : AndOrType =>
1187
+ tp.derivedAndOrType(tp.tp1.widenUnionWithoutNull, tp.tp2.widenUnionWithoutNull)
1188
+ case tp : RefinedType =>
1189
+ tp.derivedRefinedType(tp.parent.widenUnion, tp.refinedName, tp.refinedInfo)
1190
+ case tp : RecType =>
1191
+ tp.rebind(tp.parent.widenUnion)
1192
+ case tp : HKTypeLambda =>
1193
+ tp.derivedLambdaType(resType = tp.resType.widenUnion)
1194
+ case tp =>
1195
+ tp
1250
1196
1251
1197
/** Widen all top-level singletons reachable by dealiasing
1252
1198
* and going to the operands of & and |.
0 commit comments