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

varpartitions: add support for if/try/case paths #1455

Draft
wants to merge 1 commit into
base: devel
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions compiler/sem/varpartitions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,40 @@ proc pathExpr(node: PNode; owner: PSym): PNode =
break
else:
break
of nkElifExpr, nkElifBranch, nkElseExpr, nkElse, nkExceptBranch, nkOfBranch:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this dig into nkBlock expression and statement varieties?

n = n.lastSon
of nkIfExpr, nkIfStmt, nkTryStmt, nkCaseStmt:
block samePathCheck:
let firstExpr =
case n.kind
of nkTryStmt:
n[0] # First element is try body
of nkCaseStmt:
n[1].lastSon # First branch is the second element
else:
n[0].lastSon
let firstValidPath = pathExpr(firstExpr, owner)
# The first expression should be a valid path
if firstValidPath == nil:
break samePathCheck

let remainderStart = if n.kind == nkCaseStmt: 2 else: 1
for idx in remainderStart ..< n.len:
Copy link
Collaborator

@saem saem Sep 10, 2024

Choose a reason for hiding this comment

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

Any trailing finally should be removed from the iteration since it's not part of the expression, as in it will always be a statement, right?

# Only check branches with a type, as no types implies noreturn for
# expressions
Comment on lines +384 to +385
Copy link
Collaborator

Choose a reason for hiding this comment

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

They're either noreturn or unit, the difference being that the latter doesn't "abort" the current expression like the former does. You might need to rely on the endsInNoReturn analysis.

if not n[idx].lastSon.typ.isEmptyType():
# If the first path is not a symbol, then we currently can't check
# if other paths points to the same resource, so bail.
if firstValidPath.kind != nkSym:
break samePathCheck

let path = pathExpr(n[idx], owner)
if path.kind != nkSym or path.sym.itemId != firstValidPath.sym.itemId:
break samePathCheck

result = firstValidPath

break
else:
break
# borrowFromConstExpr(n) is correct here because we need 'node'
Expand Down