Bug 23665 – Add traits to retrieve template parameter information

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-02-02T16:02:51Z
Last change time
2024-12-13T19:27:03Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20223 →

Comments

Comment #0 by qs.il.paperinik — 2023-02-02T16:02:51Z
Add `__traits` to expose information about a template’s parameters: A template parameter has the following properties: 1. An identifier. 2. A kind: It is a value parameter, a type parameter, an alias parameter, or a sequence parameter. Arguably, a template `this` parameter is a type parameter, but IMO, it should be its own kind. 3. A type if it is a value parameter. (Alias and sequence parameters can be bound to value arguments that have types, but the parameter itself has no type.) 4. Optionally a constraint. 5. Optionally a default. Chellanges: 1. Only values have types. 2. Types, constraints, and defaults might not be accessible, a symbolic (not a string) return is useful. 3. Types, constraints, and defaults can be dependent on previous paramters; a symbolic return is not possible in that case. Proposed specification: First, provide the trait `templateParameterLength` taking an alias to a template that returns the number of (lexical) template parameters. (By lexical, I mean that a sequence parameter counts as exactly 1 parameter, even if logically, it is “0 or many”.) Note: For the following that take an index, if the index is out of range (≥ `templateParameterLength`), it is a compile error. The wording assumes that the index is in range. For each template parameter property, provide a trait named `templateParameter(Identifier|Kind|Type|Constraint|Default)`, respectively, taking an alias to a template and an index that returns compile-time information of the respective properties (if available – a parameter might not have a type, constraint, or default). E.g. `__traits(templateParameterKind, std.meta.AliasSeq, 0)` returns the kind of the only parameter: sequence. Also provide the trait `templateParameterHas(Type|Constraint|Default)` taking an alias to a template and an index that returns a bool providing information about the availability of that property: `templateParameterHasType` is a compile-error when the parameter is not of kind value. (The programmer should use `static if` to enusre the parameter queried is of kind value.) It returns `true` if the type is independent of previous template parameters and `false` if it is dependent on them. (This might be a best-effort, i.e. there could be edge cases in which `false` could be returned when `true` is actually possible.) `templateParameterHas(Constraint|Default)` returns returns `true` if the template parameter has a constraint or default, respectively. Identifiers are returned as strings (cf. `__traits(identifier)`). Unnamed parameters are syntactically not possible, the string is never empty or `null`. The kind could be designated by a finite set of strings ("value", "type", "alias", "sequence", and "this") or by values of an `enum`. `__traits(templateParameterType)` returns a sequence consisting of 1 or 2 entries: The first entry is the string used to define the parameter; the second entry is present and an alias to the type when `__traits(templateParameterHasType)` is `true` (and thus the type is well-defined). For constraints and defaults, `__traits(templateParameter(Constraint|Default))` compiles if `__traits(templateParameterHas(Constraint|Default))` is `true`. Because constraints and defaults can depend on previous parameters, they cannot always be extracted symbolically. Again, a sequence consisting of 1 or 2 entries is returned: The first entry is the string consisting of the tokens making up the constraint/default, the second is present if the constraint/default is independent of previous parameters and thus can be extracted symbolically.
Comment #1 by robert.schadek — 2024-12-13T19:27:03Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20223 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB