Details

      Description

      This was a difficult minimization. g must be overloaded; the expression must be typed as an argument; and both legs of the if as well as the call to map appear to be necessary. Remove any of the above, and one sees the appropriate error message - List(g) is attempting to call g with a String rather than one of the types upon which it is overloaded.

      class C1
      class C2
      class A {
        def f(x: Any) = x
        def g(x: C1): String = "A"
        def g(x: C2): String = "B"
        
        def crash() = f(List[String]() flatMap { x =>
          if (false) List(g(x)) else List[C1]() map g
        })
      }
      // at scala.Predef$.assert(Predef.scala:162)
      // at scala.tools.nsc.Global.assert(Global.scala:235)
      // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:291)
      // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$transformArgs$1.apply(SuperAccessors.scala:74)
      // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$transformArgs$1.apply(SuperAccessors.scala:71)
      // at scala.reflect.internal.TreeInfo$$anonfun$mapMethodParamsAndArgs$1.apply(TreeInfo.scala:115)
      // at scala.reflect.internal.TreeInfo$$anonfun$mapMethodParamsAndArgs$1.apply(TreeInfo.scala:115)
      // at scala.reflect.internal.util.Collections$class.foreach2(Collections.scala:150)
      // at scala.reflect.internal.SymbolTable.foreach2(SymbolTable.scala:12)
      

        Activity

        Hide
        Paul Phillips added a comment -

        It's a regression since 2.9.

        % scalac29 -d /tmp bug.scala 
        bug.scala:9: error: overloaded method value g with alternatives:
          (x: C2)String <and>
          (x: C1)String
         cannot be applied to (String)
            if (false) List(g(x)) else List[C1]() map g
                            ^
        one error found
        
        Show
        Paul Phillips added a comment - It's a regression since 2.9. % scalac29 -d /tmp bug.scala bug.scala:9: error: overloaded method value g with alternatives: (x: C2)String <and> (x: C1)String cannot be applied to (String) if (false) List(g(x)) else List[C1]() map g ^ one error found
        Hide
        Jason Zaugg added a comment -

        That's slippery. Observing it from a safe distance:

        
        class C1
        class C2
        class A {
          def f(x: Any) = x
          def g(x: C1): String = "A"
          def g(x: C2): String = "B"
        
          def hof(x: String => Any) {}
        
          class X[A]() {
            def this(a: A) = this()
            def map[B](f: A => Any): Any = ??? // remove type parameter => avoid crash
          }
        
          def crash() = hof { x =>
            if (false) new X(g("")) else new X[C1]().map(g)
        
            // Other lubby situations crash:
            //
            // (true: Boolean) match {
            //   case false => new X(g("")); case true => new X[C1]().map(g)
            // }
        
            // try new X(g("")) catch { case _ => new X[C1]().map(g) }
        
            // List(new X(g("")), new X[C1]().map(g))
          }
        
          // No crash if the argument isn't a function
          // def nocrash1() = identity {
          //   if (false) new X(g("")) else new X[C1]().map(g)
          // }
        }
        

        The error is buffered into a Context deep down in type checking, but it doesn't get reported later on. It's pretty hard to see through the thicket of silent(...) / tryTwice(...) etc.

        Show
        Jason Zaugg added a comment - That's slippery. Observing it from a safe distance: class C1 class C2 class A { def f(x: Any) = x def g(x: C1): String = "A" def g(x: C2): String = "B" def hof(x: String => Any) {} class X[A]() { def this(a: A) = this() def map[B](f: A => Any): Any = ??? // remove type parameter => avoid crash } def crash() = hof { x => if (false) new X(g("")) else new X[C1]().map(g) // Other lubby situations crash: // // (true: Boolean) match { // case false => new X(g("")); case true => new X[C1]().map(g) // } // try new X(g("")) catch { case _ => new X[C1]().map(g) } // List(new X(g("")), new X[C1]().map(g)) } // No crash if the argument isn't a function // def nocrash1() = identity { // if (false) new X(g("")) else new X[C1]().map(g) // } } The error is buffered into a Context deep down in type checking, but it doesn't get reported later on. It's pretty hard to see through the thicket of silent(...) / tryTwice(...) etc.
        Hide
        A. P. Marki added a comment -

        In SI-5687, the assert fails on an expr of the form new C().f().g() where C is "erroneous or inaccessible type" because of a bad type member. Only the top Apply gets error type.

        Show
        A. P. Marki added a comment - In SI-5687 , the assert fails on an expr of the form new C().f().g() where C is "erroneous or inaccessible type" because of a bad type member. Only the top Apply gets error type.
        Hide
        Hubert Plociniczak added a comment -

        SI-5687 is not related to this one at all.

        Show
        Hubert Plociniczak added a comment - SI-5687 is not related to this one at all.
        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/commit/e9a696

          People

          • Assignee:
            Hubert Plociniczak
            Reporter:
            Paul Phillips
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development