mirror of
https://github.com/golang/go
synced 2024-11-18 04:24:47 -07:00
cmd/compile/internal/syntax: fix constraint literal parsing for generic functions
Fixes #49174. Change-Id: I943c370f7abd5f50a541e682f130b3526c3b5bdb Reviewed-on: https://go-review.googlesource.com/c/go/+/359014 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
c0ac39c70e
commit
bb49eb3e6a
@ -588,19 +588,24 @@ func (p *parser) typeDecl(group *Group) Decl {
|
|||||||
d.Name = p.name()
|
d.Name = p.name()
|
||||||
if p.tok == _Lbrack {
|
if p.tok == _Lbrack {
|
||||||
// array/slice or generic type
|
// array/slice or generic type
|
||||||
|
// name "[" ...
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
p.next()
|
p.next()
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case _Rbrack:
|
case _Rbrack:
|
||||||
|
// name "[" "]" ...
|
||||||
p.next()
|
p.next()
|
||||||
d.Type = p.sliceType(pos)
|
d.Type = p.sliceType(pos)
|
||||||
case _Name:
|
case _Name:
|
||||||
// array or generic type
|
// array or generic type
|
||||||
|
// name "[" name ...
|
||||||
p.xnest++
|
p.xnest++
|
||||||
|
// TODO(gri) p.expr may consume an opening "[" when it shouldn't (issue #49175)
|
||||||
x := p.expr()
|
x := p.expr()
|
||||||
p.xnest--
|
p.xnest--
|
||||||
if name0, ok := x.(*Name); p.allowGenerics() && ok && p.tok != _Rbrack {
|
if name0, ok := x.(*Name); p.allowGenerics() && ok && p.tok != _Rbrack {
|
||||||
// generic type
|
// generic type
|
||||||
|
// name "[" name ...
|
||||||
d.TParamList = p.paramList(name0, _Rbrack, true)
|
d.TParamList = p.paramList(name0, _Rbrack, true)
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
if p.gotAssign() {
|
if p.gotAssign() {
|
||||||
@ -609,12 +614,14 @@ func (p *parser) typeDecl(group *Group) Decl {
|
|||||||
d.Type = p.typeOrNil()
|
d.Type = p.typeOrNil()
|
||||||
} else {
|
} else {
|
||||||
// x is the array length expression
|
// x is the array length expression
|
||||||
|
// name "[" x ...
|
||||||
if debug && x == nil {
|
if debug && x == nil {
|
||||||
panic("length expression is nil")
|
panic("length expression is nil")
|
||||||
}
|
}
|
||||||
d.Type = p.arrayType(pos, x)
|
d.Type = p.arrayType(pos, x)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
// name "[" ...
|
||||||
d.Type = p.arrayType(pos, nil)
|
d.Type = p.arrayType(pos, nil)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1816,7 +1823,7 @@ func (p *parser) embeddedTerm() Expr {
|
|||||||
// ParameterDecl = [ IdentifierList ] [ "..." ] Type .
|
// ParameterDecl = [ IdentifierList ] [ "..." ] Type .
|
||||||
func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
|
func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
|
||||||
if trace {
|
if trace {
|
||||||
defer p.trace("paramDecl")()
|
defer p.trace("paramDeclOrNil")()
|
||||||
}
|
}
|
||||||
|
|
||||||
// type set notation is ok in type parameter lists
|
// type set notation is ok in type parameter lists
|
||||||
@ -1849,6 +1856,11 @@ func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
|
|||||||
// name "[" n "]" E
|
// name "[" n "]" E
|
||||||
f.Name = name
|
f.Name = name
|
||||||
}
|
}
|
||||||
|
if typeSetsOk && p.tok == _Operator && p.op == Or {
|
||||||
|
// name "[" ... "]" "|" ...
|
||||||
|
// name "[" n "]" E "|" ...
|
||||||
|
f = p.embeddedElem(f)
|
||||||
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// This file contains test cases for typeset-only constraint elements.
|
// This file contains test cases for typeset-only constraint elements.
|
||||||
// TODO(gri) gofmt once/if gofmt supports this notation.
|
|
||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
@ -44,8 +43,20 @@ type (
|
|||||||
_[_ ~t|struct{}] t
|
_[_ ~t|struct{}] t
|
||||||
_[_ t|~struct{}] t
|
_[_ 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
|
// Single-expression type parameter lists and those that don't start
|
||||||
// with a (type parameter) name are considered array sizes.
|
// with a (type parameter) name are considered array sizes.
|
||||||
// The term must be a valid expression (it could be a type - and then
|
// The term must be a valid expression (it could be a type - and then
|
||||||
|
Loading…
Reference in New Issue
Block a user