mirror of https://github.com/golang/go.git
go/parser: accept pointer designation for type parameters in contracts
Change-Id: Ib119b7cd22de7117db82b987a3cd4573cbb6f6c8
This commit is contained in:
parent
29365a1738
commit
49c8636998
|
|
@ -921,12 +921,16 @@ type (
|
|||
type Constraint struct {
|
||||
// Invariant: Param == nil || len(MNames) == len(Types)
|
||||
// MNames entries will be nil if we have a list of types
|
||||
Param *Ident // constrained type parameter; or nil (for embedded contracts)
|
||||
MNames []*Ident // list of method names; or nil (for embedded contracts or type constraints)
|
||||
Types []Expr // embedded contract (single *CallExpr), list of types, or list of method signatures (*FuncType)
|
||||
Star token.Pos // position of "*"; or token.NoPos if not present
|
||||
Param *Ident // constrained type parameter; or nil (for embedded contracts)
|
||||
MNames []*Ident // list of method names; or nil (for embedded contracts or type constraints)
|
||||
Types []Expr // embedded contract (single *CallExpr), list of types, or list of method signatures (*FuncType)
|
||||
}
|
||||
|
||||
func (c *Constraint) Pos() token.Pos {
|
||||
if c.Star.IsValid() {
|
||||
return c.Star
|
||||
}
|
||||
if c.Param != nil {
|
||||
return c.Param.Pos()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2582,7 +2582,7 @@ func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token
|
|||
return spec
|
||||
}
|
||||
|
||||
// Constraint = TypeParam TypeOrMethod { "," TypeOrMethod } | ContractName "(" [ TypeList [ "," ] ] ")" .
|
||||
// Constraint = [ "*" ] TypeParam TypeOrMethod { "," TypeOrMethod } | ContractName "(" [ TypeList [ "," ] ] ")" .
|
||||
// TypeParam = Ident .
|
||||
// TypeOrMethod = Type | MethodName Signature .
|
||||
// ContractName = TypeName.
|
||||
|
|
@ -2598,9 +2598,18 @@ func (p *parser) parseConstraint() *ast.Constraint {
|
|||
return &ast.Constraint{Types: []ast.Expr{p.parseType(true)}}
|
||||
}
|
||||
|
||||
var star token.Pos
|
||||
if p.tok == token.MUL {
|
||||
star = p.pos
|
||||
p.next()
|
||||
}
|
||||
|
||||
tname := p.parseTypeName(nil)
|
||||
if p.tok == token.LPAREN {
|
||||
// ContractName "(" [ TypeList [ "," ] ] ")"
|
||||
if star.IsValid() {
|
||||
p.error(star, "pointer type requires a method")
|
||||
}
|
||||
return &ast.Constraint{Types: []ast.Expr{p.parseTypeInstance(tname)}}
|
||||
}
|
||||
|
||||
|
|
@ -2627,6 +2636,10 @@ func (p *parser) parseConstraint() *ast.Constraint {
|
|||
tparams, params := p.parseParameters(scope, methodTypeParamsOk|variadicOk, "method")
|
||||
results := p.parseResult(scope, true)
|
||||
typ = &ast.FuncType{Func: token.NoPos, TParams: tparams, Params: params, Results: results}
|
||||
} else if star.IsValid() {
|
||||
// type with (invalid) starred type parameter
|
||||
p.error(star, "pointer type requires a method")
|
||||
star = token.NoPos // suppress further errors
|
||||
}
|
||||
mnames = append(mnames, mname)
|
||||
types = append(types, typ)
|
||||
|
|
@ -2638,7 +2651,7 @@ func (p *parser) parseConstraint() *ast.Constraint {
|
|||
}
|
||||
|
||||
// param != nil
|
||||
return &ast.Constraint{Param: param, MNames: mnames, Types: types}
|
||||
return &ast.Constraint{Star: star, Param: param, MNames: mnames, Types: types}
|
||||
}
|
||||
|
||||
// ContractSpec = ident "(" [ IdentList [ "," ] ] ")" "{" { Constraint ";" } "}" .
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ var valids = []string{
|
|||
`package p; contract C(T){ T int; T imported.T; T chan<-int; T m(x int) float64; C0(); imported.C1(int, T,) }`,
|
||||
`package p; contract C(T){ T int, imported.T, chan<-int; T m(x int) float64; C0(); imported.C1(int, T,) }`,
|
||||
`package p; contract C(T){ (C(T)); (((imported.T))) }`,
|
||||
`package p; contract C(T){ *T m() }`,
|
||||
`package p; func _(type T1, T2 interface{})(x T1) T2`,
|
||||
`package p; func _(type T1 interface{ m() }, T2, T3 interface{})(x T1, y T3) T2`,
|
||||
|
||||
|
|
@ -179,6 +180,8 @@ var invalids = []string{
|
|||
// contracts
|
||||
`package p; contract C(T, T /* ERROR "T redeclared" */ ) {}`,
|
||||
`package p; contract C(T) { imported /* ERROR "expected type parameter name" */ .T int }`,
|
||||
`package p; contract C(T) { * /* ERROR "requires a method" */ C(T) }`,
|
||||
`package p; contract C(T) { * /* ERROR "requires a method" */ T int }`,
|
||||
`package p; func _() { contract /* ERROR "cannot be inside function" */ C(T) { T m(); type int, float32 } }`,
|
||||
|
||||
// issue 8656
|
||||
|
|
|
|||
Loading…
Reference in New Issue