Open som-snytt opened 2 years ago
In scala 2
def f(c: Char) = c.toHexString
compiles successfully and after typer this gets expanded to
def f(c: Char): String = scala.Predef.intWrapper(c.toInt).toHexString
no matter if in REPL or when a file is compiled. In case of
'B'.toHexString
it's
scala.Predef.intWrapper(66).toHexString
in both scala 2 and 3.
So we can see that in both cases a character literal gets widened to Int
. On the other hand a parameter of type Char
gets implicitly converted to Int
with .toInt
in scala 2.
To me it seems the problem is that there are two implicit conversions that return an instance of a type that has toHexString
method: intWrapper
and longWrapper
and scala 3 compiler doesn't know which one to choose while for some reason in scala 2 intWrapper
arbitrarily takes priority.
Unclear if there's anything non-hackish we can do here without being able to change the standard library.
Unless implicit conversions should consider a conversion to Int to be more specific than a conversion to Long? This is the logic that isValueSubType uses, I don't know if either Scala 2 or 3 take that into account for specificity.
One thing that probably should be pointed out is that here scala2 converts a Char
to an Int
with c.toInt
, which is itself a non-implicit def. The same happens for c: Int
where c
is a Char
variable. However in scala 3 it's Char.char2int(c)
, which is indeed an implicit def.
Compiler version
3.1.1
Minimized code
Maybe it's a REPL thing.
Output
As shown.
Expectation
Not as shown.
Also would not expect REPL to report different wrapper was tried.