Skip to content

[extension-types] Allow a redirecting factory constructor to redirect to a representation type constructor #3794

Open
@eernstg

Description

@eernstg

This is a proposal that we should allow a redirecting factory constructor of an extension type to redirect to a constructor of a type which is the representation type or some subtype thereof. For example:

class _C<X> {
  final X x;
  const _C(this.x);
  X get value => x;
}

extension type C<X>._(_C<X> _) implements _C<X> {
  const factory C(X x) = _C; // Currently an error; proposal is to allow it.
  X conditionalValue(bool condition, {required X Function() orElse}) =>
      condition ? x : orElse();
}

void main() {
  C<num> c = C<int>(14);
  num n = 2;
  n = c.conditionalValue(true, orElse: () => n); // OK, yields 14.
}

The point is that there is no soundness related reason to not allow this, and it is helpful in the case where we wish to use the statically known receiver type to provide the value of a type argument like X (which is often desirable for named arguments with the name orElse ;-).

In contrast, consider the following:

final class C<X> {
  final X x;
  const C(this.x);
  X get value => x;
  X conditionalValue(bool condition, {required X Function() orElse}) =>
      condition ? x : orElse();
}

void main() {
  C<num> c = C<int>(14);
  num n = 2;
  c.conditionalValue(true, orElse: () => n); // Throws!
}

In this variant, a run-time type error occurs because the argument passed to orElse has type num Function(), but the covariance based run-time type check requires an int Function(). In this kind of situation, the covariance based run-time type check is actually harmful, because there is nothing in the logic of the given method that requires this function to have the more special type, it is all fully well-typed as seen from the call site and at run time when we rely on the statically known value of the type variable.

We could get a similar effect by introducing support for lower bounds on the type parameters of generic functions (see #1674), but this proposal seems simpler, and none of these proposals subsume each other completely (for example, the lower bounds feature wouldn't allow the C extension type constructor to be constant).

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-types-laterIssues about extension types for later considerationsmall-featureA small feature which is relatively cheap to implement.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions