Skip to content

Report a missing return statement in a closure or function - #7738

Merged
bentsherman merged 4 commits into
masterfrom
fix-missing-return
Oct 2, 2026
Merged

bentsherman merged 4 commits into
masterfrom
fix-missing-return

Conversation

@bentsherman

Copy link
Copy Markdown
Member

Close #7737

The type checker turns the trailing statement of each code path into an implicit return, but never checked that every path actually yields a value. So this passed, and the closure emits null whenever the condition is false:

channel.of(1, 2, 3).map { x ->
    if( x > 1 ) {
        return x * 2
    }
}

Now, when a function or closure must return a value, every code path must end with an explicit return or a trailing expression statement (or a throw). Otherwise it reports Missing return statement on the statement where the path ends. That covers:

  • an if with no else, or an empty branch (reported on the if)
  • a branch that ends with a declaration or assignment, such as def y = 'a' or y = 'a', which were previously treated as implicit returns
  • a try/catch where the try block or a catch block doesn't return. Before, a trailing try/catch was never checked at all

The check only applies when a value is required: a non-void declared return type, an unresolved generic such as the R in map, or a def function where some path returns a value. Void functions and closures are unaffected.

Because predicate closures must return a value (#7714), a filter closure that only returns inside an if is also reported, even though the fall-through null would be treated as false.

Signed-off-by: Ben Sherman <bentshermann@gmail.com>
@bentsherman
bentsherman requested a review from a team as a code owner October 1, 2026 21:22
@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for nextflow-docs ready!

Name Link
🔨 Latest commit 636f3e0
🔍 Latest deploy log https://app.netlify.com/projects/nextflow-docs/deploys/6abf908e64458500080f3cf5
😎 Deploy Preview https://deploy-preview-7738--nextflow-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@bentsherman
bentsherman requested a review from jorgee October 1, 2026 21:23

@jorgee jorgee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks fine to me. I ran an agent to look for false positives in common patterns (>> publish closures, process and workflow bodies, each/subscribe, if / else if / else chains, try/catch and throw), and it found none.

One corner case, non-blocking: an empty body reports the error without a source position.

channel.of(1).map { x -> }
def f(x: Integer) -> String { }
Error main.nf:-1:-1: Missing return statement

The top-level addReturnsIfNeeded(node, node) uses the empty block as its own fallback, and an empty block has no position. Passing the function or closure node as the fallback would fix it. It's a rare case, so up to you whether to fix it here or wait until someone reports it.

@bentsherman
bentsherman merged commit 7193a2e into master Oct 2, 2026
29 of 31 checks passed
@bentsherman
bentsherman deleted the fix-missing-return branch October 2, 2026 13:12
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.

Type checker does not report missing return in functions and closures

2 participants