Skip to content

[Feature]: ergonomic call-site for [AssertionExtension] classes that introduce their own generic parameter #5922

@JohnVerheij

Description

@JohnVerheij

Problem Statement

Once the dual-generic emit bug (#5918) is fixed, an [AssertionExtension] class with its own generic parameter and a concrete (covariance-candidate) receiver compiles cleanly. The remaining friction is the call-site: the generated extension's signature is Matches<TActual, T>(this IAssertionSource<TActual> source, Func<T, bool> predicate, ...) where TActual : Exception, which means callers have to specify TActual explicitly when they only care about T:

Assert.That(ex).Matches<Exception, MyPayload>(p => p.IsValid);

Type inference can pick up T from the predicate argument, but it can't pick up TActual from the receiver expression alone, so the redundant Exception has to be written out at every call site.

Proposed Solution

This is a design call rather than a prescription, but the desired ergonomic end-state is: when the receiver type is concrete (the covariance-candidate branch the generator already detects), the call-site only needs to specify the class's own generic parameters. The receiver type isn't repeated.

There are a few plausible shapes for this (omit the covariant TActual and pin the receiver to IAssertionSource<TConcrete> directly; emit an additional inference-friendly overload alongside the covariant one; encode it through a constraint shape the inferencer can resolve from the receiver). Would prefer to wait on your steer about which shape fits the rest of the generator's design before opening a PR for this.

Alternatives Considered

  • Live with the explicit type argument. Works, but every call site repeats the receiver type. Verbose for the most common case.
  • Drop covariance support for this shape. Restores inference but loses the ability to assert against a subclass of the declared receiver.
  • Workaround at the call site: wrap the assertion in a helper that fixes TActual. Adds boilerplate that the generator could in principle absorb.

Feature Category

Assertions

How important is this feature to you?

Nice to have - would improve my experience

Additional Context

This is downstream of the dual-generic-emit fix (#5918). The emit fix is structural. Without it the generated source doesn't compile at all. This issue is purely about call-site ergonomics once the compile-time bug is gone.

Contribution

  • I'm willing to submit a pull request for this feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions