Skip to content

spec: function type inference should work in all assignment contexts #77245

Closed

Description

@griesemer

The Go 1.21 release introduced significantly improved type inference. Specifically:

A (possibly partially instantiated generic) function may now be called with arguments that are themselves (possibly partially instantiated) generic functions. The compiler will attempt to infer the missing type arguments of the callee (as before) and, for each argument that is a generic function that is not fully instantiated, its missing type arguments (new). [ ... ] More generally, a generic function may now be used without explicit instantiation when it is assigned to a variable or returned as a result value if the type arguments can be inferred from the assignment.

As stated, this type inference works in assignments, but it doesn't work for all assignments. For instance, given (playground):

type S struct{ f func(int) }

func g[T any](T) {}

func _(s S) {
	s.f = g          // ok
	s = S{f: g}      // error: cannot use generic function g without instantiation
	s = S{f: g[int]} // ok
}

The assignment of the generic function g to the function-typed field f of struct S works as described but the same (implicit) assignment to field f in the struct literal does not - explicit instantiation of g is required.

The same is true for assignments to array, slice, or map elements vs the same (implicit) assignment in the respective composite literals, and sends to channels (playground):

type F func(int)
type A [10]F
type S []F
type M map[string]F
type C chan F

func g[T any](T) {}

func _() {
	var a A
	a[0] = g      // ok
	a = A{g}      // error: cannot use generic function g without instantiation
	a = A{g[int]} // ok

	var s S
	s[0] = g      // ok
	s = S{g}      // error: cannot use generic function g without instantiation
	s = S{g[int]} // ok

	var m M
	m["foo"] = g         // ok
	m = M{"foo": g}      // error: cannot use generic function g without instantiation
	m = M{"foo": g[int]} // ok

	var c C
	c <- g      // error: cannot use generic function g without instantiation
	c <- g[int] // ok
}

In all these cases we have an assignment where the type on the LHS is completely known and thus the function type parameter can be inferred unambiguously, and should be inferred for consistency.

While making this change likely requires some clarifications in the spec, I believe this is arguably a bug rather than a language change because the assignments (a[0] = g) work, but the implicit assignments in composite literals don't (a = A{g}). The exception is channel sends, but even in that case the element to be sent must be assignable to the channel element type and thus establishes a clear "target" type.

Correction:
The spec is explicit about where this inference is supposed to work (see Instantiations). I believe it makes sense to generalize to all assignment contexts but that requires a spec change and proposal.

Activity

  1. added this to the Go1.27 milestone on Jan 20, 2026
  2. added theissue type on Jan 20, 2026
  3. griesemer commented on Jan 20, 2026

    @griesemer
    ContributorAuthor

    @neild just FYI.

  4. added
    BugReportIssues describing a possible bug in the Go implementation.
    on Jan 20, 2026
  5. next-n commented on Jan 21, 2026

    @next-n

    Hi Griesemer, would you mind if I take a look and try a fix for this?

  6. next-n commented on Jan 21, 2026

    @next-n

    Hi @griesemer — I opened a PR with a proposed fix and test for this issue:

    #77247

    Happy to adjust if you’re already working on it.

  7. gopherbot commented on Jan 21, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/737800 mentions this issue: cmd/compile: allow generic function values in composite literals

  8. gopherbot commented on Jan 28, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/739560 mentions this issue: go/types, types2: improve type inference for assignment contexts

  9. griesemer commented on Jan 29, 2026

    @griesemer
    ContributorAuthor

    @mrkfrmn I forgot one case: conversions. x in a conversion T(x) is also in "assignment context" because the conversion is valid if x is assignable to T (spec).

  10. 31 remaining items

  11. added a commit that references this issue on Apr 21, 2026
    f757de8
  12. gopherbot commented on May 26, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/783362 mentions this issue: doc: document generalized function type inference (update release notes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

LanguageChangeSuggested changes to the Go languageLanguageProposalIssues describing a requested change to the Go language specification.ProposalProposal-AcceptedTypeInferenceIssue is related to generic type inference

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions