Skip to content

Should declaration variance support an explicit "covariant" marker? #2078

Open
@leafpetersen

Description

@leafpetersen

We have discussed adding declaration site variance as a non-breaking feature in which type parameters to classes may be marked as out (statically checked covariant), in (statically checked contravariant), or inout (statically checked invariant). In order to make the change non-breaking, unmarked type variables would continue to be treated as runtime checked covariant. This issue is to discuss whether or not we should also add an explicit marker for runtime checked covariant classes.

Syntax

An initial proposed syntax for the marker is covariant to match the existing covariant marker on term level parameters. Example:

class C<covariant T, inout S> {
  S f1(S x) => x; // Valid because S is invariant
  T f2(T x) => x; // Valid because T is covariant
}

Semantics

A type parameter marked with this modifier would be treated as runtime checked covariant exactly as if no modifier were on the type parameter. That is, for the language, class A<T> ... and class A<covariant T> ... would be treated equivalently. Example:

class A<covariant T, S> {
  S f1(S x) => x; // Valid because S is runtime checked covariant, runtime check inserted on argument
  T f2(T x) => x; // Valid because T is runtime checked covariant, runtime check inserted on argument
}

Motivation

There are several motivations behind this proposal.

The first is that some set of our users will very likely prefer to always use statically checked variance, and will prefer that any runtime checked classes be marked explicitly covariant. This enables such marking, with a lint to prevent unmarked type parameters from being introduced.

The second is that it gives us a potential path forward towards changing the default behavior. If we eventual reach a point where the majority of code uses explicit covariant, we could then choose to make inout or out the default in a language versioned breaking change.

Discussion

Since this has no semantic significance in the proposal, the same effect in the short term could be achieved with an annotation associated with a lint. This doesn't provide any organic migration path however.

cc @eernstg @lrhn @munificent @natebosch @jakemac53 @stereotype441

Metadata

Metadata

Assignees

No one assigned

    Labels

    varianceIssues concerned with explicit variance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions