Scala Programming Language
  1. Scala Programming Language
  2. SI-5589

For-comprehension on Either.RightProjection with Tuple2 extractor in generator fails to compile

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: Scala 2.9.1
    • Fix Version/s: Backlog
    • Component/s: Type Checker
    • Labels:
      None

      Description

      The for-comprehension in the attempt method fails to compile, despite the fact that the nearly-equivalent desugared version works fine.

      object Test extends App {
        def attempt(in: Int): Either[Int, (String, Int)] = in match {
          case 0 => Right("fubar", 13)
          
          case n => {
            val recLeft = attempt(math.abs(n) - 1)
            val recRight = attempt(-math.abs(n) + 1)
            
            // compiles!
            recLeft.right flatMap {
              case (strLeft, numLeft) => {
                recRight.right map {
                  case (strRight, numRight) =>
                    (strLeft + strRight, numLeft + numRight)
                }
              }
            }
            
            // doesn't compile!
            /* for {
              (strLeft, numLeft) <- recLeft.right
              (strRight, numRight) <- recRight.right
            } yield (strLeft + strRight, numLeft + numRight) */
          }
        }
        
        attempt(42)
        println("Nothing happens")
      }
      

      I'm guessing it has something to do with filter, since that's one thing that's missing from my desugared version.

        Issue Links

          Activity

          Hide
          Paul Phillips added a comment -

          Minimized.

          class A {
            // First three compile.
            def f1(x: Either[Int, String])        = x.right map (y => y)
            def f2(x: Either[Int, String])        = for (y <- x.right) yield y
            def f3(x: Either[Int, (String, Int)]) = x.right map { case (y1, y2) => (y1, y2) }
            // Last one fails.
            def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2))
          /**
          ./a.scala:5: error: constructor cannot be instantiated to expected type;
           found   : (T1, T2)
           required: Either[Nothing,(String, Int)]
            def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2))
                                                         ^
          ./a.scala:5: error: not found: value y1
            def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2))
                                                                                      ^
          ./a.scala:5: error: not found: value y2
            def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2))
                                                                                          ^
          three errors found
          **/
          }
          
          Show
          Paul Phillips added a comment - Minimized. class A { // First three compile. def f1(x: Either[Int, String]) = x.right map (y => y) def f2(x: Either[Int, String]) = for (y <- x.right) yield y def f3(x: Either[Int, (String, Int)]) = x.right map { case (y1, y2) => (y1, y2) } // Last one fails. def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) /** ./a.scala:5: error: constructor cannot be instantiated to expected type; found : (T1, T2) required: Either[Nothing,(String, Int)] def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) ^ ./a.scala:5: error: not found: value y1 def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) ^ ./a.scala:5: error: not found: value y2 def f4(x: Either[Int, (String, Int)]) = for ((y1, y2) <- x.right) yield ((y1, y2)) ^ three errors found **/ }
          Hide
          Paul Phillips added a comment -

          See also SI-1336, to which this is related. The unnecessary call to filter which it injects leads to Nothing being inferred for the type parameter to filter, which leads to typing failure.

          Show
          Paul Phillips added a comment - See also SI-1336 , to which this is related. The unnecessary call to filter which it injects leads to Nothing being inferred for the type parameter to filter, which leads to typing failure.
          Hide
          Paul Phillips added a comment -

          Fixed in c82ecabad6 .

          Show
          Paul Phillips added a comment - Fixed in c82ecabad6 .
          Hide
          Jason Zaugg added a comment -
          Show
          Jason Zaugg added a comment - Reverted in https://github.com/scala/scala/pull/1893

            People

            • Assignee:
              Unassigned
              Reporter:
              Daniel Spiewak
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:

                Development