Skip to content

cmd/compile: type parameter involving constraint with channels seems like it should be inferrable #69153

Open

Description

@mark-rushakoff

Go version

go1.23 and go tip

Output of go env in your module/workspace:

n/a, using go.dev/play

What did you do?

https://go.dev/play/p/-psvliJDE_j

package main

import "fmt"

// Constraint to allow function to operate on a channel,
// regardless of the channel's directionality.
type channelConstraint[T any] interface {
	chan T | <-chan T | chan<- T
}

func main() {
	var sendOnlyCh chan<- string = make(chan string)
	printCap(sendOnlyCh)
	// Needs to be:
	printCap[string](sendOnlyCh)

	var receiveOnlyCh <-chan int = make(chan int, 1)
	printCap(receiveOnlyCh)
	// Needs to be:
	printCap[int](receiveOnlyCh)

	bidiCh := make(chan any)
	printCap(bidiCh)
	// Needs to be:
	printCap[any](bidiCh)
}

// printCap prints the capacity of ch,
// regardless of ch's directionality.
func printCap[T any, C channelConstraint[T]](ch C) {
	fmt.Println(cap(ch))
}

I want to write a small utility that takes a specific action that is determined by a channel's length and/or capacity. In this codebase, there are a general mix of directional and bidirectional channels. I thought I would be able to write a constraint such that my helper can accept a channel of any directionality. And I can indeed write that constraint, but when I call a function with that constraint, I have to provide the channel's element type as a type parameter in order to get the program to compile.

I am surprised that I have to provide the channel's element type, but maybe I am missing something about constraints or generics.

What did you see happen?

./prog.go:13:10: in call to printCap, cannot infer T (prog.go:28:15)

What did you expect to see?

I expected that printCap(ch) would compile; that I would not have to write printCap[int](ch).

I tried searching the issues for variations of "constraints", "channels", and "direction" or "directionality" but I was not able to find any issues that looked similar.

Activity

  1. ianlancetaylor commented on Aug 29, 2024

    @ianlancetaylor
    Contributor

    CC @griesemer

    I think we would need a special type inference rule for channel types.

    Note that I think that your program isn't going to work anyhow. The cap(ch) call isn't permitted, though that would be fixed by #63940.

  2. mark-rushakoff commented on Aug 29, 2024

    @mark-rushakoff
    ContributorAuthor

    Adjusting the code to remove the lines that failed compilation, it does appear that cap(ch) is reported correctly, on go1.23. https://go.dev/play/p/jS1_QIeyrUF

    It looks like len(ch) works too.

  3. griesemer commented on Aug 29, 2024

    @griesemer
    Contributor

    What @ianlancetaylor said. The issue here is that there's no core type for the constraint. At the moment inference does work if the constraint was just chan T | <-chan T or chan T | chan<- T (there's a core type) but instantiation doesn't work of course for the one direction that's not in the constraint.

    This might also be addressed by #63940.

  4. self-assigned this
    on Aug 29, 2024
  5. added this to the Go1.24 milestone on Aug 29, 2024
  6. griesemer commented on Aug 29, 2024

    @griesemer
    Contributor

    Marking for 1.24 - not promising that this will be addressed, but so I keep an eye on it while investigating #63940.

  7. griesemer commented on Oct 23, 2024

    @griesemer
    Contributor

    Moving to 1.25.

  8. modified the milestones: Go1.24, Go1.25 on Oct 23, 2024
  9. modified the milestones: Go1.25, Go1.26 on Jun 10, 2025
  10. modified the milestones: Go1.26, Go1.27 on Nov 24, 2025
  11. modified the milestones: Go1.27, Go1.28 on Jun 2, 2026
  12. gopherbot commented on Sep 9, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/829606 mentions this issue: cmd/compile, spec: infer E via interface{ <-chan E | chan<- E }

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

Metadata

Metadata

Assignees

Labels

TypeInferenceIssue is related to generic type inferencecompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions