mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
go/internal/typeparams: remove typeparams.{Get,Set} (cleanup)
These helper functions are no longer necessary, now that type parameters are enabled; we can access type parameters directly. When considering the existence or non-existence of type parameters, we can either check whether node.TParams != nil, or whether node.TParams.NumFields() > 0. The heuristic I'm using for deciding between these checks is as follows: - For data access, just check node.TParams != nil. - For producing errors if type parameters exist, check NumFields() > 0. Change-Id: I6597536898e975564e9e8bf6a3a91bc798e0f110 Reviewed-on: https://go-review.googlesource.com/c/go/+/346549 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
78d0f8c870
commit
7637345b6e
7 changed files with 24 additions and 50 deletions
|
|
@ -5,7 +5,6 @@
|
||||||
package typeparams
|
package typeparams
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
)
|
)
|
||||||
|
|
@ -54,25 +53,3 @@ func UnpackIndexExpr(n ast.Node) *IndexExpr {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(n ast.Node) *ast.FieldList {
|
|
||||||
switch n := n.(type) {
|
|
||||||
case *ast.TypeSpec:
|
|
||||||
return n.TParams
|
|
||||||
case *ast.FuncType:
|
|
||||||
return n.TParams
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("node type %T has no type parameters", n))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Set(n ast.Node, params *ast.FieldList) {
|
|
||||||
switch n := n.(type) {
|
|
||||||
case *ast.TypeSpec:
|
|
||||||
n.TParams = params
|
|
||||||
case *ast.FuncType:
|
|
||||||
n.TParams = params
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("node type %T has no type parameters", n))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -972,8 +972,12 @@ func (p *parser) parseMethodSpec() *ast.Field {
|
||||||
_, params := p.parseParameters(false)
|
_, params := p.parseParameters(false)
|
||||||
results := p.parseResult()
|
results := p.parseResult()
|
||||||
idents = []*ast.Ident{ident}
|
idents = []*ast.Ident{ident}
|
||||||
typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
|
typ = &ast.FuncType{
|
||||||
typeparams.Set(typ, tparams)
|
Func: token.NoPos,
|
||||||
|
TParams: tparams,
|
||||||
|
Params: params,
|
||||||
|
Results: results,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// embedded instantiated type
|
// embedded instantiated type
|
||||||
// TODO(rfindley) should resolve all identifiers in x.
|
// TODO(rfindley) should resolve all identifiers in x.
|
||||||
|
|
@ -2505,7 +2509,7 @@ func (p *parser) parseValueSpec(doc *ast.CommentGroup, _ token.Pos, keyword toke
|
||||||
func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, closeTok token.Token) {
|
func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, closeTok token.Token) {
|
||||||
list := p.parseParameterList(name0, closeTok, p.parseParamDecl, true)
|
list := p.parseParameterList(name0, closeTok, p.parseParamDecl, true)
|
||||||
closePos := p.expect(closeTok)
|
closePos := p.expect(closeTok)
|
||||||
typeparams.Set(spec, &ast.FieldList{Opening: openPos, List: list, Closing: closePos})
|
spec.TParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
|
||||||
// Type alias cannot have type parameters. Accept them for robustness but complain.
|
// Type alias cannot have type parameters. Accept them for robustness but complain.
|
||||||
if p.tok == token.ASSIGN {
|
if p.tok == token.ASSIGN {
|
||||||
p.error(p.pos, "generic type cannot be alias")
|
p.error(p.pos, "generic type cannot be alias")
|
||||||
|
|
@ -2636,12 +2640,12 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
|
||||||
Name: ident,
|
Name: ident,
|
||||||
Type: &ast.FuncType{
|
Type: &ast.FuncType{
|
||||||
Func: pos,
|
Func: pos,
|
||||||
|
TParams: tparams,
|
||||||
Params: params,
|
Params: params,
|
||||||
Results: results,
|
Results: results,
|
||||||
},
|
},
|
||||||
Body: body,
|
Body: body,
|
||||||
}
|
}
|
||||||
typeparams.Set(decl.Type, tparams)
|
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ package parser
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/internal/typeparams"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -455,10 +454,10 @@ func (r *resolver) Visit(node ast.Node) ast.Visitor {
|
||||||
// at the identifier in the TypeSpec and ends at the end of the innermost
|
// at the identifier in the TypeSpec and ends at the end of the innermost
|
||||||
// containing block.
|
// containing block.
|
||||||
r.declare(spec, nil, r.topScope, ast.Typ, spec.Name)
|
r.declare(spec, nil, r.topScope, ast.Typ, spec.Name)
|
||||||
if tparams := typeparams.Get(spec); tparams != nil {
|
if spec.TParams != nil {
|
||||||
r.openScope(spec.Pos())
|
r.openScope(spec.Pos())
|
||||||
defer r.closeScope()
|
defer r.closeScope()
|
||||||
r.walkTParams(tparams)
|
r.walkTParams(spec.TParams)
|
||||||
}
|
}
|
||||||
ast.Walk(r, spec.Type)
|
ast.Walk(r, spec.Type)
|
||||||
}
|
}
|
||||||
|
|
@ -474,8 +473,8 @@ func (r *resolver) Visit(node ast.Node) ast.Visitor {
|
||||||
|
|
||||||
// Type parameters are walked normally: they can reference each other, and
|
// Type parameters are walked normally: they can reference each other, and
|
||||||
// can be referenced by normal parameters.
|
// can be referenced by normal parameters.
|
||||||
if tparams := typeparams.Get(n.Type); tparams != nil {
|
if n.Type.TParams != nil {
|
||||||
r.walkTParams(tparams)
|
r.walkTParams(n.Type.TParams)
|
||||||
// TODO(rFindley): need to address receiver type parameters.
|
// TODO(rFindley): need to address receiver type parameters.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -539,9 +538,6 @@ func (r *resolver) walkFieldList(list *ast.FieldList, kind ast.ObjKind) {
|
||||||
// that they may be resolved in the constraint expressions held in the field
|
// that they may be resolved in the constraint expressions held in the field
|
||||||
// Type.
|
// Type.
|
||||||
func (r *resolver) walkTParams(list *ast.FieldList) {
|
func (r *resolver) walkTParams(list *ast.FieldList) {
|
||||||
if list == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r.declareList(list, ast.Typ)
|
r.declareList(list, ast.Typ)
|
||||||
r.resolveList(list)
|
r.resolveList(list)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ package printer
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/internal/typeparams"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -383,8 +382,8 @@ func (p *printer) parameters(fields *ast.FieldList, isTypeParam bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *printer) signature(sig *ast.FuncType) {
|
func (p *printer) signature(sig *ast.FuncType) {
|
||||||
if tparams := typeparams.Get(sig); tparams != nil {
|
if sig.TParams != nil {
|
||||||
p.parameters(tparams, true)
|
p.parameters(sig.TParams, true)
|
||||||
}
|
}
|
||||||
if sig.Params != nil {
|
if sig.Params != nil {
|
||||||
p.parameters(sig.Params, false)
|
p.parameters(sig.Params, false)
|
||||||
|
|
@ -1633,8 +1632,8 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
|
||||||
case *ast.TypeSpec:
|
case *ast.TypeSpec:
|
||||||
p.setComment(s.Doc)
|
p.setComment(s.Doc)
|
||||||
p.expr(s.Name)
|
p.expr(s.Name)
|
||||||
if tparams := typeparams.Get(s); tparams != nil {
|
if s.TParams != nil {
|
||||||
p.parameters(tparams, true)
|
p.parameters(s.TParams, true)
|
||||||
}
|
}
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
p.print(blank)
|
p.print(blank)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
"go/internal/typeparams"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -590,7 +589,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
|
||||||
})
|
})
|
||||||
|
|
||||||
alias := tdecl.Assign.IsValid()
|
alias := tdecl.Assign.IsValid()
|
||||||
if alias && typeparams.Get(tdecl) != nil {
|
if alias && tdecl.TParams.NumFields() != 0 {
|
||||||
// The parser will ensure this but we may still get an invalid AST.
|
// The parser will ensure this but we may still get an invalid AST.
|
||||||
// Complain and continue as regular type definition.
|
// Complain and continue as regular type definition.
|
||||||
check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
|
check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
|
||||||
|
|
@ -613,10 +612,10 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
|
||||||
named := check.newNamed(obj, nil, nil, nil, nil)
|
named := check.newNamed(obj, nil, nil, nil, nil)
|
||||||
def.setUnderlying(named)
|
def.setUnderlying(named)
|
||||||
|
|
||||||
if tparams := typeparams.Get(tdecl); tparams != nil {
|
if tdecl.TParams != nil {
|
||||||
check.openScope(tdecl, "type parameters")
|
check.openScope(tdecl, "type parameters")
|
||||||
defer check.closeScope()
|
defer check.closeScope()
|
||||||
named.tparams = check.collectTypeParams(tparams)
|
named.tparams = check.collectTypeParams(tdecl.TParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine underlying type of named
|
// determine underlying type of named
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/internal/typeparams"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -195,8 +194,8 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
|
||||||
// a receiver specification.)
|
// a receiver specification.)
|
||||||
if sig.tparams != nil {
|
if sig.tparams != nil {
|
||||||
var at positioner = f.Type
|
var at positioner = f.Type
|
||||||
if tparams := typeparams.Get(f.Type); tparams != nil {
|
if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TParams != nil {
|
||||||
at = tparams
|
at = ftyp.TParams
|
||||||
}
|
}
|
||||||
check.errorf(at, _Todo, "methods cannot have type parameters")
|
check.errorf(at, _Todo, "methods cannot have type parameters")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,13 +156,13 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tparams := typeparams.Get(ftyp); tparams != nil {
|
if ftyp.TParams != nil {
|
||||||
sig.tparams = check.collectTypeParams(tparams)
|
sig.tparams = check.collectTypeParams(ftyp.TParams)
|
||||||
// Always type-check method type parameters but complain that they are not allowed.
|
// Always type-check method type parameters but complain that they are not allowed.
|
||||||
// (A separate check is needed when type-checking interface method signatures because
|
// (A separate check is needed when type-checking interface method signatures because
|
||||||
// they don't have a receiver specification.)
|
// they don't have a receiver specification.)
|
||||||
if recvPar != nil {
|
if recvPar != nil {
|
||||||
check.errorf(tparams, _Todo, "methods cannot have type parameters")
|
check.errorf(ftyp.TParams, _Todo, "methods cannot have type parameters")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue