t.Errorf("comparable not assignable to any")
}
}
+
+func TestIssue55030(t *testing.T) {
+ // makeSig makes the signature func(typ...)
+ makeSig := func(typ Type) {
+ par := NewVar(nopos, nil, "", typ)
+ params := NewTuple(par)
+ NewSignatureType(nil, nil, nil, params, nil, true)
+ }
+
+ // makeSig must not panic for the following (example) types:
+ // []int
+ makeSig(NewSlice(Typ[Int]))
+
+ // string
+ makeSig(Typ[String])
+
+ // P where P's core type is string
+ {
+ P := NewTypeName(nopos, nil, "P", nil) // [P string]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
+ }
+
+ // P where P's core type is an (unnamed) slice
+ {
+ P := NewTypeName(nopos, nil, "P", nil) // [P []int]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
+ }
+
+ // P where P's core type is bytestring (i.e., string or []byte)
+ {
+ t1 := NewTerm(true, Typ[String]) // ~string
+ t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
+ u := NewUnion([]*Term{t1, t2}) // ~string | []byte
+ P := NewTypeName(nopos, nil, "P", nil) // [P ~string | []byte]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
+ }
+}
package types2
-import "cmd/compile/internal/syntax"
+import (
+ "cmd/compile/internal/syntax"
+ "fmt"
+)
// ----------------------------------------------------------------------------
// API
// NewSignatureType creates a new function type for the given receiver,
// receiver type parameters, type parameters, parameters, and results. If
// variadic is set, params must hold at least one parameter and the last
-// parameter must be of unnamed slice type. If recv is non-nil, typeParams must
-// be empty. If recvTypeParams is non-empty, recv must be non-nil.
+// parameter's core type must be of unnamed slice or bytestring type.
+// If recv is non-nil, typeParams must be empty. If recvTypeParams is
+// non-empty, recv must be non-nil.
func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
if variadic {
n := params.Len()
if n == 0 {
panic("variadic function must have at least one parameter")
}
- if _, ok := params.At(n - 1).typ.(*Slice); !ok {
- panic("variadic parameter must be of unnamed slice type")
+ core := coreString(params.At(n - 1).typ)
+ if _, ok := core.(*Slice); !ok && !isString(core) {
+ panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
}
}
sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
t.Errorf("comparable not assignable to any")
}
}
+
+func TestIssue55030(t *testing.T) {
+ // makeSig makes the signature func(typ...)
+ makeSig := func(typ Type) {
+ par := NewVar(token.NoPos, nil, "", typ)
+ params := NewTuple(par)
+ NewSignatureType(nil, nil, nil, params, nil, true)
+ }
+
+ // makeSig must not panic for the following (example) types:
+ // []int
+ makeSig(NewSlice(Typ[Int]))
+
+ // string
+ makeSig(Typ[String])
+
+ // P where P's core type is string
+ {
+ P := NewTypeName(token.NoPos, nil, "P", nil) // [P string]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
+ }
+
+ // P where P's core type is an (unnamed) slice
+ {
+ P := NewTypeName(token.NoPos, nil, "P", nil) // [P []int]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
+ }
+
+ // P where P's core type is bytestring (i.e., string or []byte)
+ {
+ t1 := NewTerm(true, Typ[String]) // ~string
+ t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
+ u := NewUnion([]*Term{t1, t2}) // ~string | []byte
+ P := NewTypeName(token.NoPos, nil, "P", nil) // [P ~string | []byte]
+ makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
+ }
+}
package types
import (
+ "fmt"
"go/ast"
"go/token"
)
// NewSignatureType creates a new function type for the given receiver,
// receiver type parameters, type parameters, parameters, and results. If
// variadic is set, params must hold at least one parameter and the last
-// parameter must be of unnamed slice type. If recv is non-nil, typeParams must
-// be empty. If recvTypeParams is non-empty, recv must be non-nil.
+// parameter's core type must be of unnamed slice or bytestring type.
+// If recv is non-nil, typeParams must be empty. If recvTypeParams is
+// non-empty, recv must be non-nil.
func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
if variadic {
n := params.Len()
if n == 0 {
panic("variadic function must have at least one parameter")
}
- if _, ok := params.At(n - 1).typ.(*Slice); !ok {
- panic("variadic parameter must be of unnamed slice type")
+ core := coreString(params.At(n - 1).typ)
+ if _, ok := core.(*Slice); !ok && !isString(core) {
+ panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
}
}
sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}