mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	[dev.typeparams] cmd/compile/internal/types2: implement close(ch) where ch is of type parameter type
Change-Id: I45189468553e83390fd2640b5708c60a7852fbb5 Reviewed-on: https://go-review.googlesource.com/c/go/+/333713 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
		
							parent
							
								
									6511922a14
								
							
						
					
					
						commit
						5f0ea40c67
					
				
					 5 changed files with 62 additions and 26 deletions
				
			
		|  | @ -212,19 +212,23 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( | ||||||
| 
 | 
 | ||||||
| 	case _Close: | 	case _Close: | ||||||
| 		// close(c) | 		// close(c) | ||||||
| 		c := asChan(x.typ) | 		if !underIs(x.typ, func(u Type) bool { | ||||||
| 		if c == nil { | 			uch, _ := u.(*Chan) | ||||||
| 			check.errorf(x, invalidArg+"%s is not a channel", x) | 			if uch == nil { | ||||||
|  | 				check.errorf(x, invalidOp+"cannot close non-channel %s", x) | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 			if uch.dir == RecvOnly { | ||||||
|  | 				check.errorf(x, invalidOp+"cannot close receive-only channel %s", x) | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 			return true | ||||||
|  | 		}) { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if c.dir == RecvOnly { |  | ||||||
| 			check.errorf(x, invalidArg+"%s must not be a receive-only channel", x) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		x.mode = novalue | 		x.mode = novalue | ||||||
| 		if check.Types != nil { | 		if check.Types != nil { | ||||||
| 			check.recordBuiltinType(call.Fun, makeSig(nil, c)) | 			check.recordBuiltinType(call.Fun, makeSig(nil, x.typ)) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case _Complex: | 	case _Complex: | ||||||
|  |  | ||||||
|  | @ -6,6 +6,45 @@ | ||||||
| 
 | 
 | ||||||
| package builtins | package builtins | ||||||
| 
 | 
 | ||||||
|  | // close | ||||||
|  | 
 | ||||||
|  | type C0 interface{ int } | ||||||
|  | type C1 interface{ chan int } | ||||||
|  | type C2 interface{ chan int | <-chan int } | ||||||
|  | type C3 interface{ chan int | chan float32 } | ||||||
|  | type C4 interface{ chan int | chan<- int } | ||||||
|  | type C5[T any] interface{ ~chan T | chan<- T } | ||||||
|  | 
 | ||||||
|  | func _[T any](ch T) { | ||||||
|  | 	close(ch /* ERROR cannot close non-channel */) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C0](ch T) { | ||||||
|  | 	close(ch /* ERROR cannot close non-channel */) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C1](ch T) { | ||||||
|  | 	close(ch) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C2](ch T) { | ||||||
|  | 	close(ch /* ERROR cannot close receive-only channel */) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C3](ch T) { | ||||||
|  | 	close(ch) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C4](ch T) { | ||||||
|  | 	close(ch) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func _[T C5[X], X any](ch T) { | ||||||
|  | 	close(ch) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // make | ||||||
|  | 
 | ||||||
| type Bmc interface { | type Bmc interface { | ||||||
| 	~map[rune]string | ~chan int | 	~map[rune]string | ~chan int | ||||||
| } | } | ||||||
|  | @ -22,31 +61,31 @@ type Bss interface { | ||||||
| 	~[]int | ~[]string | 	~[]int | ~[]string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func _[T any] () { | func _[T any]() { | ||||||
| 	_ = make(T /* ERROR invalid argument */ ) | 	_ = make(T /* ERROR invalid argument */) | ||||||
| 	_ = make(T /* ERROR invalid argument */ , 10) | 	_ = make(T /* ERROR invalid argument */, 10) | ||||||
| 	_ = make(T /* ERROR invalid argument */ , 10, 20) | 	_ = make(T /* ERROR invalid argument */, 10, 20) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func _[T Bmc] () { | func _[T Bmc]() { | ||||||
| 	_ = make(T) | 	_ = make(T) | ||||||
| 	_ = make(T, 10) | 	_ = make(T, 10) | ||||||
| 	_ = make /* ERROR expects 1 or 2 arguments */ (T, 10, 20) | 	_ = make /* ERROR expects 1 or 2 arguments */ (T, 10, 20) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func _[T Bms] () { | func _[T Bms]() { | ||||||
| 	_ = make /* ERROR expects 2 arguments */ (T) | 	_ = make /* ERROR expects 2 arguments */ (T) | ||||||
| 	_ = make(T, 10) | 	_ = make(T, 10) | ||||||
| 	_ = make /* ERROR expects 2 arguments */ (T, 10, 20) | 	_ = make /* ERROR expects 2 arguments */ (T, 10, 20) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func _[T Bcs] () { | func _[T Bcs]() { | ||||||
| 	_ = make /* ERROR expects 2 arguments */ (T) | 	_ = make /* ERROR expects 2 arguments */ (T) | ||||||
| 	_ = make(T, 10) | 	_ = make(T, 10) | ||||||
| 	_ = make /* ERROR expects 2 arguments */ (T, 10, 20) | 	_ = make /* ERROR expects 2 arguments */ (T, 10, 20) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func _[T Bss] () { | func _[T Bss]() { | ||||||
| 	_ = make /* ERROR expects 2 or 3 arguments */ (T) | 	_ = make /* ERROR expects 2 or 3 arguments */ (T) | ||||||
| 	_ = make(T, 10) | 	_ = make(T, 10) | ||||||
| 	_ = make(T, 10, 20) | 	_ = make(T, 10, 20) | ||||||
|  |  | ||||||
|  | @ -144,7 +144,7 @@ func close1() { | ||||||
| 	var r <-chan int | 	var r <-chan int | ||||||
| 	close() // ERROR not enough arguments | 	close() // ERROR not enough arguments | ||||||
| 	close(1, 2) // ERROR too many arguments | 	close(1, 2) // ERROR too many arguments | ||||||
| 	close(42 /* ERROR not a channel */) | 	close(42 /* ERROR cannot close non-channel */) | ||||||
| 	close(r /* ERROR receive-only channel */) | 	close(r /* ERROR receive-only channel */) | ||||||
| 	close(c) | 	close(c) | ||||||
| 	_ = close /* ERROR used as value */ (c) | 	_ = close /* ERROR used as value */ (c) | ||||||
|  |  | ||||||
|  | @ -105,8 +105,6 @@ func asPointer(t Type) *Pointer { | ||||||
| 	return op | 	return op | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // asTuple is not needed - not provided |  | ||||||
| 
 |  | ||||||
| func asSignature(t Type) *Signature { | func asSignature(t Type) *Signature { | ||||||
| 	op, _ := optype(t).(*Signature) | 	op, _ := optype(t).(*Signature) | ||||||
| 	return op | 	return op | ||||||
|  | @ -117,11 +115,6 @@ func asMap(t Type) *Map { | ||||||
| 	return op | 	return op | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func asChan(t Type) *Chan { |  | ||||||
| 	op, _ := optype(t).(*Chan) |  | ||||||
| 	return op |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // If the argument to asInterface, asNamed, or asTypeParam is of the respective type | // If the argument to asInterface, asNamed, or asTypeParam is of the respective type | ||||||
| // (possibly after expanding an instance type), these methods return that type. | // (possibly after expanding an instance type), these methods return that type. | ||||||
| // Otherwise the result is nil. | // Otherwise the result is nil. | ||||||
|  |  | ||||||
|  | @ -66,5 +66,5 @@ func main() { | ||||||
| 	close(c) | 	close(c) | ||||||
| 	close(cs) | 	close(cs) | ||||||
| 	close(cr) // ERROR "receive" | 	close(cr) // ERROR "receive" | ||||||
| 	close(n)  // ERROR "invalid operation.*non-chan type|must be channel|not a channel" | 	close(n)  // ERROR "invalid operation.*non-chan type|must be channel|non-channel" | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robert Griesemer
						Robert Griesemer