Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mark-rushakoff opened this issue Aug 29, 2024 · 6 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. TypeInference Issue is related to generic type inference
Milestone

Comments

@mark-rushakoff
Copy link
Contributor

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.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Aug 29, 2024
@gabyhelp
Copy link

@ianlancetaylor ianlancetaylor added the TypeInference Issue is related to generic type inference label Aug 29, 2024
@ianlancetaylor
Copy link
Member

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.

@mark-rushakoff
Copy link
Contributor Author

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.

@griesemer
Copy link
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.

@griesemer griesemer self-assigned this Aug 29, 2024
@griesemer griesemer added this to the Go1.24 milestone Aug 29, 2024
@griesemer
Copy link
Contributor

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

@griesemer
Copy link
Contributor

Moving to 1.25.

@griesemer griesemer modified the milestones: Go1.24, Go1.25 Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. TypeInference Issue is related to generic type inference
Projects
Development

No branches or pull requests

5 participants