Skip to content

Implement type alias parameter variance for super-bounded types #33444

@eernstg

Description

@eernstg

As of commit bfa8be8, and following up on the discussion in #33261, each parameter in a parameterized type alias has an associated inferred variance (which classifies that parameter as covariant, contravariant, invariant, or neither of those).

The variance of a type alias parameter is used in the determination of whether any given type is super-bounded, in that only a covariant parameter occurs covariantly in a parameterized type based on that type alias (so T occurs covariantly in G<T> when the type parameter of G is covariant, and T occurs covariantly in G<int Function(T)> when the type parameter of G is contravariant, etc), and similarly for occurring contravariantly and invariantly.

For example:

// The type parameter X of Fco is covariant because it is used in a
// covariant position, and only that, in the type on the right hand side.
typedef Fco<X extends int> = X Function();

// The type parameter X of Fct is contravariant because it is used in a
// contravariant position, only, in the type on the right hand side.
typedef Fct<X extends int> = void Function(X);

// The type parameters X of Fin1 and Fin2 are invariant because they are used
// in an invariant respectively both a covariant and a contravariant position
// in the type on the right hand side.
typedef Fin1<X extends int> = void Function<Y extends X>();
typedef Fin2<X extends int> = X Function(X);

// The type parameter X of F has no variance. Super-bounding is pointless,
// and not supported.
typedef F<X extends int> = void Function();

main() {
  // Correctly super-bounded, because `Fco<Null>` is regular-bounded.
  Fco<dynamic> v1; //# 01: ok
  // Not correctly super-bounded, because `Fct<dynamic>` is not regular-bounded.
  Fct<dynamic> v2; //# 02: compile-time error
  Fct<Null> v2b; // Regular-bounded (no need to consider substitutions).
  // Not correctly super-bounded, because `Fin1<dynamic>` is not regular-bounded.
  Fin1<dynamic> v3; //# 03: compile-time error
  Fin1<Null> v3b; // Regular-bounded.
  // Not correctly super-bounded, because `Fin2<dynamic>` is not regular-bounded.
  Fin2<dynamic> v4; //# 04: compile-time error
  Fin2<Null> v4b; // Regular-bounded.
  // Not correctly super-bounded, because `F<dynamic>` is not regular-bounded.
  F<dynamic> v5; //# 05: compile-time error
  F<Null> v5b; // Regular-bounded.
}

This issue is concerned with the implementation of support for this behavior, and in particular for detecting this kind of compile-time error.


Subtasks

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-metaCross-cutting, high-level issues (for tracking many other implementation issues, ...).

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions