Enhance constant-folding during inlining (second try)#25731
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
When the compiler constant-folds `Pattern.CASE_INSENSITIVE | Pattern.COMMENTS` into a single IntConstant (e.g. 6), parseFlags failed to match. This adds a case to decompose the constant back into individual flag bits. See scala/scala3#25731 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
An ascription that doesn't pass that condition is an invalid ascription. How does it even get there? |
It turns out you can generate malformed trees with macros. See #25690 for more 😅 |
|
Right. Then the macro needs to be fixed. |
Sure, that's why I opened the PR on ZIO to enable In the meantime, and in case other codebases rely on broken macros, don't you think that defensively checking the assertion is valid would make sense? |
|
See also the internal Slack discussion about |
No, it really doesn't make sense. You can't pollute every other place of the compiler with dealing with bad stuff that macros generate. It's not sustainable. In this case it might run on the JVM because it inserts casts to heal things, but not on JS, whose backend is stricter. At most, you could have a postprocessing after a macro that turns bad ascriptions into casts. And emits a warning in the process. At least the blast radius of that hack would be limited to macros. |
|
I filled zio/zio#10721, let's see if I can get some help fixing this in ZIO directly. PR also opened: zio/zio#10725. |
When the compiler constant-folds `Pattern.CASE_INSENSITIVE | Pattern.COMMENTS` into a single IntConstant (e.g. 6), parseFlags failed to match. This adds a case to decompose the constant back into individual flag bits. See scala/scala3#25731 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
When the compiler constant-folds `Pattern.CASE_INSENSITIVE | Pattern.COMMENTS` into a single IntConstant (e.g. 6), parseFlags failed to match. This adds a case to decompose the constant back into individual flag bits. See scala/scala3#25731 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
When the compiler constant-folds `Pattern.CASE_INSENSITIVE | Pattern.COMMENTS` into a single IntConstant (e.g. 6), parseFlags failed to match. This adds a case to decompose the constant back into individual flag bits. See scala/scala3#25731 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
When the compiler constant-folds `Pattern.CASE_INSENSITIVE | Pattern.COMMENTS` into a single IntConstant (e.g. 6), parseFlags failed to match. This adds a case to decompose the constant back into individual flag bits. See scala/scala3#25731 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
81b7a7e to
05083ab
Compare
|
@WojciechMazur, I made zio/zio#10725 on ZIO to avoid #25690 and #25692, and leviysoft/oolong#61 on Oolong to avoid #25697, so I hope the open community build can now pass on this change. Could you please update ZIO and Oolong in the open community build, and then run it on this PR? |
Sure, just be aware I can force these 2 to be used from main branch instead of latest release, but when it comes to zio the problem was in majority present for the users of their macros - I cannot safely force zio dependency upgrade for these, as it might lead to other, unrelated compilation errors. Effectively their builds might be broken until they upgrade to latest version of ZIO |
Ah, I see, thanks for the explanation. So I guess I need to wait until both ZIO and Oolong release new versions. |
|
@WojciechMazur ZIO just released 2.1.26 with my fix 🥳 Could we try running the community build on this PR, with these updated versions? |
05083ab to
bbd3d41
Compare
|
If I understand correctly, the open community build actually uses the latest releases by default. So it might pass now, modulo projects that might use older versions of ZIO, as Wojciech mentioned above. Solal launched a community build run for me:
Wait and see. |
|
It shows 88 new failing projects, but it seems a lot of them are not related to this PR 🤔 |
|
@WojciechMazur: the community build took oolong 0.5.0, while the latest version on Scaladex and Maven central is 0.5.2. Do you know why? That's actually the only new failure caused by a compilation error. The other 87 new failures are due to tests failing. It's still not clear to me how these are related to this PR. |
It caused by problems with our Scaladex scrapping, resulting in project configs not being updated. I'm fixing it right now |
bbd3d41 to
22f1319
Compare
|
@WojciechMazur, ping me when I can try to run the open community build again 🙂 |
22f1319 to
387126e
Compare
|
There are conflicts in the presentation compiler build - once it's fixed we can shcedule a new OpenCB |
387126e to
66263c2
Compare
|
OpenCB results against 08.07.2026 nightly (last one) https://scala3.westeurope.cloudapp.azure.com/dashboard/compare?baseScalaVersion=3.10.0-RC1-bin-20260707-a4dab1a-NIGHTLY&targetScalaVersion=3.10.0-RC1-bin-20260708-66263c2&reason=Compilation |
|
Thanks a lot! |
|
I see no regression in pekko or zio-dependent libraries, so I think we can try to merge and see if we get any regressions in the next nightlies. |
|
It looks okay to me but I'm not the right person for inlining stuff, maybe @jchyb ? |
|
Ah I forgot this PR had history... okay given the previous discussion I guess people are okay with it. |
66263c2 to
d3632c4
Compare
|
I'm rebasing because main is already broken and we shouldn't break it further so let's wait til that's fixed to merge this. |
d3632c4 to
064c25e
Compare
|
(rebased) |
|
@mbovel Regression reproducer for kitlangton/neotype, do you think it must be fixed in the library or can be resolved in compiler? // macro.scala
import scala.quoted.*
abstract class Newtype[A]:
opaque type Type = A
inline def apply(inline input: A): Type =
${ Newtype.applyImpl[A, Type]('input) }
object Newtype:
def applyImpl[A: Type, T: Type](input: Expr[A])(using Quotes): Expr[T] =
// Same cast neotype uses after (optional) compile-time validation.
input.asExprOf[T]
//> using file macro.scala
type NonEmptyString = NonEmptyString.Type
object NonEmptyString extends Newtype[String]
type FullName = FullName.Type
object FullName extends Newtype[NonEmptyString]
@main def Test(): Unit =
val fullName: FullName = FullName(NonEmptyString("Bob Smith"))
println(fullName)yields Potential fix: object Newtype:
def applyImpl[A: Type, T: Type](input: Expr[A])(using Quotes): Expr[T] =
import quotes.reflect.*
Typed(input.asTerm, TypeTree.of[T]).asExprOf[T]
however it feels like that can be something compiler can do for us instead. There was no issues under -Xcheck-macros before |
|
@WojciechMazur the fix is the same as in https://github.com/scala/scala3/pull/25731/changes#diff-1afc6b9cbf71fc548e1526eea8be0e3420423fd7da2485caebd5473f055ac125; use an // macro.scala
import scala.quoted.*
abstract class Newtype[A]:
opaque type Type = A
inline def apply(inline input: A): Type =
${ Newtype.applyImpl[A, Type]('input) }
object Newtype:
def applyImpl[A: Type, T: Type](input: Expr[A])(using Quotes): Expr[T] =
// Same cast neotype uses after (optional) compile-time validation.
'{$input.asInstanceOf[T]}There is a crucial phase distinction here:
Previously, |
#24431 was reverted in #25703. This PR restores #24431.
Fixes #24420 and fixes #24412.