d.Name = p.name()
if p.tok == _Lbrack {
// array/slice or generic type
+ // name "[" ...
pos := p.pos()
p.next()
switch p.tok {
case _Rbrack:
+ // name "[" "]" ...
p.next()
d.Type = p.sliceType(pos)
case _Name:
// array or generic type
+ // name "[" name ...
p.xnest++
+ // TODO(gri) p.expr may consume an opening "[" when it shouldn't (issue #49175)
x := p.expr()
p.xnest--
if name0, ok := x.(*Name); p.allowGenerics() && ok && p.tok != _Rbrack {
// generic type
+ // name "[" name ...
d.TParamList = p.paramList(name0, _Rbrack, true)
pos := p.pos()
if p.gotAssign() {
d.Type = p.typeOrNil()
} else {
// x is the array length expression
+ // name "[" x ...
if debug && x == nil {
panic("length expression is nil")
}
d.Type = p.arrayType(pos, x)
}
default:
+ // name "[" ...
d.Type = p.arrayType(pos, nil)
}
} else {
// ParameterDecl = [ IdentifierList ] [ "..." ] Type .
func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
if trace {
- defer p.trace("paramDecl")()
+ defer p.trace("paramDeclOrNil")()
}
// type set notation is ok in type parameter lists
// name "[" n "]" E
f.Name = name
}
+ if typeSetsOk && p.tok == _Operator && p.op == Or {
+ // name "[" ... "]" "|" ...
+ // name "[" n "]" E "|" ...
+ f = p.embeddedElem(f)
+ }
return f
}
// license that can be found in the LICENSE file.
// This file contains test cases for typeset-only constraint elements.
-// TODO(gri) gofmt once/if gofmt supports this notation.
package p
_[_ ~t|struct{}] t
_[_ t|~struct{}] t
_[_ ~t|~struct{}] t
+
+ // TODO(gri) fix this (issue #49175)
+ // _[_ []t]t
+ _[_ ~[]t]t
)
+// test cases for issue #49174
+func _[_ t]() {}
+func _[_ []t]() {}
+func _[_ []t | t]() {}
+func _[_ t | []t]() {}
+func _[_ []t | []t]() {}
+func _[_ t[t] | t[t]]() {}
+
// Single-expression type parameter lists and those that don't start
// with a (type parameter) name are considered array sizes.
// The term must be a valid expression (it could be a type - and then