Skip to content
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

allow generic compileTime proc folding #22022

Merged
merged 7 commits into from
Aug 17, 2024

Conversation

metagn
Copy link
Collaborator

@metagn metagn commented Jun 6, 2023

fixes #10753, fixes #22021, refs #19365 (was fixed by #22029, but more faithful test added)

For whatever reason compileTime proc calls did not fold if the proc was generic (since this folding was introduced). I'm guessing the intention was for unresolved generic procs to not fold, which is now the logic.

Non-magic compileTime procs also now don't fold at compile time in typeof contexts to avoid possible runtime errors (only the type is important) and prevent double/needless evaluation.

@metagn

This comment was marked as outdated.

@metagn metagn changed the title allow generic compileTime procs? [backport] allow generic compileTime proc folding [backport] Jun 6, 2023
@metagn metagn changed the title allow generic compileTime proc folding [backport] allow generic compileTime proc folding Jun 13, 2023
@metagn

This comment was marked as outdated.

@metagn metagn closed this Aug 17, 2024
@metagn metagn reopened this Aug 17, 2024
@metagn
Copy link
Collaborator Author

metagn commented Aug 17, 2024

I've changed it so non-magic calls do not fold at compile time in typeof contexts so stew keeps working, but the implementation ended up being a bit messy; maybe there's a cleaner way, if not hopefully it's good enough

@@ -49,7 +49,9 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
else:
m = mode.intVal
result = newNodeI(nkTypeOfExpr, n.info)
inc c.inTypeofContext
let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can see here we already have efInTypeof. Can this be used instead of c.inTypeofContext?

Copy link
Collaborator Author

@metagn metagn Aug 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I tried first, it doesn't always propagate, even in simple cases like typeof(foo(compileTimeProc())) where it's nested in another call.

@Araq Araq merged commit f7c11a8 into nim-lang:devel Aug 17, 2024
18 checks passed
Copy link
Contributor

Thanks for your hard work on this PR!
The lines below are statistics of the Nim compiler built from f7c11a8

Hint: mm: orc; opt: speed; options: -d:release
173453 lines; 7.806s; 654.559MiB peakmem

narimiran pushed a commit that referenced this pull request Sep 13, 2024
fixes #10753, fixes #22021, refs #19365 (was fixed by #22029, but more
faithful test added)

For whatever reason `compileTime` proc calls did not fold if the proc
was generic ([since this folding was
introduced](c25ffbf#diff-539da3a63df08fa987f1b0c67d26cdc690753843d110b6bf0805a685eeaffd40)).
I'm guessing the intention was for *unresolved* generic procs to not
fold, which is now the logic.

Non-magic `compileTime` procs also now don't fold at compile time in
`typeof` contexts to avoid possible runtime errors (only the important)
and prevent double/needless evaluation.

(cherry picked from commit f7c11a8)
Araq pushed a commit that referenced this pull request Sep 22, 2024
…port:2.0] (#24152)

fixes #24150, refs #22022

An exception is raised in the `semExprWithType` call, which means `dec
c.inTypeofContext` is never called, but `compiles` allows compilation to
continue. This means `c.inTypeofContext` is left perpetually nonzero,
which prevents `compileTime` evaluation for the rest of the program.

To fix this, `defer:` is used for the `dec c.inTypeofContext` call, as
is done for
[`instCounter`](https://github.com/nim-lang/Nim/blob/d51d88700b2fb3bd228d5e8f7385e2e4a2e2880c/compiler/seminst.nim#L374)
in other parts of the compiler.
narimiran pushed a commit that referenced this pull request Sep 28, 2024
…port:2.0] (#24152)

fixes #24150, refs #22022

An exception is raised in the `semExprWithType` call, which means `dec
c.inTypeofContext` is never called, but `compiles` allows compilation to
continue. This means `c.inTypeofContext` is left perpetually nonzero,
which prevents `compileTime` evaluation for the rest of the program.

To fix this, `defer:` is used for the `dec c.inTypeofContext` call, as
is done for
[`instCounter`](https://github.com/nim-lang/Nim/blob/d51d88700b2fb3bd228d5e8f7385e2e4a2e2880c/compiler/seminst.nim#L374)
in other parts of the compiler.

(cherry picked from commit a177720)
metagn added a commit to metagn/Nim that referenced this pull request Oct 3, 2024
Araq pushed a commit that referenced this pull request Oct 6, 2024
fixes #24228, refs #22022

As described in
#24228 (comment),
instantiating generic routines inside `typeof` causes all code inside to
be treated as being in a typeof context, and thus preventing compile
time proc folding, causing issues when code is generated for the
instantiated routine. Now, instantiated generic procs are treated as
never being inside a `typeof` context.

This is probably an arbitrary special case and more issues with the
`typeof` behavior from #22022 are likely. Ideally this behavior would be
removed but it's necessary to accomodate the current [proc `declval` in
the package `stew`](status-im/nim-stew#190), at
least without changes to `compileTime` that would either break other
code (making it not eagerly fold by default) or still require a change
in stew (adding an option to disable the eager folding).

Alternatively we could also make the eager folding opt-in only for
generic compileTime procs so that #22022 breaks nothing whatsoever, but
a universal solution would be better. Edit: Done in #24230 via
experimental switch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants