Skip to content

Commit 1ee888a

Browse files
authored
Merge pull request #2742 from dotty-staging/fix-#2741
Fix #2741: Handle wildcard types in unions and intersections.
2 parents bf22702 + 9783152 commit 1ee888a

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
@@ -1423,8 +1423,11 @@ object Types {
14231423
/** A marker trait for types that can be types of values or prototypes of value types */
14241424
trait ValueTypeOrProto extends TermType
14251425

1426+
/** A marker trait for types that can be types of values or wildcards */
1427+
trait ValueTypeOrWildcard extends TermType
1428+
14261429
/** A marker trait for types that can be types of values or that are higher-kinded */
1427-
trait ValueType extends ValueTypeOrProto
1430+
trait ValueType extends ValueTypeOrProto with ValueTypeOrWildcard
14281431

14291432
/** A marker trait for types that are guaranteed to contain only a
14301433
* single non-null value (they might contain null in addition).
@@ -2317,7 +2320,8 @@ object Types {
23172320

23182321
object AndType {
23192322
def apply(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = {
2320-
assert(tp1.isValueType && tp2.isValueType, i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
2323+
assert(tp1.isInstanceOf[ValueTypeOrWildcard] &&
2324+
tp2.isInstanceOf[ValueTypeOrWildcard], i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
23212325
unchecked(tp1, tp2)
23222326
}
23232327

@@ -2340,7 +2344,8 @@ object Types {
23402344

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

2343-
assert(tp1.isInstanceOf[ValueType] && tp2.isInstanceOf[ValueType])
2347+
assert(tp1.isInstanceOf[ValueTypeOrWildcard] &&
2348+
tp2.isInstanceOf[ValueTypeOrWildcard], s"$tp1 $tp2")
23442349
def isAnd = false
23452350

23462351
private[this] var myJoin: Type = _
@@ -2375,7 +2380,8 @@ object Types {
23752380
unique(new CachedOrType(tp1, tp2))
23762381
}
23772382
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
2378-
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
2383+
if (tp1 eq tp2) tp1
2384+
else apply(tp1, tp2)
23792385
}
23802386

23812387
// ----- ExprType and LambdaTypes -----------------------------------
@@ -3506,7 +3512,7 @@ object Types {
35063512
object TryDynamicCallType extends FlexType
35073513

35083514
/** Wildcard type, possibly with bounds */
3509-
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with TermType {
3515+
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with ValueTypeOrWildcard {
35103516
def derivedWildcardType(optBounds: Type)(implicit ctx: Context) =
35113517
if (optBounds eq this.optBounds) this
35123518
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)