diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 1432c56914ec..777f43931e13 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1118,15 +1118,15 @@ object Types { /** Widen this type and if the result contains embedded union types, replace * them by their joins. - * "Embedded" means: inside intersectons or recursive types, or in prefixes of refined types. + * "Embedded" means: inside type lambdas, intersections or recursive types, or in prefixes of refined types. * If an embedded union is found, we first try to simplify or eliminate it by * re-lubbing it while allowing type parameters to be constrained further. * Any remaining union types are replaced by their joins. * - * For instance, if `A` is an unconstrained type variable, then - * - * ArrayBuffer[Int] | ArrayBuffer[A] - * + * For instance, if `A` is an unconstrained type variable, then + * + * ArrayBuffer[Int] | ArrayBuffer[A] + * * is approximated by constraining `A` to be =:= to `Int` and returning `ArrayBuffer[Int]` * instead of `ArrayBuffer[? >: Int | A <: Int & A]` * @@ -1155,6 +1155,8 @@ object Types { tp.derivedRefinedType(tp.parent.widenUnion, tp.refinedName, tp.refinedInfo) case tp: RecType => tp.rebind(tp.parent.widenUnion) + case tp: HKTypeLambda => + tp.derivedLambdaType(resType = tp.resType.widenUnion) case tp => tp } diff --git a/tests/pos/i9479.scala b/tests/pos/i9479.scala new file mode 100644 index 000000000000..4477722a9051 --- /dev/null +++ b/tests/pos/i9479.scala @@ -0,0 +1,10 @@ +trait Applicative[F[_]] + +def traverse[F[_]: Applicative, A, B](as: List[A])(f: A => F[B]) = ??? + +object Test { + implicit def eitherApplicative[A]: Applicative[[X] =>> Either[A, X]] = ??? + + // Used to fail looking for `Applicative[[X] =>> Right[Nothing, X] | Left[Int, X]]` + traverse(List(1, 2))(i => if (true) Right(i) else Left(i)) +}