-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Declaration and definition of impls and their associated functions #4672
Comments
In discussions we considered a number of possible approaches. There was one family of "definition in the impl file" approaches where an impl is usable by importers as long as it is declared in the api file. The impl declaration would fix the non-function associated constants. The impl definition would be allowed to live in the impl file. There were a number of variations on how the out-of-line associated function bodies would be ordered with respect to the impl definition:
We didn't like that this family of approaches made it convenient and natural to put the impl's function signatures in the impl file, forcing callers to use the function signatures in the interface in many cases. |
Another approach put the impl declaration and definition are in the api file, but out-of-line associated function bodies could be defined in the impl file. The non-function associated constants would be fixed by the declaration and the function signatures would be fixed by the definition, acting as a forward declaration of any functions whose bodies were not defined in the impl definition. Out-of-line function bodies would be allowed in the impl file. |
The approach we ended up favoring was the "most like classes" approach. Here:
We liked that this gave some flexibility in ordering, since you could say that a type implemented an interface before you could name all the values of its associated constants or the types mentioned in the associated function signatures (when they were different from the interface's). We also liked the idea of allowing the definition to be short by not repeating the interface function signatures when they matched. We thought that an impl could explicitly specify that it was using the default function body from the interface by writing |
Further details:
|
* Change `InterfaceWitness` -> `ImplWitness` * Include a `SpecificId` in the `ImplWitness`. This allows the `InstBlock` it contains to have its own identity, allowing it to be changed as the impl is processed. Evaluation only updates the specific. * Create the `ImplWitness` at the start of the impl definition. In the future, this will be populated with the values of non-function associated constants. For now, it starts full of invalid instruction ids. * Implements the model suggested in #4672 . Note that the non-SemIR testdata changes are to these file: * `toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon` * `toolchain/check/testdata/struct/import.carbon` * `toolchain/check/testdata/tuple/import.carbon` The last two are due to an import of generics bug exposed by this PR, which will be fixed in a follow-on. --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com> Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Per discussion from 2025-01-21, we are going to try something simpler at first:
This is subject to change once we get some experience if we discover that this makes it too hard to break dependency cycles in cases we would like to support. |
Given the discussion about Note, Java uses |
…` clause (#4850) Based on [the lastest thinking on #4672](#4672 (comment)) , require a full syntactic match for impl redeclaration, instead of excluding the `where` restriction. This means no updates to the impl witness on redeclaration, and no diagnostics that those updates are consistent. Not included in this PR, but will need to be done in the future: * Support for assigning values to associated constants in the body of the impl definition. This will require moving the checking that non-function associated constants are set from the definition start to definition end. * Identify semantic redeclarations that are not syntactic matches to give a failed redeclaration diagnostic. This should be done once we are already identifying impl declarations with the same type structure in order to require they be identified in an impl_priority/match_first block. * Merging of the functions in `check/impl.cpp` that are now always called together. Also add some test coverage of `where` parsing I developed in PR I've now abandoned because of this new simplification of the impl redeclaration semantics. --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com> Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Summary of issue:
There are three aspects of an impl specified by a developer:
addr self
method in the interface my be implemented by aself
method in the impl.The first and last aspects can have defaults specified by the interface if the
default
modifier is used on that member. Furthermore, in some sense the interface's signatures for associated functions can be thought of as default signatures for the corresponding impl functions.This leads us to some questions:
;
)? by an impl definition (with curly braces{
...}
)?There are some existing answers to these questions in the design, but I believe it is time to re-evaluate given that (a) I understand we have defined a syntax for implementing function bodies outside of the impl definition (mentioned in #3763), and (b) I am working on implementing these concerns in the toolchain.
Details:
There are some desirable traits a solution might have:
The text was updated successfully, but these errors were encountered: