Skip to content

Error message for missing parentheses on static dispatch call#9245

Open
fpsvogel wants to merge 5 commits intoroc-lang:mainfrom
fpsvogel:improve-error-for-static-dispatch-missing-parentheses
Open

Error message for missing parentheses on static dispatch call#9245
fpsvogel wants to merge 5 commits intoroc-lang:mainfrom
fpsvogel:improve-error-for-static-dispatch-missing-parentheses

Conversation

@fpsvogel
Copy link
Copy Markdown
Contributor

@fpsvogel fpsvogel commented Mar 7, 2026

Resolves #9193

Improves the error message when a static dispatch call with zero arguments is missing empty parentheses.

It may make the most sense to review this PR one commit at a time: two tweaks to the error message are in separate commits, because they involve nontrivial logic that I didn't want to lump into the principal changes in the first commit. These are the two tweaks:

  • Making the error message point to the method call without parentheses as the problem region (in the example below, not [1, 2, 3] but .len).
  • In the suggested fix, extending the highlighted text to include not only the method name but also the empty parentheses (in the example below, not Use `len`() instead but Use `len()` instead).

The new error message:

Screen Shot 2026-03-07 at 3 44 50 PM

Source for the above example:

app [main!] { pf: platform "./platform/main.roc" }

main! = || {
  dbg [1, 2, 3].len
}

The current error message, before these changes:

Screen Shot 2026-03-07 at 3 56 07 PM

Copy link
Copy Markdown
Collaborator

@jaredramirez jaredramirez left a comment

Choose a reason for hiding this comment

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

Overall this approach looks good! Just have one note about performance that needs to be figured out, then this is good to merge!

Comment thread src/check/Check.zig Outdated
Comment on lines 4386 to 4393
const is_method = try self.isMethodOnNominalType(receiver_var, dot_access.field_name);

// Then, unify the actual receiver type with the expected record
_ = try self.unifyInContext(record_being_accessed, receiver_var, env, .{ .record_access = .{
.field_name = dot_access.field_name,
.field_region = dot_access.field_name_region,
.is_method = is_method,
} });
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This approach makes sense to me, but it would be ideal to only pay for checking self.isMethodOnNominalType if the unification fails. Running the check for all record fields could get expensive.

Currently, self.unifyInContext is not set up for that, but I think it's worth exploring if there's a nice way to do set the context on error or something!

Copy link
Copy Markdown
Contributor Author

@fpsvogel fpsvogel Mar 21, 2026

Choose a reason for hiding this comment

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

Good idea, thanks.

In 5f2dbb6 I made that adjustment in a way that felt a bit fragile, so I did a refactor in the next commit 224432b, but I'm not sure if it's worth the extra LOC, at least for now while there is only one case of this type of error. Do you have a preference between the two?

@github-actions
Copy link
Copy Markdown

Thank you for your contribution! Sometimes PRs end up staying open for a long time without activity, which can make the list of open PRs get long and time-consuming to review. To keep things manageable for reviewers, this bot automatically closes PRs that haven’t had activity in 60 days. This PR hasn’t had activity in 30 days, so it will be automatically closed if there is no more activity in the next 30 days. Keep in mind that PRs marked Closed are not deleted, so no matter what, the PR will still be right here in the repo. You can always access it and reopen it anytime you like!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

improve error message if you forgot () on static dispatch call

2 participants