-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Missing ability to check whether inline argument is constant #11780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is exactly what the first version of This kind of code is more suited for macros than inline code in general. But to have this functionality in inline code we could define a macro that looks something like this inline def isConstString(inline str: String): Boolean = ${ impl('str) }
private def impl(str: Expr[String])(using Quotes): Expr[Boolean] =
Expr(str.value.isDefined)
// or
// str.value match { case Some(_) => true ; case _ => false }
// or
// str match { case Expr(_) => true ; case _ => false } Now inline given blah(inline body: String): Name =
inline if isConstString(body) then Name.now(body)
else Name.lazily(body) We could add |
FYI @japgolly the macro you wrote can be simplified considerably using the - private def _blah(expr: Expr[String])(using Quotes): Expr[Name] = {
- import quotes.reflect.*
- expr.asTerm match {
- case Inlined(_, _, Literal(StringConstant(s))) => '{ Name.now($expr) }
- case _ => '{ Name.lazily($expr) }
- }
- }
+ private def _blah(expr: Expr[String])(using Quotes): Expr[Name] =
+ if expr.value.isDefined then '{ Name.now($expr) } else '{ Name.lazily($expr) } |
I would avoid adding this capability to the library for 3.0. Anyone who requires it in inline can implement the macro in 3 lines of code. If we see that is really useful to have we can consider adding it in a later version of scala 3. |
Uh oh!
There was an error while loading. Please reload this page.
I'd be happy to contribute a PR to fix if necessary.
The
inline
doc saysand then goes on to show this example:
So if I understand correctly,
n == 0
andn == 1
occur at compile-time and only match constants.def p(n: Int) = power(expr,n); p(10)
wouldn't translate to the example translation above becausen
would be a dynamic reference rather than a constant.1
and0
because they're constants in the inline function bodyAll well and good but what if one wants to simply know whether
n
is a constant or not (regardless of the value)?In my case I was trying to determine whether a
String
argument is constant or not.This doesn't work:
The methods in
scala.compiletime
don't seem to help because they're more about types.My own workaround was to fallback to the quoting API like this:
It'd be nice to be able to make this work without falling back to quotes. This ability doesn't seem to exist yet, nor does it seem hard to write. I'd be happy to write a PR to add this. Maybe a bunch of methods like
inline def stringConstantOpt(inline s: String): Option[String]
for each constant type?The text was updated successfully, but these errors were encountered: