Skip to content

ClassCastException on by-name parameter in enrichment method #8035

Closed
@travisbrown

Description

@travisbrown

minimized code

implicit class Ops[A](val a: String) extends AnyVal {
  def foo(e: => String): Unit = ()
}

def bar(e: => String): Unit = (new Ops("")).foo(e)
def baz(e: => String): Unit = "".foo(e)
Compiles but fails at runtime
scala> bar("")

scala> baz("")
java.lang.ClassCastException: java.lang.String incompatible with scala.Function0
	at rs$line$1$.baz(rs$line$1:6)
	at rs$line$3$.<init>(rs$line$3:1)
	at rs$line$3$.<clinit>(rs$line$3)
	at rs$line$3.res0(rs$line$3)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at dotty.tools.repl.Rendering.$anonfun$3(Rendering.scala:72)
	at dotty.tools.repl.Rendering$$Lambda$1465.000000006884EA20.apply(Unknown Source)
	at scala.Option.map(Option.scala:242)
	at dotty.tools.repl.Rendering.valueOf(Rendering.scala:72)
	at dotty.tools.repl.Rendering.renderVal(Rendering.scala:95)
	at dotty.tools.repl.ReplDriver.displayMembers$3$$anonfun$3(ReplDriver.scala:291)
	at dotty.tools.repl.ReplDriver$$Lambda$1411.00000000649C0620.apply(Unknown Source)
	at scala.collection.immutable.List.map(List.scala:219)
	at scala.collection.immutable.List.map(List.scala:79)
	at dotty.tools.repl.ReplDriver.displayMembers$6(ReplDriver.scala:291)
	at dotty.tools.repl.ReplDriver.displayDefinitions$$anonfun$3$$anonfun$2(ReplDriver.scala:317)
	at dotty.tools.repl.ReplDriver$$Lambda$1370.0000000066279820.apply(Unknown Source)
	at scala.Option.map(Option.scala:242)
	at dotty.tools.repl.ReplDriver.displayDefinitions$$anonfun$1(ReplDriver.scala:317)
	at dotty.tools.repl.ReplDriver$$Lambda$1366.0000000066276E20.apply(Unknown Source)
	at dotty.tools.dotc.core.Phases.atPhase$$anonfun$1(Phases.scala:35)
	at dotty.tools.dotc.core.Phases$$Lambda$1031.000000006780A020.apply(Unknown Source)
	at dotty.tools.dotc.core.Periods.atPhase(Periods.scala:25)
	at dotty.tools.dotc.core.Phases.atPhase(Phases.scala:35)
	at dotty.tools.dotc.core.Contexts$Context.atPhase(Contexts.scala:75)
	at dotty.tools.repl.ReplDriver.displayDefinitions(ReplDriver.scala:323)
	at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:245)
	at dotty.tools.repl.ReplDriver$$Lambda$1362.0000000066274A20.apply(Unknown Source)
	at scala.util.Either.fold(Either.scala:189)
	at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:247)
	at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:193)
	at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:127)
	at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:130)
	at dotty.tools.repl.ReplDriver$$Lambda$230.00000000668CFA20.apply(Unknown Source)
	at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:148)
	at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:130)
	at dotty.tools.repl.Main$.main(Main.scala:6)
	at dotty.tools.repl.Main.main(Main.scala)

expectation

This works fine on Scala 2, and it works fine here if you remove the unused [A] on Ops, or if you remove the extends AnyVal, or if you do both. If you change the implicit class to something like this:

implicit def toOps(a: String): Ops[Unit] = new Ops(a)

class Ops[A](val a: String) extends AnyVal {
  def foo(e: => String): Unit = ()
}

def baz(e: => String): Unit = "".foo(e)

…Dotty still throws the ClassCastException.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions