Captured generic type arguments in constraints (associated type alias via using T
)
#9632
Replies: 1 comment
-
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Captured generic type arguments in constraints (associated type alias via
using T
)Summary
Introduce a way to “capture” generic type arguments appearing inside constraints and expose them as local type parameters without increasing the generic arity of the declaring method/type. The proposed syntax allows writing constraints like
IValidator<using TRequest>
,where using TRequest
declares a captured type parameterTRequest
that is inferred (bound) from the constrained type’s implementation. This removes redundant explicit type parameters that are only there to “pipe through” an associated type of another generic.Motivation
Today, APIs frequently need to couple one type parameter to another via a constraint, e.g.,
where TValidator : IValidator<TRequest>
. In most such cases,TRequest
is not a degree of freedom that the caller conceptually chooses; instead, it is logically owned byTValidator
and should be inferred from it. Requiring an explicitTRequest
:TValidator
andTRequest
).The proposal removes
TRequest
from the public arity while keeping it strongly typed and available inside the declaration body.Detailed design
New concept: captured type parameter
Grammar sketch
type_argument ::= type | using identifier
Binding and semantics
where TValidator : IValidator<using TRequest>
, the compiler searches the actual type substituted forTValidator
for an implementation that makes it anIValidator<X>
for someX
. If suchX
exists and is unambiguous, bindTRequest := X
.where TValidator : IValidator<using TRequest> where TRequest : class
TRequest := X
).Ambiguity rules
X
satisfy the capture for the same using parameter (e.g., the type implementsIValidator<Foo>
andIValidator<Bar>
), binding is ambiguous and the declaration is not applicable at the call site. The compiler should report a dedicated diagnostic (e.g., “ambiguous associated type binding for ‘TRequest’”).where TRequest : FooBase
) or by reverting to an explicit type parameter.Variance
Metadata and reflection
SomeType<TRequest>
) behave as ifTRequest
were a regular type parameter bound at use time, with a concrete type substituted upon successful binding.Overload resolution
Constraints visibility order
Restrictions
Examples
Current (redundant explicit type parameter)
Proposed (captured associated type)
Multiple captured associated types
Ambiguity and disambiguation
Variance-aware capture
Unresolved questions
Prior art
Rust
(traits) andSwift
protocols solve a similar problem by tying a type member to a conforming type.C#
today emulates this with extra generic parameters plus constraints, which this proposal streamlines.Implementation notes
using T
to actual interface/base implementations; upon success, bind the captured parameter.(a)
use of using outside constraints,(b)
name collisions,(c)
ambiguous capture,(d)
capture not found.Benefits
Beta Was this translation helpful? Give feedback.
All reactions