-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Inlining cannot deal with varargs well, which means we are stopped in the starting block when trying to turn string interpolators into whitebox macros. For instance, consider the f
interpolator. An interpolated string is expanded to:
new StringContext(s_0, ..., s_n).f(e_1, ..., e_n)
Currently f
is a whitebox macro which produces a specialized interpolator with some specific function type, such as
(Int, Double, String) => String
How can we get analogous functionality with just inlining? Here's a sequence of action items that could help get us there:
- Turn
f
into an extension method. I.e.
inline def f(this sc: StringContext)(args: Any*): String =
Makes it easier to get at the string context. Requires #5114.
-
Make varargs immutable arrays instead of Seqs (this just makes the next step easier). Requires Opaque types - selftype encoding #5300.
-
Add rewrite rules that deal with array length and indexing. I.e.
new Array(x_0, ..., x_n)(i) --> x_i
new Array(x_0, ..., x_n).length = n + 1
This lets us get to the arguments passed in the parts
array.
- Implement string parsing using string constant folding (#5406)
- Define a type and implicit instances from strings to the types they represent. Something like
trait Format[S <: String & Singleton, T]
- Summon an implicit instance of
Format
for each suffix string. - Somehow assemble a result type from this, which has the form
((T_1, ..., _T_n)) => String
and cast the runtime implementation off
to this type. - Apply an
untuple
operation (i.e. the inverse oftupled
) to the result, yielding an n-ary method. This last step also needs to be supported with a native rewrite rule.
Or some other mix. In any case, to get off the ground we need to be able to recursively access a sequence of vararg arguments and synthesize a method of arbitrary arity. These require specialized support.