question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Any` (or `Matchable`) inferred at call site of `implicit class` based extension method (unlike in Scala 2)

See original GitHub issue

Compiler version

3.1.0 (but same problem on 3.0.0, 3.0.1, 3.0.2)

Minimized code

// This minimal code sample exposes the problem when compiled with Scala 3.1,
// i.e., it doesn't generate a compilation error on line xxx
// When compiled as-is with Scala 2.13.8, that line (correctly) doesn't compile

object M {
  // In Scala 3.1, the following extension produces incorrect results:
  // extension [A](a: A)
  //   def ===(a1: A): Boolean = a == a1

  // This is the same extension method defined using Scala 2 syntax
  // and when compiled with Scala 3, it exhibits the same problem
  implicit class EqualExtension[A](val a: A) extends AnyVal {
    def ===(a1: A): Boolean = a == a1
  }
}

object Main {
  import M._

  val eqs: Seq[Boolean] = Seq(
    1 === 1,
    "1" === "1",
    "1" === 1   // This line shouldn't compile, but does with the Scala 3.1.0 compiler
  )
}

Output

When compiled with Scala 2.13.8, the following (correct) compiler error message is produced:

sbt:sc3> compile
[info] compiling 1 Scala source to /Users/ericloots/tmp/sc3/target/scala-2.13/classes ...
[error] /Users/ericloots/tmp/sc3/src/main/scala/ExtensionMethods.scala:25:13: type mismatch;
[error]  found   : Int(1)
[error]  required: String
[error]     "1" === 1   // This line shouldn't compile, but does with the Scala 3.1.0 compiler
[error]             ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed 20 Jan 2022, 18:38:07

Expectation

Compiling the minimised code with Scala 3.1.0 should produce the same compilation error.

Note: I first thought this was an issue with Scala 3 extension methods, so then I tried using the Scala 2 way to define the extension method, with the same result.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
elootscommented, Jan 20, 2022

Interesting. And I realize that the ‘canonical’ solution to this is Multiversal Equality.

That said; it surprised me that the behavior observed when compiling with Scala 2(.13.8) is, as it were, as side effect of the inability of that compiler to infer the correct type(s).

Op 20 jan. 2022 om 20:13 heeft som-snytt @.***> het volgende geschreven:

The “same type” here is Any or Matchable, it depends on what is inferred.

Scala 2 is unable to infer the obvious thing, as it were.

I notice that def ===[B <: A] doesn’t “help”, as the A is not “fixed” by supplying a string.

— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you authored the thread.

0reactions
som-snyttcommented, Jan 20, 2022

While I may have made the observation, credit goes to Titus Winters for actually naming it as “Hyrum’s Law” and popularizing the concept more broadly.

May I say that everyone needs their Titus Winters.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Relationship with Scala 2 Implicits
Extension methods have no direct counterpart in Scala 2, but they can be simulated with implicit classes. For instance, the extension method.
Read more >
Why Scala Infer the Bottom Type when the type parameter ...
Generally speaking, when a type is placed in the function/method parameters, it means it's in the so-called "contravariant position".
Read more >
Implicit methods/functions in Scala 2 and 3 (Dotty ...
In this article I'll show how you can create implicit methods (also known as extension methods) in Scala 2 and Scala 3 (Dotty)....
Read more >
Inline - Scala 3 - EPFL
Transparent Inline Methods ... Here, the inline method choose returns an instance of either of the two types A or B . If...
Read more >
Scala Implicits Are Everywhere
Calling a function that has implicit arguments results in the omitted arguments being filled from the context of the call based on their...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found