You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cmd/compile: type parameter involving constraint with channels seems like it should be inferrable #69153
package main
import"fmt"// Constraint to allow function to operate on a channel,// regardless of the channel's directionality.typechannelConstraint[Tany] interface {
chanT|<-chanT|chan<-T
}
funcmain() {
varsendOnlyChchan<-string=make(chanstring)
printCap(sendOnlyCh)
// Needs to be:printCap[string](sendOnlyCh)
varreceiveOnlyCh<-chanint=make(chanint, 1)
printCap(receiveOnlyCh)
// Needs to be:printCap[int](receiveOnlyCh)
bidiCh:=make(chanany)
printCap(bidiCh)
// Needs to be:printCap[any](bidiCh)
}
// printCap prints the capacity of ch,// regardless of ch's directionality.funcprintCap[Tany, CchannelConstraint[T]](chC) {
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.
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
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.
Activity
gabyhelp commentedon Aug 29, 2024
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
ianlancetaylor commentedon Aug 29, 2024
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 commentedon Aug 29, 2024
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_QIeyrUFIt looks like
len(ch)works too.griesemer commentedon Aug 29, 2024
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 Torchan 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 commentedon Aug 29, 2024
Marking for 1.24 - not promising that this will be addressed, but so I keep an eye on it while investigating #63940.
griesemer commentedon Oct 23, 2024
Moving to 1.25.
gopherbot commentedon Sep 9, 2026
Change https://go.dev/cl/829606 mentions this issue:
cmd/compile, spec: infer E via interface{ <-chan E | chan<- E }