From 754b68e8410efffafb688a1b2f2a4b25023bb75d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 24 Oct 2022 11:44:04 +0100 Subject: [PATCH] Fix handling of baseType of (A & Double) | Null --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 5 +++++ tests/pos/i16236.scala | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i16236.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 332129e72850..3e5b07d8d7e5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -369,7 +369,7 @@ object TypeOps: } // Step 3: Intersect base classes of both sides - val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect) + val commonBaseClasses = tp.mapReduceAndOr(_.baseClasses)(intersect) val doms = dominators(commonBaseClasses, Nil) def baseTp(cls: ClassSymbol): Type = tp.baseType(cls).mapReduceOr(identity)(mergeRefinedOrApplied) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index dc1f02c8a0fd..1c326195c9c4 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -478,6 +478,11 @@ object Types { case _ => f(this) } + final def mapReduceAndOr[T](f: Type => T)(g: (T, T) => T)(using Context): T = stripTypeVar match { + case tp: AndOrType => g(tp.tp1.mapReduceAndOr(f)(g), tp.tp2.mapReduceAndOr(f)(g)) + case _ => f(this) + } + // ----- Associated symbols ---------------------------------------------- /** The type symbol associated with the type */ diff --git a/tests/pos/i16236.scala b/tests/pos/i16236.scala new file mode 100644 index 000000000000..6451689ad94d --- /dev/null +++ b/tests/pos/i16236.scala @@ -0,0 +1,9 @@ +trait A + +def consume[T](t: T): Unit = () + +def fails(p: (Double & A) | Null): Unit = consume(p) // was: assertion failed: & A + +def switchedOrder(p: (A & Double) | Null): Unit = consume(p) // ok +def nonPrimitive(p: (String & A) | Null): Unit = consume(p) // ok +def notNull(p: (Double & A)): Unit = consume(p) // ok