Skip to content
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

scalac sometimes ignores companion implicits #7291

Closed
scabug opened this issue Mar 23, 2013 · 10 comments
Closed

scalac sometimes ignores companion implicits #7291

scabug opened this issue Mar 23, 2013 · 10 comments
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Mar 23, 2013

trait Fooable[T]
object Fooable {
  implicit def conjure[T]: Fooable[T] = {
    println("conjure")
    new Fooable[T]{}
  }

}

object Main extends App {
  implicit def traversable[T, Coll[_] <: Traversable[_]](implicit
elem: Fooable[T]): Fooable[Coll[T]] = {
    println("traversable")
    new Fooable[Coll[T]]{}
  }
  implicitly[Fooable[List[Any]]] 
}

Should print "conjure", then "traversable". Currently it prints just "conjure". Details: http://groups.google.com/group/scala-internals/browse_thread/thread/f284df8ee19c2aba

@scabug
Copy link
Author

scabug commented Mar 23, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7291?orig=1
Reporter: @xeno-by
Affected Versions: 2.10.1, 2.11.0-M2

@scabug
Copy link
Author

scabug commented Mar 24, 2013

@xeno-by said (edited on Mar 24, 2013 10:41:52 AM UTC):
An interesting twist of events is that this bug is fixed in scalad, the type debugger. Now the question is how exactly this happened.

11:40 ~/Projects/Master/sandbox (master)$ scalad Test.scala -Xprint:typer
Initial compilation of sources...
[[syntax trees at end of                     typer]] // Test.scala
package <empty> {
  abstract trait Fooable[T >: Nothing <: Any] extends scala.AnyRef;
  object Fooable extends scala.AnyRef {
    def <init>(): Fooable.type = {
      Fooable.super.<init>();
      ()
    };
    implicit def conjure[T >: Nothing <: Any]: Fooable[T] = {
      scala.this.Predef.println("conjure");
      {
        final class $anon extends AnyRef with Fooable[T] {
          def <init>(): anonymous class $anon = {
            $anon.super.<init>();
            ()
          };
          <empty>
        };
        new $anon()
      }
    }
  };
  object Test extends AnyRef with App {
    def <init>(): Test.type = {
      Test.super.<init>();
      ()
    };
    implicit def traversable[T >: Nothing <: Any, Coll[_ >: Nothing <: Any] >: [_]Nothing <: [_]Traversable[_]](implicit elem: Fooable[T]): Fooable[Coll[T]] = {
      scala.this.Predef.println("traversable");
      {
        final class $anon extends AnyRef with Fooable[Coll[T]] {
          def <init>(): anonymous class $anon = {
            $anon.super.<init>();
            ()
          };
          <empty>
        };
        new $anon()
      }
    };
    scala.this.Predef.implicitly[Fooable[List[Any]]](Test.this.traversable[Any, List](Fooable.conjure[Any]))
  }
}

Initial compilation finished. Starting UI...

@scabug
Copy link
Author

scabug commented Mar 24, 2013

@xeno-by said:
Hubert has kindly provided a fix for this one. I will submit a pull request once we're done with the paper (somewhen in the beginning of April).

@scabug
Copy link
Author

scabug commented Apr 21, 2013

@xeno-by said:
I'll do the backporting next week.

@scabug
Copy link
Author

scabug commented Apr 22, 2013

@hubertp said:
I cleaned it up already yesterday (https://github.com/hubertp/scala-dev/tree/topic/minor-typer-cleanup). PR is coming today. Sorry Eugene ;)

@scabug
Copy link
Author

scabug commented Apr 22, 2013

@hubertp said:
scala/scala#2428

@scabug
Copy link
Author

scabug commented May 5, 2013

@xeno-by said:
scala/scala#2494

@scabug
Copy link
Author

scabug commented May 11, 2013

@xeno-by said:
scala/scala@fdead2b

@scabug
Copy link
Author

scabug commented Feb 5, 2016

Michael Khan (michael.khan) said (edited on Feb 5, 2016 11:10:06 AM UTC):
This issue has re-surfaced.

I have a case class with an associated companion class defined in a domains package (Play project) as follows:

case class Registration(serviceName: String, serviceUrl: String, metadata: Option[Map[String, String]] = None)

object Registration {
implicit val format = Json.format[Registration]
}

We have a custom HTTP library we have built for our organisation which allows us to make HTTP calls - it is publicly available here (https://github.com/hmrc/http-verbs). The following call is made:

http.POST(s"$serviceUrl/registration", registration, Seq("Content-Type" -> "application/json")) 

where the second parameter is of type Registration.

When compiling the compiler complains as follows:

[error] /foo/app/connectors/ServiceLocatorConnector.scala:40: diverging implicit expansion for type uk.gov.hmrc.play.http.HttpReads[P] [error] starting with method readFromJson in trait JsonHttpReads [error] http.POST(s"$serviceUrl/registration", registration, [error] ^ [error] one error found [error] (compile:compileIncremental) Compilation failed

When I explicitly import the companion object into the same translation unit where this http.POST method is called, the compiler is able to pick up the implicit and compilation is a success. If I don't, then it complains about diverging implicit expansion error.

@som-snytt
Copy link

This particular example has worked in the modern era, the PPP epoch, or post-paulp.

@SethTisue SethTisue modified the milestones: Backlog, 2.11.0 Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants