Skip to content

Commit ffc4c16

Browse files
nicolasstuckiliufengyun
authored andcommitted
Fix #3916: Fix interpretation of boxed value classes
1 parent 5ef6c80 commit ffc4c16

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,15 @@ class Interpreter(implicit ctx: Context) {
117117
case Typed(expr, _) =>
118118
interpretTreeImpl(expr, env)
119119

120-
// Getting the underlying value of a value class. The value class is evaluated as its boxed representation
121-
// as values in the interpreter are `Object`s. Therefore we just get it from the enviroment as is.
122-
case Select(qualifier, _)
120+
case Select(qualifier, name)
123121
if tree.symbol.owner.isValueClass && tree.symbol.is(ParamAccessor) && env.contains(qualifier.symbol) =>
124-
env(qualifier.symbol)
122+
val value = env(qualifier.symbol)
123+
val clazz = value.getClass
124+
if (clazz.getCanonicalName != tree.symbol.owner.showFullName) value // Already unboxed
125+
else {
126+
val method = getMethod(clazz, name, Nil)
127+
interpreted(method.invoke(value))
128+
}
125129

126130
case SeqLiteral(elems, _) =>
127131
elems.map(elem => interpretTreeImpl(elem, env))

tests/pos/i3916/Macro_1.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import scala.quoted._
2+
3+
class FInterpolatorHelper(val sc: StringContext) extends AnyVal {
4+
inline def ff(arg1: Any): String = ~FInterpolation.fInterpolation(sc, Seq('(arg1)))
5+
inline def ff(arg1: Any, arg2: Any): String = ~FInterpolation.fInterpolation(sc, Seq('(arg1), '(arg2)))
6+
inline def ff(arg1: Any, arg2: Any, arg3: Any): String = ~FInterpolation.fInterpolation(sc, Seq('(arg1), '(arg2), '(arg3)))
7+
// ...
8+
}
9+
10+
object FInterpolation {
11+
private def liftSeq(args: Seq[Expr[Any]]): Expr[Seq[Any]] = args match {
12+
case x :: xs => '{ (~x) +: ~(liftSeq(xs)) }
13+
case Nil => '(Seq(): Seq[Any])
14+
}
15+
16+
def fInterpolation(sc: StringContext, args: Seq[Expr[Any]]): Expr[String] = {
17+
val str: Expr[String] = sc.parts.mkString("")
18+
val args1: Expr[Seq[Any]] = liftSeq(args)
19+
'{ (~str).format(~args1: _*) }
20+
}
21+
}

tests/pos/i3916/Test_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
println(new FInterpolatorHelper(StringContext("hello%s")).ff(5))
4+
}
5+
}

0 commit comments

Comments
 (0)