From 011b7ce8d12c14e9bd9b95a2519a6513a407bfc9 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 19 Mar 2025 09:38:51 -0700 Subject: [PATCH] go/types, types2: fix silly logic error in commonUnder Fixes #72936. Change-Id: I79ed8d559c8565fa960b974f8c1207ee442f4c26 Reviewed-on: https://go-review.googlesource.com/c/go/+/659256 LUCI-TryBot-Result: Go LUCI Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer Reviewed-by: Robert Findley --- src/cmd/compile/internal/types2/under.go | 10 ++++---- src/go/types/under.go | 10 ++++---- .../types/testdata/fixedbugs/issue72936.go | 23 +++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 src/internal/types/testdata/fixedbugs/issue72936.go diff --git a/src/cmd/compile/internal/types2/under.go b/src/cmd/compile/internal/types2/under.go index 846788a210..9e5334b724 100644 --- a/src/cmd/compile/internal/types2/under.go +++ b/src/cmd/compile/internal/types2/under.go @@ -112,11 +112,13 @@ func commonUnder(t Type, cond func(t, u Type) *typeError) (Type, *typeError) { } // If we have different channel directions, keep the restricted one // and complain if they conflict. - if chu.dir == SendRecv { - ct, cu = t, u // switch to current, possibly restricted channel - } else if chu.dir != ch.dir { + switch { + case chu.dir == ch.dir: + // nothing to do + case chu.dir == SendRecv: + ct, cu = t, u // switch to restricted channel + case ch.dir != SendRecv: return bad("channels %s and %s have conflicting directions", ct, t) - } return true } diff --git a/src/go/types/under.go b/src/go/types/under.go index 8d87e24237..2c09c49134 100644 --- a/src/go/types/under.go +++ b/src/go/types/under.go @@ -115,11 +115,13 @@ func commonUnder(t Type, cond func(t, u Type) *typeError) (Type, *typeError) { } // If we have different channel directions, keep the restricted one // and complain if they conflict. - if chu.dir == SendRecv { - ct, cu = t, u // switch to current, possibly restricted channel - } else if chu.dir != ch.dir { + switch { + case chu.dir == ch.dir: + // nothing to do + case chu.dir == SendRecv: + ct, cu = t, u // switch to restricted channel + case ch.dir != SendRecv: return bad("channels %s and %s have conflicting directions", ct, t) - } return true } diff --git a/src/internal/types/testdata/fixedbugs/issue72936.go b/src/internal/types/testdata/fixedbugs/issue72936.go new file mode 100644 index 0000000000..eb4942c0d9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue72936.go @@ -0,0 +1,23 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func _[C chan<- int | chan int](c C) { c <- 0 } +func _[C chan int | chan<- int](c C) { c <- 0 } +func _[C <-chan int | chan<- int](c C) { c <- /* ERROR "receive-only channel <-chan int" */ 0 } + +func _[C <-chan int | chan int](c C) { <-c } +func _[C chan int | <-chan int](c C) { <-c } +func _[C chan<- int | <-chan int](c C) { <-c /* ERROR "send-only channel chan<- int" */ } + +// from issue report + +func send[C interface{ ~chan<- V | ~chan V }, V any](c C, v V) { + c <- v +} + +func receive[C interface{ ~<-chan V | ~chan V }, V any](c C) V { + return <-c +} -- 2.51.0