Skip to content

Interface error improvements - #12594

Merged
0x6e merged 17 commits into
masterfrom
nathan/interface-error-improvements
Jul 29, 2026
Merged

Interface error improvements#12594
0x6e merged 17 commits into
masterfrom
nathan/interface-error-improvements

Conversation

@0x6e

@0x6e 0x6e commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Reorganise the interface syntax tests (17 -> 9 files) around the compiler's validation stages so every diagnostic is asserted exactly once: declaration-body rules, interface/target resolution, self-implementation conformance, child delegation, cross-statement conflicts and parser-level grammar errors, keeping the two regression guards untouched. Drop the runtime test that duplicated implements_defaults.

We then iterated through the various errors to:

  • group multiple errors for the same statement into one error;
  • provide better descriptions of what the expected interface API should be;
  • consolidate the error creation code into functions that are re-used.

This resulted in us being able to remove interfaces::validate_function_implementations and rename interfaces::validate_properties_and_callbacks to interfaces::validate_self_implement_statements which no longer filters out function declarations.

Relates to #1870.


Stack created with GitHub Stacks CLIGive Feedback 💬

@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch from 6d2dab7 to 290ba4a Compare July 22, 2026 16:00
@0x6e
0x6e marked this pull request as ready for review July 22, 2026 17:00
@0x6e
0x6e requested a review from LeonMatthes July 22, 2026 17:01

@LeonMatthes LeonMatthes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Much better.

It would be great if we can show the actual code that needs to be added.
And I think we should keep the check errors on the implement statement instead of the implementation candidate (with potentially a note diagnostic on the candidate).

Comment thread internal/compiler/tests/syntax/interfaces/interface_grammar.slint Outdated
Comment thread internal/compiler/tests/syntax/interfaces/interface_grammar.slint
Comment thread internal/compiler/tests/syntax/interfaces/implement_self.slint Outdated
Comment thread internal/compiler/tests/syntax/interfaces/implement_self.slint Outdated
Comment thread internal/compiler/tests/syntax/interfaces/implement_self.slint Outdated
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch from 290ba4a to b1d9c5a Compare July 27, 2026 10:52
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch 2 times, most recently from 468adca to 2c5e839 Compare July 27, 2026 18:17
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch from 2c5e839 to 796eb63 Compare July 27, 2026 20:10
Base automatically changed from nathan/function-callback-display to master July 28, 2026 07:56
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch from 796eb63 to ccc102e Compare July 28, 2026 09:10
@0x6e
0x6e requested a review from LeonMatthes July 28, 2026 09:11

@LeonMatthes LeonMatthes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is definitely an improvement.

I left a few more ideas for further refinement. As discussed, these can be done as another follow-up.

Comment thread internal/compiler/object_tree/interfaces.rs Outdated
Comment thread internal/compiler/object_tree/interfaces.rs
Comment thread internal/compiler/tests/syntax/interfaces/implement_self.slint
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch 2 times, most recently from 2031621 to 097664a Compare July 29, 2026 14:56
0x6e and others added 7 commits July 29, 2026 18:01
Reorganise the interface syntax tests (17 -> 9 files) around the compiler's
validation stages so every diagnostic is asserted exactly once:
declaration-body rules, interface/target resolution, self-implementation
conformance, child delegation, cross-statement conflicts and parser-level
grammar errors, keeping the two regression guards untouched. Drop the runtime
test that duplicated implements_defaults.

The child-forward "Cannot override binding" branch was unreachable - a
pre-existing binding for an interface member is always intercepted by the
earlier base-conflict or declaration-conflict checks - so replace it with a
debug_assert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `uses` keyword has been replaced with the `implement` statement.
Remove the old language from the syntax errors.
Rewrite the diagnostics emitted by `property_matches_interface` so that
a mismatch between a component's API and an implemented interface is
described precisely — the member's kind (property / callback /
function), its visibility, and its purity. Multiple mismatches on a
single member are presented as a multi-line list.
…gnostic

Rather than emitting a error for every issue with a child-implement
statement, consolidate them into one error with a list of issues.
… diagnostic for the `implement` statement

Rather than emitting an error per conflict consolidate them all into a
single error with a list of conflicts.
…a single diagnostic for the `implement` statement

Rather than emitting an error per conflict consolidate them all into a
single error with a list of conflicts.

This function may still emit other diagnostics where the error source is
not the `implement` statement.
Re-use the `missing_type_description` lambda to describe a missing
property or callback in `validate_interface_member_implementation`.
0x6e added 10 commits July 29, 2026 18:01
Rather than saying "Cannot implement 'Interface'" we shorten it to
"'Interface' error." followed by the list of conflicts. This is less
verbose, doesn't mention the `implement` keyword where it is not the
cause of the error and is just a bit nicer to read.
Remove `interfaces::validate_function_implementations` and rename
`interfaces::validate_properties_and_callbacks` to
`validate_self_implement_statements`. The new function no longer filters
our function declarations, allowing us to use the same checking code and
errors for all interface API.
…rface function implementation

The langtype::Function implementation of PartialEq means that the
compiler would emit an error if the implementation of an interface did
not have exactly matching parameter names. We do not require this to
satisfy interface API, so introduce our own comparison function for
langtype::Type.
…don't match

For example, `public` or `protected` function visibility doesn't make
much sense in a property context (expects `in`, `out`, `in-out`). In
this case, we emit the full type that the interface expects so that the
user can get it right in one iteration.
Improve the parsing and compiler error to make it clear that interface
inheritance is not supported (yet).
Add a syntax test to verify that `@rust-attr` does not support
annotating interfaces.
Interface errors that occur due to a missing member, or a member being
fully the wrong type (e.g. property instead of callback) now print the
required Slint code.
Add a generic note to the unsatisfactory statement. In the future we can
make this more specific.
Before we were emitting notes before the relevant errors which was not
very useful when looking at `slint-compiler` output. Now we emit the
notes after the error, giving us more understandable compiler output:

```
error: Cannot implement 'ValidInterface'.
       - 'reset' must be a 'public function() -> void' (found a 'int' property)
       - 'speak' must be a 'callback() -> void' (found a 'int' property)
       - 'value' must be an in-out 'int' property (found a 'callback() -> void')
   --> internal/compiler/tests/syntax/interfaces/implement_self.slint:255:15
    |
255 |     implement ValidInterface <=> self;
    |               ^^^^^^^^^^^^^^^
note: 'reset' does not satisfy 'ValidInterface'
   --> internal/compiler/tests/syntax/interfaces/implement_self.slint:262:5
    |
262 |     in-out property <int> reset;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: 'speak' does not satisfy 'ValidInterface'
   --> internal/compiler/tests/syntax/interfaces/implement_self.slint:260:5
    |
260 |     in-out property <int> speak;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: 'value' does not satisfy 'ValidInterface'
   --> internal/compiler/tests/syntax/interfaces/implement_self.slint:258:5
    |
258 |     callback value();
    |     ^^^^^^^^^^^^^^^^^
```
…ing uses

Verify that the new `implement` keyword doesn't break existing uses of
the name "implement" for properties/callback/functions/etc.
@0x6e
0x6e force-pushed the nathan/interface-error-improvements branch from 097664a to b7ae663 Compare July 29, 2026 17:02
@0x6e
0x6e merged commit 52c7894 into master Jul 29, 2026
95 of 97 checks passed
@0x6e
0x6e deleted the nathan/interface-error-improvements branch July 29, 2026 18:11
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.

2 participants