Skip to content

Commit 9783152

Browse files
committed
Fix #2741: Handle wildcard types in unions and intersections.
i2741.scala is a test case where this happens.
1 parent 57ee82c commit 9783152

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,8 +1417,11 @@ object Types {
14171417
/** A marker trait for types that can be types of values or prototypes of value types */
14181418
trait ValueTypeOrProto extends TermType
14191419

1420+
/** A marker trait for types that can be types of values or wildcards */
1421+
trait ValueTypeOrWildcard extends TermType
1422+
14201423
/** A marker trait for types that can be types of values or that are higher-kinded */
1421-
trait ValueType extends ValueTypeOrProto
1424+
trait ValueType extends ValueTypeOrProto with ValueTypeOrWildcard
14221425

14231426
/** A marker trait for types that are guaranteed to contain only a
14241427
* single non-null value (they might contain null in addition).
@@ -2311,7 +2314,8 @@ object Types {
23112314

23122315
object AndType {
23132316
def apply(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = {
2314-
assert(tp1.isValueType && tp2.isValueType, i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
2317+
assert(tp1.isInstanceOf[ValueTypeOrWildcard] &&
2318+
tp2.isInstanceOf[ValueTypeOrWildcard], i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
23152319
unchecked(tp1, tp2)
23162320
}
23172321

@@ -2334,7 +2338,8 @@ object Types {
23342338

23352339
abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType with AndOrType {
23362340

2337-
assert(tp1.isInstanceOf[ValueType] && tp2.isInstanceOf[ValueType])
2341+
assert(tp1.isInstanceOf[ValueTypeOrWildcard] &&
2342+
tp2.isInstanceOf[ValueTypeOrWildcard], s"$tp1 $tp2")
23382343
def isAnd = false
23392344

23402345
private[this] var myJoin: Type = _
@@ -2369,7 +2374,8 @@ object Types {
23692374
unique(new CachedOrType(tp1, tp2))
23702375
}
23712376
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
2372-
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
2377+
if (tp1 eq tp2) tp1
2378+
else apply(tp1, tp2)
23732379
}
23742380

23752381
// ----- ExprType and LambdaTypes -----------------------------------
@@ -3500,7 +3506,7 @@ object Types {
35003506
object TryDynamicCallType extends FlexType
35013507

35023508
/** Wildcard type, possibly with bounds */
3503-
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with TermType {
3509+
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with ValueTypeOrWildcard {
35043510
def derivedWildcardType(optBounds: Type)(implicit ctx: Context) =
35053511
if (optBounds eq this.optBounds) this
35063512
else if (!optBounds.exists) WildcardType

tests/pos/i2741.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object Result {
2+
type ResultF[F] = F | Errors
3+
type ResultF2[F] = F & Errors
4+
5+
case class Errors(msgs: Seq[String])
6+
7+
implicit class ResultFunctions[A](val res: ResultF[A]) extends AnyVal {
8+
def map[B](f: A => B): ResultF[B] = res match {
9+
case errs: Errors => errs
10+
case x: A => f(x)
11+
}
12+
}
13+
implicit class ResultFunctions2[A](val res: ResultF2[A]) extends AnyVal {
14+
def map[B](f: A => B): ResultF[B] = ???
15+
}
16+
}

0 commit comments

Comments
 (0)