Skip to content

cmd/compile: allow parameterized type aliases to omit redundant type parameters #68617

Open
@adonovan

Description

@adonovan

#46477 is an accepted proposal to allow type parameters on aliases, although the implied change to the spec wording has not yet been fleshed out, so it's not clear whether the current issue is a compiler bug or a request to change the spec.

When instantiating a parameterized function, it is legal to omit one or more type parameters (a suffix of the parameter tuple) if they can be inferred from the argument types. For example, all three of these uses of Contains are instantiated the same way, even though only the first is fully explicit:

https://go.dev/play/p/o3WFjULJVqE

	_ = slices.Contains[mySliceType, string](slice, "")
	_ = slices.Contains[mySliceType](slice, "")
	_ = slices.Contains(slice, "")

This inference needn't be based on the types of the arguments, but can also proceed from the explicit type arguments, as in this variant where the argument types alone are insufficient:

func _(slice mySliceType) {
	_ = slices.Contains[mySliceType](nil, "") // inferred as [mySliceType, mystring]
}

type mystring string
type mySliceType []mystring

Parameterized type aliases should behave in an analogous way. That is, if the first type arguments to a parameterized type alias are sufficient to determine the instantiation, the others should not be required. However, that is not the current behavior of the compiler:

https://go.dev/play/p/BkWFFkHDKPW?v=gotip

type SliceElementType[Slice ~[]Elem, Elem any] = Elem

var _ SliceElementType[myStringSlice] // error: not enough type arguments

I see two reasons for making the analogy. The first is symmetry. The second is that parameterized type aliases with this inference may be used to express "pure functions over types", including destructuring operators. For example, the SliceElementType[T] operator is the inverse of the []T operator: the latter adds a slice type constructor, and the former strips it off. This is a useful form of expressiveness that allows you to denote the element type of an arbitrary slice type, which might not otherwise be expressible. One can imagine similar operators for denoting the elements of pointer, map, and chan types, the parameters and result types of functions, and (someday) the types of struct fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Thinkingcompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions