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

Error without file or line number information when compiling Akka with Scala 2.11.0-M8 #8219

Closed
scabug opened this issue Jan 31, 2014 · 10 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jan 31, 2014

When compiling Akka I with 2.11.0-M8 I get a compilation error without line numbers or file information in one of the tests.

[error] type mismatch;
[error]  found   : Any
[error]  required: AnyRef
[error] Note: Any is not implicitly converted to AnyRef.  You can safely
[error] pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so.
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 68 s, completed Jan 31, 2014 4:45:55 PM

I've also tried with this SNAPSHOT version (2.11.0-20140131.015148-534) and it fails in the same way.

It might be that it's not one of the test frameworks that are using macros in a bad way, but I've "minimized" the problem to a standalone project.

@scabug
Copy link
Author

scabug commented Jan 31, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8219?orig=1
Reporter: Björn Antonsson (bjorn.antonsson)
Affected Versions: 2.11.0-M8
See #8230
Attachments:

  • broken.tgz (created on Jan 31, 2014 4:02:37 PM UTC, 9958 bytes)

@scabug
Copy link
Author

scabug commented Jan 31, 2014

@retronym said:
Actually it looks like an old, latent bug. It must be trigged by the current layout of the implicits in scope.

I can reproduce it with 2.10.3 (using the exact classpath as in your report):

scala-hash v2.10.3 -classpath /Users/jason/Downloads/broken/target/scala-2.11.0-SNAPSHOT/test-classes:/Users/jason/Downloads/broken/target/scala-2.11.0-SNAPSHOT/classes:/Users/jason/.ivy2/cache/org.scalatest/scalatest_2.11.0-M8/jars/scalatest_2.11.0-M8-2.1.RC1.jar:/Users/jason/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.0-M8.jar:/Users/jason/.ivy2/cache/org.scala-lang.modules/scala-parser-combinators_2.11.0-M8/bundles/scala-parser-combinators_2.11.0-M8-1.0.0-RC5.jar:/Users/jason/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11.0-M8/bundles/scala-xml_2.11.0-M8-1.0.0-RC7.jar:/Users/jason/.ivy2/cache/org.scalacheck/scalacheck_2.11.0-M8/jars/scalacheck_2.11.0-M8-1.11.3.jar:/Users/jason/.ivy2/cache/org.scala-sbt/test-interface/jars/test-interface-1.0.jar /Users/jason/Downloads/broken/src/test/scala/Broken.scala
error: type mismatch;
 found   : Any
 required: AnyRef
Note: Any is not implicitly converted to AnyRef.  You can safely
pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so.
one error found

@scabug
Copy link
Author

scabug commented Jan 31, 2014

@retronym said:
Analysis:

I believe that we should create a throwaway Context in:

    // Typers.scala
    def viewExists(from: Type, to: Type): Boolean = (
         !from.isError
      && !to.isError
      && context.implicitsEnabled
      && (inferView(EmptyTree, from, to, reportAmbiguous = false) != EmptyTree)
    )

This is called in your example when performing overload resolution between the two == members on ByteString. One in inherited from Any, the other from AnyRef.

Scala has a pretty gnarly approach to overload resolution, in which it checks if arguments of the types of candidate A could are applicable to to candidate B, and vice-versa. This should determine that the method in AnyRef is more specific. (Note: they are really two independent members, as the parameter types don't exactly coincide).

Anyway, during this applicability checking, implicit views are allowed. This triggers a search for an implicit view from Any => AnyRef, which results in an ambiguous error with that warning. Coopting the ambiguity error for this purpose is already suspicious; I remember being a bit concerned when that was added, actually. Anyway, this error gets buffered in the enclosing Context (because we didn't make a child context to firewall the results of this implicit search), and later helpfully issued at the position of the EmptyTree passed as a dummy by viewExists.

@scabug
Copy link
Author

scabug commented Jan 31, 2014

@retronym said:
Here's my WIP fix: https://github.com/retronym/scala/tree/ticket/8219

Still need to minimize the test.

@scabug
Copy link
Author

scabug commented Feb 1, 2014

Björn Antonsson (bjorn.antonsson) said:
Thanks Jason,
That's an awesome turnaround time.

@scabug
Copy link
Author

scabug commented Feb 3, 2014

@retronym said (edited on Feb 3, 2014 9:59:40 AM UTC):
Isolated:

trait Equalizer[T]
trait Gen[A]

class Broken {
  implicit def const[T](x: T): Gen[T] = ???
  implicit def convertToEqualizer[T](left: T): Equalizer[T] = ???

  def in(a: Any) = ()
  in {
    import scala.Left
    "" == ""
  }
}

Paul pointed out in another ticket that the fact the AnyRef#== overloads, rather the overrides Any#== is pretty suspicious. You would not be allowed to compile real classes with those signatures as they collapse into an overriding relationship after erasure.

@scabug
Copy link
Author

scabug commented Feb 3, 2014

@retronym said:
scala/scala#3460

@scabug
Copy link
Author

scabug commented Feb 3, 2014

@retronym said (edited on Feb 3, 2014 3:43:43 PM UTC):
Looks like the fix is less risky than I thought. One of my attempts uncovered #8230.

@scabug
Copy link
Author

scabug commented Feb 4, 2014

@retronym said:
scala/scala#3464

@scabug scabug closed this as completed Feb 11, 2014
@scabug
Copy link
Author

scabug commented Apr 2, 2014

@retronym said:
Marking #8463 as a duplicate of this ticket. We should add its test cases when fixing this bug:

Reproduce code:

  case class Foo[+T[_]](activity:T[Long])
  type Cell[T] = T
  def insertCell(u:Foo[Cell]) = ???
  insertCell(Foo(5))

Expected result:
Type error with line numer.

Actual result:

[error] type mismatch;
[error]  found   : Long
[error]  required: ?T
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error]  both method longWrapper in class LowPriorityImplicits of type (x: Long)scala.runtime.RichLong
[error]  and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
[error]  are possible conversion functions from Long to ?T

It seems to be related to using a type alias and a long. Those all produce type errors with line numbers:

  case class Foo2[+T[_]](color:T[String])
  def insertCell2(u:Foo2[Cell]) = ???
  insertCell2(Foo2("color"))

  def insertOption(u:Foo[Option]) = ???
  insertOption(Foo(5))

  def insertOption2(u:Foo2[Option]) = ???
  insertOption2(Foo2("color"))

Another code sample that produces the same error message without line number:

  class DefaultType[Name]
  case class Foo[+T[_]](
    activity:T[Long]
  )(t:DefaultType[T[_]])
  Foo(3)(new DefaultType[Option[_]])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants