Skip to content

go/types, cmd/compile/internal/types2: type inference limitation leads to incorrect result for directed channel type constraint #65202

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

Open
leaxoy opened this issue Jan 22, 2024 · 3 comments
Assignees
Labels
generics Issue is related to generics NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. TypeInference Issue is related to generic type inference
Milestone

Comments

@leaxoy
Copy link

leaxoy commented Jan 22, 2024

Proposal Details

Think such code:
can be found here: https://go.dev/play/p/qNBK9KjxqrW

func Chan[E any, C ~<-chan E](c C) {}

func x() {
    c := make(chan int)
    Chan(c)
}

then Chan(c) produce chan int does not satisfy ~<-chan int (chan int missing in ~<-chan int)

In my opinion, this is a flaw in generic design that should be supported

@gopherbot gopherbot added this to the Proposal milestone Jan 22, 2024
@bcmills bcmills added the generics Issue is related to generics label Jan 22, 2024
@seankhliao
Copy link
Member

I think this is just a type inference issue https://go.dev/play/p/YASG8TZx0Lc

cc @griesemer

@seankhliao seankhliao added the TypeInference Issue is related to generic type inference label Jan 22, 2024
@seankhliao seankhliao changed the title proposal: generics: chan int does not satisfy ~<-chan int (chan int missing in ~<-chan int) go/types, types2: inference fails for read only channels and underlying types Jan 22, 2024
@griesemer griesemer self-assigned this Jan 22, 2024
@griesemer griesemer added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. and removed Proposal labels Jan 22, 2024
@griesemer griesemer modified the milestones: Proposal, Go1.23 Jan 22, 2024
@findleyr
Copy link
Member

Indeed, I think we should be able to infer <-chan int for C when unifying ~<-chan E with chan int. As we've seen many times, encoding these types of assignability rules in the unification algorithm is tricky. But on first glance this may not be too bad.

@griesemer
Copy link
Contributor

Let's consider the simpler example (no ~) with the same issue:

func f[C <-chan E, E any](C) {}

func _() {
    var c chan int
    f(c)
}

Per (internal) discussion: @findleyr points out that the code gives rise to three type equations:

  1. C ≡A chan int (i.e., C and chan int match per assignability rules)
  2. C ≡C <-chan E (C must satisfy constraint <-chan E)
  3. E ≡C any

and that there is exactly one solution: C ➞ <-chan int and E ➞ int. With this solution, the code will work.

The implementation solves these equations using unification. When solving equation 1, unification infers C ➞ chan int. When solving equation 2, (inexact) unification infers E ➞ int. (For equation 3 there's nothing left to do.)
Because the implementation unifies one equation at a time and always infers (at most) one type (so chan int for C) rather than a set of possible types (like {chan int, <-chan int, chan<- int} for C) inference produces the wrong result after which instantiation fails, leading to the reported error.

Thus, this is an implementation limitation at the moment. It's unlikely that we'll be able to address this in the near future, as this is notoriously difficult and this is not a high-priority issue.

In this case it may be possible to just use the following work-around and write the code as follows:

func f[E any](<-chan E) {}

func _() {
    var c chan int
    f(c)
}

Leaving issue open for future reference/consideration.

@griesemer griesemer modified the milestones: Go1.23, Backlog Jan 22, 2024
@griesemer griesemer changed the title go/types, types2: inference fails for read only channels and underlying types go/types, types2: type inference limitation leads to incorrect result for directed channel type constraint Jan 22, 2024
@dmitshur dmitshur changed the title go/types, types2: type inference limitation leads to incorrect result for directed channel type constraint go/types, cmd/compile/internal/types2: type inference limitation leads to incorrect result for directed channel type constraint May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generics Issue is related to generics NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. TypeInference Issue is related to generic type inference
Projects
None yet
Development

No branches or pull requests

6 participants