diff --git a/modules/core/src/main/scala/result.scala b/modules/core/src/main/scala/result.scala index 833924d3..0b061264 100644 --- a/modules/core/src/main/scala/result.scala +++ b/modules/core/src/main/scala/result.scala @@ -404,7 +404,7 @@ trait ResultInstances extends ResultInstances0 { case Result.Warning(ps, a) => ff match { case err @ Result.InternalError(_) => err - case fail @ Result.Failure(_) => fail + case Result.Failure(ps0) => Result.Failure(ps0 ++ ps) case Result.Success(f) => Result.Warning(ps, f(a)) case Result.Warning(ps0, f) => Result.Warning(ps0 ++ ps, f(a)) } diff --git a/modules/core/src/test/scala/laws/ResultSuite.scala b/modules/core/src/test/scala/laws/ResultSuite.scala index ea9add25..4c718a97 100644 --- a/modules/core/src/test/scala/laws/ResultSuite.scala +++ b/modules/core/src/test/scala/laws/ResultSuite.scala @@ -20,6 +20,7 @@ import cats.data.NonEmptyChain import cats.kernel.laws.discipline.{EqTests, SemigroupTests} import cats.laws.discipline.{ApplicativeTests, MonadErrorTests, ParallelTests, TraverseTests} import cats.laws.discipline.arbitrary._ +import cats.syntax.parallel._ import munit.DisciplineSuite import org.scalacheck.{Arbitrary, Cogen, Gen} import org.scalacheck.Arbitrary.{arbitrary => getArbitrary} @@ -71,4 +72,17 @@ class ResultSuite extends DisciplineSuite { checkAll("Eq[Result[Int]]", EqTests[Result[Int]].eqv) checkAll("Applicative[ResultT] @ Int", ApplicativeTests[Result].applicative[Int, Int, Int]) + + // A `Warning` carries problems as well as a value, so combining one with a `Failure` must + // retain both sets whichever side the warning is on. + test("Parallel accumulates a warning's problems on either side of a failure") { + val warning: Result[Int] = Result.Warning(NonEmptyChain(Problem("w")), 1) + val failure: Result[Int] = Result.Failure(NonEmptyChain(Problem("f"))) + + def messages(r: Result[(Int, Int)]): List[String] = + r.toProblems.toList.map(_.message) + + assertEquals(messages((warning, failure).parTupled), List("w", "f")) + assertEquals(messages((failure, warning).parTupled), List("f", "w")) + } }