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

folding const expressions with branching logic #24689

Open
wants to merge 2 commits into
base: devel
Choose a base branch
from

Conversation

Graveflo
Copy link
Contributor

motivating example:

iterator p(a: openArray[char]): int =
  if a.len != 0:
    if a[0] != '/':
      discard
for t in p(""): discard

The compiler wants to evaluate a[0] at compile time even though it is protected by the if statement above it. Similarly expressions like a.len != 0 and a[0] == '/' have problems. It seems like the logic in semfold needs to be more aware of branches to positively identify when it is okay to fail compilation in these scenarios. It's a bit tough though because it may be the case that non-constant expressions in branching logic can properly protect some constant expressions.

@Graveflo Graveflo marked this pull request as draft February 15, 2025 05:37
@Graveflo
Copy link
Contributor Author

will add tests cases later. Just wanted to put this up in case anyone has comments

@metagn
Copy link
Collaborator

metagn commented Feb 15, 2025

It's a bit tough though because it may be the case that non-constant expressions in branching logic can properly protect some constant expressions.

IMO the compiler should not do this if it inserts the constant expression itself, only when the user explicitly writes out the operation on a constant. This would require us to mark inserted constant expressions though and then track this in semfold which might be difficult. Instead we could disable this error on the getConstExpr calls in transf if c.inlining > 0, since both the loop body and the iterator body are transformed before inlining and thus the proper constant uses are already checked. In any case disabling the error altogether is probably still better than the current situation but idk.

@Araq Araq marked this pull request as ready for review February 15, 2025 07:50
@Graveflo
Copy link
Contributor Author

Graveflo commented Feb 15, 2025

I looked a little and this doesn't seem to have any bad effects that I am aware of. I'm thinking to leave it at this for now.
There is still this:

block:
  iterator p(a: openArray[char]): int =
    if a.len > 1:
      if a[1] != '/':
        discard
  var a: array[1, char] = ['z']
  for t in p(a): discard

but that is in a different section of the compiler and I have a feeling it might want to keep the check. Makes me wonder if some of this inlining process should generate code that looks like this. Not sure:

iterator p(a: openArray[char]): int =
  if false:
    discard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants