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

Implicit conversions fail when overriding implicit val from super trait

    Details

      Description

      Consider this:

      import scala.concurrent.duration._
      
      trait Foo { implicit val timeout = 1 second }
      trait Bar extends Foo { implicit override val timeout = 2 seconds }
      

      In 2.10.0-RC2 and 2.10.0-RC3, the implicit conversion that gives the seconds method to Int fails:

      Welcome to Scala version 2.10.0-RC3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
      Type in expressions to have them evaluated.
      Type :help for more information.
      
      scala> :load foo.scala
      Loading foo.scala...
      import scala.concurrent.duration._
      warning: there were 1 feature warnings; re-run with -feature for details
      defined trait Foo
      <console>:11: error: value seconds is not a member of Int
             trait Bar extends Foo { implicit override val timeout = 2 seconds }
                                                                       ^
      

      When the implicit keyword is removed from the overridden val, the implicit conversion works properly.

        Activity

        Hide
        Paul Phillips added a comment -

        For some reason if the overriding implicit is typed without an expected type, the failure is reported. It looks to me like it proceeds to type the override with an expected type of Int, at which point it finds the implicit, but it's too late. Supposed to be a silent context being used somewhere?

        import scala.concurrent.duration._
        
        trait Foo { implicit val v: Duration = 1.seconds }
        trait Bar1 extends Foo { override implicit val v = 2.seconds } // fails
        trait Bar2 extends Foo { override implicit val v: Duration = 2.seconds } // compiles
        
        Show
        Paul Phillips added a comment - For some reason if the overriding implicit is typed without an expected type, the failure is reported. It looks to me like it proceeds to type the override with an expected type of Int, at which point it finds the implicit, but it's too late. Supposed to be a silent context being used somewhere? import scala.concurrent.duration._ trait Foo { implicit val v: Duration = 1.seconds } trait Bar1 extends Foo { override implicit val v = 2.seconds } // fails trait Bar2 extends Foo { override implicit val v: Duration = 2.seconds } // compiles
        Hide
        Jason Zaugg added a comment -

        I'm looking into this. My test case:

        object O {
          implicit def i: Int = 0
        }
        
        import O._
         
        trait Foo {
          implicit val v1: Any
          implicit val d1: Any
                   val v2: Any
          implicit val v3: Any
        }
        
        trait Bar1 extends Foo {
          implicit val v1      = {implicitly[Int]; ()} // fail
                   def d1      = {implicitly[Int]; ()} // okay
          implicit val v2      = {implicitly[Int]; ()} // okay
          implicit val v3: Any = {implicitly[Int]; ()} // okay
        
        }
        
        
        Show
        Jason Zaugg added a comment - I'm looking into this. My test case: object O { implicit def i: Int = 0 } import O._ trait Foo { implicit val v1: Any implicit val d1: Any val v2: Any implicit val v3: Any } trait Bar1 extends Foo { implicit val v1 = {implicitly[Int]; ()} // fail def d1 = {implicitly[Int]; ()} // okay implicit val v2 = {implicitly[Int]; ()} // okay implicit val v3: Any = {implicitly[Int]; ()} // okay }
        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/pull/3263

          People

          • Assignee:
            Jason Zaugg
            Reporter:
            Michael Pilquist
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development