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

Type parameter ignored in selectDynamic invocation

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: Scala 2.10.1
    • Component/s: Type Checker
    • Labels:
      None

      Description

      As noticed by Dinko Srkoc in http://thread.gmane.org/gmane.comp.lang.scala.user/58246 sometimes the type parameter on a selectDynamic call gets lost.

      With this definition:

      import language.dynamics
      
      class C(v: Any) extends Dynamic {
        def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
        def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
      }
      

      one gets this behaviour:

      scala> new C(42).foo[Int].get
      java.lang.ClassCastException: java.lang.Integer cannot be cast to scala.runtime.Nothing$
      

      This happens because in Typers.scala, mkInvoke is called with the following cxTree:
      new C.<init>(42).foo[Int].get

      Note that the outer element of that tree is a Select(..., "get"), and that's not handled by mkInvoke:

        val (outer, explicitTargs) = cxTree1 match {
          case TypeApply(fun, targs)              => (fun, targs)
          case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
          case t                                  => (t, Nil)
        }
      

      That can be fixed by adding another case:

        val (outer, explicitTargs) = cxTree1 match {
          case TypeApply(fun, targs)              => (fun, targs)
          case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
          case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
          case t                                  => (t, Nil)
        }
      

      With that change, the examples work as expected:

      scala> new C(42).foo[Int]().get
      res0: Int = 42
      
      scala> new C(42).foo[Int].get
      res1: Int = 42 
      

        Activity

        Hide
        Paul Phillips added a comment -

        Nice job, you're almost there! Sending a pull request with the fix and a test case makes our lives tremendously easier.

        Show
        Paul Phillips added a comment - Nice job, you're almost there! Sending a pull request with the fix and a test case makes our lives tremendously easier.
        Hide
        Jan Niehusmann added a comment -

        Maybe a duplicate of SI-6320

        Show
        Jan Niehusmann added a comment - Maybe a duplicate of SI-6320
        Hide
        Jan Niehusmann added a comment -

        There are similar cases not covered by the mentioned patch:

        scala> new C(42).foo[String].get
        java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        
        scala> new C(42).foo[String].get : Int
        res2: Int = 42
        

        Here, the [String] parameter is ignored, again. This time because the cxTree starts with the type annotation: (new C.<init>(42).foo[String].get: Int)

        Is there an easy way to find everything which can possibly get attached to cxTree?

        Show
        Jan Niehusmann added a comment - There are similar cases not covered by the mentioned patch: scala> new C(42).foo[String].get java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String scala> new C(42).foo[String].get : Int res2: Int = 42 Here, the [String] parameter is ignored, again. This time because the cxTree starts with the type annotation: (new C.<init>(42).foo [String] .get: Int) Is there an easy way to find everything which can possibly get attached to cxTree?
        Show
        Jan Niehusmann added a comment - https://github.com/scala/scala/pull/1619
        Hide
        Jan Niehusmann added a comment -

        I'd guess that there are other possible contents of cxTree not yet handled. Is there a better way to fix this than to add all such cases manually to mkInvoke?

        Show
        Jan Niehusmann added a comment - I'd guess that there are other possible contents of cxTree not yet handled. Is there a better way to fix this than to add all such cases manually to mkInvoke?
        Hide
        Jan Niehusmann added a comment -

        pull request against 2.10.x at https://github.com/scala/scala/pull/1621

        Show
        Jan Niehusmann added a comment - pull request against 2.10.x at https://github.com/scala/scala/pull/1621
        Hide
        Paul Phillips added a comment -

        That PR was merged, but this is not fixed in general; https://github.com/scala/scala/pull/1681 should fix them all.

        Show
        Paul Phillips added a comment - That PR was merged, but this is not fixed in general; https://github.com/scala/scala/pull/1681 should fix them all.
        Hide
        Paul Phillips added a comment -

        edbcc64

        Show
        Paul Phillips added a comment - edbcc64

          People

          • Assignee:
            Paul Phillips
            Reporter:
            Jan Niehusmann
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development