-
Notifications
You must be signed in to change notification settings - Fork 57
Fix a bug in extraction for method calls with multiple list of arguments #1694
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a bug in AST extraction for method calls with multiple argument lists in the Dotty frontend. The fix adds pattern matching cases to handle nested Apply nodes, which represent curried method calls with multiple parameter lists.
Key Changes
- Added support for nested
Applynodes inExThisCallextractor to handle methods with multiple argument lists - Added support for nested
Applynodes onExThisCallinExCallextractor for proper recursion - Added test cases to validate extraction of methods with multiple argument lists and ClassTag context bounds
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| frontends/dotty/src/main/scala/stainless/frontends/dotc/ASTExtractors.scala | Adds pattern matching cases to handle nested Apply nodes for multiple argument lists in ExThisCall and ExCall extractors |
| frontends/benchmarks/extraction/valid/MethodCallsWithMultipleArgsLists.scala | Test case for methods with multiple explicit argument lists (e.g., pred(l)(0)(0)) |
| frontends/benchmarks/extraction/valid/ClassTagMethodCalls.scala | Test case for methods with ClassTag context bounds that create implicit argument lists |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
frontends/dotty/src/main/scala/stainless/frontends/dotc/ASTExtractors.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems okay-ish as a quick fix.
However, I find it misleading that ExCall also matches ExThisCall. These extractors are mainly used here:
stainless/frontends/dotty/src/main/scala/stainless/frontends/dotc/CodeExtraction.scala
Lines 1867 to 1878 in 2b3d9c0
| case ExThisCall(tt, sym, tps, args) => | |
| extractCall(tr, Some(tpd.This(tt.cls)), sym, tps, args) | |
| case ExCastCall(expr, from, to) => | |
| // Double check that we are dealing with regular integer types | |
| val xt.BVType(true, size) = extractType(from)(using dctx, NoSourcePosition): @unchecked | |
| val newType @ xt.BVType(true, newSize) = extractType(to)(using dctx, NoSourcePosition): @unchecked | |
| if (size > newSize) xt.BVNarrowingCast(extractTree(expr), newType) | |
| else xt.BVWideningCast(extractTree(expr), newType) | |
| case c@ExCall(rec, sym, tps, args) => | |
| extractCall(c, rec, sym, tps, args) |
where there is clearly a case for this.m(...) and a distinct case for m(...).
If I understand correctly, after this PR, this-calls with multiple argument lists will not be matched by ExThisCall but instead by ExCall, while this-calls with a single argument list will still be matched by ExThisCall.
That creates a semantic overlap where ExCall subsumes part of ExThisCall’s intended domain. This makes the extractor behavior arity-dependent, which I find confusing and harder to reason about.
I would find it more coherent to either:
- Extend
ExThisCallto support multiple argument lists, or - Let
ExCallmatchthis-calls as it currently does, but then completely removeExThisCall, which should no longer be necessary.
On a separate note, ExThisCall also seems limited to paths of depth one: it matches this.m but not this.c.m, since it only recognizes a single top-level TermRef and does not recurse. We might want to test this and potentially address it separately.
Fixes a problem in the extraction of method calls with multiple lists of arguments. Previously, the receiver (i.e., probably
this) was lost as it was extracted as a function call without receiver.Fixes #1692
Was discovered while working on class tags, as they add implicitly a new list of parameters to methods.
Example:
Here, the call to
predin therequireoffwas extracted as:instead of
See #1692 for more details.