digitalmars.D.bugs - [Issue 23666] New: Recognize template opApply pattern
- d-bugmail puremagic.com (71/71) Feb 02 2023 https://issues.dlang.org/show_bug.cgi?id=23666
https://issues.dlang.org/show_bug.cgi?id=23666 Issue ID: 23666 Summary: Recognize template opApply pattern Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: qs.il.paperinik gmail.com Normally, when `opApply` is a template, `foreach` variable types cannot be inferred and must be stated explicitly. I propose an exception to this rule to make implementing `opApply` with respect to attributes (safe, nogc, pure, nothrow) easier[1, 2]. Basic idea: Make `opApply` a template to infer attributes based on the delegate argument’s type. If `opApply` is a template with a single template type parameter that is used as the type of the single function parameter and is additioanlly constrained to a delegate type, we can use that type to infer `foreach` variable types. A minimal example: ```d struct S { int opApply(DG : int delegate(int))(DG dg) { return 0; } } void main() safe { foreach (x; S()) // infer `int` for x { } } ``` Details: When all `opApply` function templates in an aggregate have as their first template parameter a type parameter that is “aptly” constrained[5] (“aptly” defined blow), the respective instantiations with the constraint type are valid (i.e. instantiate `opApply(DG : Constraint)` as `opApply!Constraint`), and the resulting template instance (a member function) can be called with 1 argument of the type of the constraint (i.e. `opApply!Constraint(Constraint.init)` compiles), these member function templates are added to non-template `opApply` member functions used to determine `foreach` types. To be “aptly constrained” means that the constraint is a type of the following form: ```d int delegate ParameterList MemberFunctionAttributes` ``` where `ParameterList` and `MemberFunctionAttributes` [3, 4] are defined in the D grammar. The parameters of the `ParameterList` in an “apt” constraint are considered together with `ParameterList`s of non-template `opApply(int delegate ParameterList MemberFunctionAttributes)` (if any) to find the best match in terms of number and `ref`-ness. If the best match for a given `foreach` statement is such a template instance, it is instantiated again with the type of the `foreach` lambda, where the types of the `foreach` body lambda’s parameters are set to the types determied by the constraint in the `opApply` template. A template `opApply` may have more than one template parameter and more than one function parameter when the additional parameters have defaults. [1] Relevant thread: https://forum.dlang.org/thread/zlzhrzzamwkohturhrhc forum.dlang.org [2] Relevant post: https://forum.dlang.org/post/uquebghlhhstkuxtulwf forum.dlang.org [3] https://dlang.org/spec/function.html#Parameters [4] https://dlang.org/spec/function.html#MemberFunctionAttributes [5] https://dlang.org/spec/template.html#Constraint --
Feb 02 2023