Skip to content

Show root of stackoverflow in IsFullyDefinedAccumulator #12649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2021

Conversation

odersky
Copy link
Contributor

@odersky odersky commented May 30, 2021

This gives a better diagnosis for #12640.

case tp =>
foldOver(x, tp)
catch case ex: Throwable =>
handleRecursive("traverse ", s"${tp.show}" , ex)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be useful to print the constraints here too, since the loop might be due to cyclic constraints as we traverse type variables.

Copy link
Contributor Author

@odersky odersky May 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you go. With that we get:

-- Error: i12640.scala:15:42 ---------------------------------------------------
15 |         case Some(s1,a) => Cons(a, () => unfold(s1,f))
   |                                          ^
   |Recursion limit exceeded.
   |Maybe there is an illegal cyclic reference?
   |If that's not the case, you could also try to increase the stacksize using the -Xss JVM option.
   |A recurring operation is (inner to outer):
   |
   |  traverse  (((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ]
   |) => R in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R) in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |  Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  (((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ]
   |) => R in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R) in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |  Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  (((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ]
   |) => R in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R) in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  ...
   |
   |  traverse  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |  Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  (((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ]
   |) => R in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |    Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |  ]
   |) => R in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R) in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  [T] =>> 
   |  x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  Nothing in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  Nothing[Option[((S, S => F[Option[(S, T)]]), Nothing)]] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)
   |  traverse  ((S, S => F[Option[(S, T)]])) => 
   |  Nothing[Option[((S, S => F[Option[(S, T)]]), Nothing)]] in Constraint(
   | uninstantiated variables: 
   | constrained types: [A, B](fa: F[A])(f: A => F[B]): F[B], 
   |  [F[_$3], T](head: T, tailFun: () => F[x.CpsStream[F, T]]): x.Cons[F, T]
   |, 
   |  [S, F[_$5], T]
   |    (s0: S)
   |      (f: S => F[Option[(S, T)]])
   |        (implicit evidence$1: x.CpsMonad[F]): F[x.CpsStream[F, T]]
   | bounds: 
   |     A := Option[(S, T)]
   |     B := x.CpsStream[F, T]
   |     F := 
   |    [R] =>> (((S, S => F[Option[(S, T)]])) => 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), 
   |        Option[((S, S => F[Option[(S, T)]]), Nothing)]
   |      ]
   |    ) => R
   |     T
   |     >: (a : T) | 
   |      x.CpsStream[
   |        [T] =>> 
   |          x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R)
   |            , 
   |          T]
   |      , Nothing]
   |     S := (S, S => F[Option[(S, T)]])
   |     F := 
   |    [T] =>> 
   |      x.CpsStream[([R] =>> (((S, S => F[Option[(S, T)]])) => Nothing) => R), T]
   |     T
   | ordering: 
   |)

@rssh My gut feeling is that you are trying to push higher-kinded types too far here. I mean nobody stops you, but if you want code to be widely used then crazy types and constraints like this are a show-stopper. Even if the compiler survives this, how will anybody be able to debug type errors when they arise?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, that original (unminimized) bug source is an attempt to create adapter for a well-known library [fs2 if anybody care], so the genie was already released from the bottle a long time ago.

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it looks like this is already fixed on master, if I run the testcase there I only get type errors and no stackoverflow, in this PR we get a stackoverflow because it's based on a week-old version of master but meanwhile e58ece8 already added stackoverflow handling.

@odersky
Copy link
Contributor Author

odersky commented May 30, 2021

I added a regression test. I still have some doubts what goes on here since with the added handleRecursion the stackoverflow problem gets reported. Bit without it, the SO goes away and we see the other errors instead.

@smarter
Copy link
Member

smarter commented May 30, 2021

That's because handleRecursive throws a RecursionOverflow so it's not caught by the catch ex: StackOverflowError added in e58ece8

@odersky
Copy link
Contributor Author

odersky commented May 31, 2021

Doh! Completely forgot about that one.

@odersky odersky merged commit d28b891 into scala:master May 31, 2021
@odersky odersky deleted the fix-12640 branch May 31, 2021 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants