Skip to content

Add unreachable code detection#904

Open
nae3x wants to merge 3 commits intoevhub:developfrom
nae3x:issue-599-impl
Open

Add unreachable code detection#904
nae3x wants to merge 3 commits intoevhub:developfrom
nae3x:issue-599-impl

Conversation

@nae3x
Copy link
Copy Markdown

@nae3x nae3x commented Mar 13, 2026

This pull request implement solution for the issue #599

Changes

  • Add unreachable code detection function that triggers in proc_funcdef during deferred_code_proc
  • Add related unit tests
  • Update it_ret, it_ret_none, and it_ret_tuple in target_sys_test.coco to avoid triggering the unreachable code checker
  • Update keyword_funcdef_handle to move the generated yield statement to the top of the function (after docstring if any) to avoid trigger the unreachable code checker

Examples

# validate-issue-599.coco
def f():
  return 1
  f = 2

With --strict:

Compiling         validate-issue-599.coco ...
CoconutStyleError: found unreachable code after return statement (remove --strict to downgrade to a warning) (line 1 in 'validate-issue-599.coco')
  def f():
Coconut exiting with error: CoconutStyleError

Without --strict:

Compiling         validate-issue-599.coco ...
CoconutSyntaxWarning: found unreachable code after return statement (line 1 in 'validate-issue-599.coco')
  def f():
Compiled to       validate-issue-599.py .

Limitations

  • Only checks for code that comes after terminator statements (return, raise) at the top level of function bodies
  • Only reports the function definition's line number, not the line number of the unreachable code itself, as source line information is not available at this stage of compilation

@nae3x
Copy link
Copy Markdown
Author

nae3x commented Mar 13, 2026

Hello @evhub. Thank you for the open-source contribution opportunity

Currently I am trying to figure out how to make the detection work with yield def syntax. The way it work right now is that it append the yield statement at the end of the fucntion and cause the checker to falsly trigger.

# validate-issue-599.coco
yield def yield_f():
  return 1

Result:

Compiling         validate-issue-599.coco ...
CoconutStyleError: found unreachable code after return statement (remove --strict to downgrade to a warning) (line 1 in 'validate-issue-599.coco')
  yield def yield_f():
Coconut exiting with error: CoconutStyleError

Complied Python file:

def yield_f():  #1 (line in Coconut source)
    raise _coconut.StopIteration((1))  #2 (line in Coconut source)

    if False:  #3 (line in Coconut source)
        yield  #3 (line in Coconut source)

There are some ideas that I can think of:

  1. Fix at the yield def by update keyword_funcdef_handle to insert if False: yield before any terminator statement or after the docstring, so it never appears after a return/raise. This keeps the detector simple but changes the shape of compiled output for yield def.

  2. Fix at the detector by update detect_unreachable_code to distinguish compiler-generated lines from user-written lines and skip them. I am not sure if this is possible

At this point, I am unsure if my solution is heading in the right direction, and I would appreciate some guidance if possible 😅.

@nae3x
Copy link
Copy Markdown
Author

nae3x commented Mar 20, 2026

Hello! I decided to go with the fix yield def solution and move the genereated yield statement to the top of the function instead. This resolved the checker issue, and all tests passed and everything seem to be working fine.

Now the complied code is like this:

Coconut file:

# validate-issue-599.coco
yield def yield_f_without_docstring():
  return 1

yield def yield_f_with_docstring():
  """docstring"""
  return 1

Complied Python file:

# Compiled Coconut: -----------------------------------------------------------

def yield_f_without_docstring():  #1 (line in Coconut source)
    if False:  #2 (line in Coconut source)
        yield  #2 (line in Coconut source)
    raise _coconut.StopIteration((1))  #2 (line in Coconut source)


def yield_f_with_docstring():  #4 (line in Coconut source)
    """docstring"""  #5 (line in Coconut source)
    if False:  #6 (line in Coconut source)
        yield  #6 (line in Coconut source)
    raise _coconut.StopIteration((1))  #6 (line in Coconut source)

If there’s another approach that I should consider, please let me know.

@nae3x nae3x marked this pull request as ready for review March 20, 2026 13:59
@nae3x nae3x changed the title Add unreachable code detection (WIP) Add unreachable code detection Mar 20, 2026
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.

1 participant