chapel-py: expose Dyno error data in Python API, improve error messages.#28391
Merged
DanilaFe merged 32 commits intochapel-lang:mainfrom Feb 12, 2026
Merged
chapel-py: expose Dyno error data in Python API, improve error messages.#28391DanilaFe merged 32 commits intochapel-lang:mainfrom
DanilaFe merged 32 commits intochapel-lang:mainfrom
Conversation
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
When converting to Python, we strip off some data if we can't pass it. That means we can't restore that data back from Python. Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
jabraham17
approved these changes
Feb 11, 2026
Comment on lines
+246
to
+258
| /** Different error types have different arguments in their '->info()' tuple, | ||
| not all of which can be converetd to Python. Also, the C preprocessor | ||
| doesn't allow us to use commas in macro arguments, so we can't just write | ||
| std::tuple<EINFO> to get a tuple of an error's info. Instead, use template | ||
| specialization here to define a ErrorInfoBundle with a type alias that | ||
| is fully convertible. | ||
|
|
||
| It seems to be a good idea to keep the tuple returned by Python's | ||
| version of `->info()` always the same size as the original tuple. This | ||
| way, as more components of the error info become convertible, | ||
| they can be added to the returned tuple without changing user code that | ||
| unpacks the tuple. Thus, we pad the tuple with 'dummy' elements for | ||
| non-convertible types. |
Member
There was a problem hiding this comment.
I won't pretend to full understand this code. But I see no obvious errors
| if as_ is not None: | ||
| location = as_.location() | ||
| elif isinstance(error, chapel.TertiaryUseImportUnstable): | ||
| node = error.info()[1] |
Member
There was a problem hiding this comment.
nit, use tuple unpacking like the other statements
| related_info = None | ||
| location = error.location() | ||
| if isinstance(error, chapel.NoMatchingCandidates): | ||
| (call, _, appress, _) = error.info() |
Member
There was a problem hiding this comment.
It took me way too long to grok that appress -> ApplicabilityResult. Consider app_results and app_result
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
…ense ...and since I'm not currently providing related information. Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
jabraham17
approved these changes
Feb 11, 2026
2 tasks
DanilaFe
added a commit
that referenced
this pull request
Mar 4, 2026
There have been some indications that after #28391, it was harder to compile chapel-py due to memory constraints. This is plausible, since we have added a whole variety of new generated methods, and a whole new class hierarchy. To help address this, this PR splits the file that generates all the methods from the `metho-tables.h` into separate source files. ## Testing - [x] chapel-py builds - [x] CLS tests still pass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This all started because the language server was not giving me detailed enough information about why calls are not resolving.
Why are there no matching candidates?!
I think there might be some kind of method or setting in my editor to show detailed information (which would include the failing candidates). However, if only a particular argument is causing the problem (as it is in the case above), why not highlight that specific argument?
This was not possible in
chapel-py's previous state of things. It exposed the parentErrorclass to Python, which included.message()and the additional notes. However, these notes are in plain English, and make it hard to work backwards to find the (e.g.) actual that caused the issue. However, from the get-go (as described in #20701), our errors were designed to separate the content of the error from its presentation. To this end, different error sub-classes contain bundles (tuples) of information, from which we can determine the erroneous actual.The goal of this PR, then, was to plumb this wealth of additional information into
chapel-pyproper. I did this by:generated-types-list.hto adapt all the error messages we have listed inerror-classes-list.h. NotablyGeneralErroris not a generated type in plain Dyno, but I treat it as such inchapel-pyfor uniformity. This required a tiny bit of boilerplate on Dyno's front, adding->toBlaError()methods toErrorBase.infomethod for each error message. The type of thisinfomethod differs for every error message, but more importantly, not all information exposed by error messages can be converted into Python data. To make progress, and to guard against future error messages adding new, unsupported error information, I wrote some template code to produce 'Python-safe' tuples from arbitrary->infodata.std::monostate?), but we already have support for tuples, so using them was the path of least resistance.uast-methods.h), which can be precise about whether their return type can benullptror not via theNilablewrapper, theerror-classes-list.hmacro header does not provide such information. Thus, we must assume any pointer type contained in the->info()can benullptr. This requires a recursive transformation that tags pointer types as such, implemented byCanConvert::transform.error-classes-list.hheader to generate each unique->info()methods within the method table. All this was big and complicated enough that I broke out a separateerror-methods.hheader.The net result is a Python class hierarchy with

infomethods that produce tuples of the data we required.To make my specific improvement, I then exposed
ApplicabilityResult, a list of which is included in theNoMatchingCandidateserror. ThisApplicabilityResultincludes the actual of the call that could not be passed. This conversion is nigh-trivial, since ourPythonClassWithContextabstraction provides working defaults with nearly no additional boilerplate.With this, I was finally able to write my logic in
chapel.lspto provide more specific locations for errors in which a single actual caused all candidate matching failures. I also went ahead and provided nicer error locations for a few other error messages.My future work for this is to explore using the newly-provided error information for other things, such as fixits for simple errors. This PR is complicated enough now that I do not intend to do that here.
Reviewed by @jabraham17 -- thanks!
Testing