]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: reduce differences between go/types and types2 builtins.go
authorRobert Griesemer <gri@golang.org>
Wed, 17 May 2023 03:05:13 +0000 (20:05 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 18 May 2023 18:39:34 +0000 (18:39 +0000)
Change-Id: I2946e061c70d31df3ba2aa3582700c3785b647e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/495615
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/builtins.go
src/go/types/api.go
src/go/types/builtins.go

index de74da0bac53c38000c491395038d9768baff8ea..1d2780966a4cb99ced5d102e1486c2dcca980b84 100644 (file)
@@ -18,12 +18,16 @@ import (
 // but x.expr is not set. If the call is invalid, the result is
 // false, and *x is undefined.
 func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (_ bool) {
+       argList := call.ArgList
+
        // append is the only built-in that permits the use of ... for the last argument
        bin := predeclaredFuncs[id]
        if call.HasDots && id != _Append {
                //check.errorf(call.Ellipsis, invalidOp + "invalid use of ... with built-in %s", bin.name)
-               check.errorf(call, InvalidDotDotDot, invalidOp+"invalid use of ... with built-in %s", bin.name)
-               check.use(call.ArgList...)
+               check.errorf(call,
+                       InvalidDotDotDot,
+                       invalidOp+"invalid use of ... with built-in %s", bin.name)
+               check.use(argList...)
                return
        }
 
@@ -47,7 +51,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        switch id {
        default:
                // check all arguments
-               args = check.exprList(call.ArgList)
+               args = check.exprList(argList)
                nargs = len(args)
                for _, a := range args {
                        if a.mode == invalid {
@@ -60,7 +64,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                }
        case _Make, _New, _Offsetof, _Trace:
                // arguments require special handling
-               nargs = len(call.ArgList)
+               nargs = len(argList)
        }
 
        // check argument count
@@ -486,7 +490,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                // make(T, n)
                // make(T, n, m)
                // (no argument evaluated yet)
-               arg0 := call.ArgList[0]
+               arg0 := argList[0]
                T := check.varType(arg0)
                if T == Typ[Invalid] {
                        return
@@ -512,7 +516,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
 
                types := []Type{T}
                var sizes []int64 // constant integer arguments, if any
-               for _, arg := range call.ArgList[1:] {
+               for _, arg := range argList[1:] {
                        typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
                        types = append(types, typ)
                        if size >= 0 {
@@ -520,7 +524,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        }
                }
                if len(sizes) == 2 && sizes[0] > sizes[1] {
-                       check.error(call.ArgList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
+                       check.error(argList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
                        // safe to continue
                }
                x.mode = value
@@ -532,7 +536,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        case _New:
                // new(T)
                // (no argument evaluated yet)
-               T := check.varType(call.ArgList[0])
+               T := check.varType(argList[0])
                if T == Typ[Invalid] {
                        return
                }
@@ -641,7 +645,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        case _Offsetof:
                // unsafe.Offsetof(x T) uintptr, where x must be a selector
                // (no argument evaluated yet)
-               arg0 := call.ArgList[0]
+               arg0 := argList[0]
                selx, _ := unparen(arg0).(*syntax.SelectorExpr)
                if selx == nil {
                        check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
@@ -842,7 +846,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                }
                var t operand
                x1 := x
-               for _, arg := range call.ArgList {
+               for _, arg := range argList {
                        check.rawExpr(nil, x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
                        check.dump("%v: %s", atPos(x1), x1)
                        x1 = &t // use incoming x only for first argument
@@ -921,8 +925,8 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
 
                // We can type-check this fine but we're introducing a synthetic
                // type parameter for the result. It's not clear what the API
-               // implications are here. Report an error for 1.18 but continue
-               // type-checking.
+               // implications are here. Report an error for 1.18 (see go.dev/issue/50912),
+               // but continue type-checking.
                var code Code
                switch id {
                case _Real:
index 14cd9cdcdb409bdbfe2ed14509d731acaa2b1602..3f83a8088ad9be362f9876dbdcdb4953e45c1a4b 100644 (file)
@@ -286,6 +286,10 @@ type Info struct {
        InitOrder []*Initializer
 }
 
+func (info *Info) recordTypes() bool {
+       return info.Types != nil
+}
+
 // TypeOf returns the type of expression e, or nil if not found.
 // Precondition: the Types, Uses and Defs maps are populated.
 func (info *Info) TypeOf(e ast.Expr) Type {
index 64d34e51cba542bc80cb949794979f09aca24ab6..9f22fcf166004f1474ec9b8b3aad606776c207c6 100644 (file)
@@ -18,13 +18,15 @@ import (
 // but x.expr is not set. If the call is invalid, the result is
 // false, and *x is undefined.
 func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
+       argList := call.Args
+
        // append is the only built-in that permits the use of ... for the last argument
        bin := predeclaredFuncs[id]
        if call.Ellipsis.IsValid() && id != _Append {
                check.errorf(atPos(call.Ellipsis),
                        InvalidDotDotDot,
                        invalidOp+"invalid use of ... with built-in %s", bin.name)
-               check.use(call.Args...)
+               check.use(argList...)
                return
        }
 
@@ -48,7 +50,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
        switch id {
        default:
                // check all arguments
-               args = check.exprList(call.Args)
+               args = check.exprList(argList)
                nargs = len(args)
                for _, a := range args {
                        if a.mode == invalid {
@@ -61,7 +63,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
        case _Make, _New, _Offsetof, _Trace:
                // arguments require special handling
-               nargs = len(call.Args)
+               nargs = len(argList)
        }
 
        // check argument count
@@ -115,7 +117,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
                                y := args[1]
                                if t := coreString(y.typ); t != nil && isString(t) {
-                                       if check.Types != nil {
+                                       if check.recordTypes() {
                                                sig := makeSig(S, S, y.typ)
                                                sig.variadic = true
                                                check.recordBuiltinType(call.Fun, sig)
@@ -135,7 +137,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = S
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, sig)
                }
 
@@ -214,7 +216,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                // record the signature before changing x.typ
-               if check.Types != nil && mode != constant_ {
+               if check.recordTypes() && mode != constant_ {
                        check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
                }
 
@@ -240,7 +242,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                x.mode = novalue
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
                }
 
@@ -261,7 +263,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        return
                }
                x.mode = novalue
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
                }
 
@@ -316,7 +318,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                // both argument types must be identical
                if !Identical(x.typ, y.typ) {
-                       check.errorf(x, InvalidComplex, invalidArg+"mismatched types %s and %s", x.typ, y.typ)
+                       check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
                        return
                }
 
@@ -349,7 +351,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        x.mode = value
                }
 
-               if check.Types != nil && x.mode != constant_ {
+               if check.recordTypes() && x.mode != constant_ {
                        check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
                }
 
@@ -372,11 +374,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                if !Identical(dst.elem, src.elem) {
-                       check.errorf(x, InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, y, dst.elem, src.elem)
+                       check.errorf(x, InvalidCopy, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, y, dst.elem, src.elem)
                        return
                }
 
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
                }
                x.mode = value
@@ -411,7 +413,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                x.mode = novalue
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
                }
 
@@ -477,7 +479,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        x.mode = value
                }
 
-               if check.Types != nil && x.mode != constant_ {
+               if check.recordTypes() && x.mode != constant_ {
                        check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
                }
 
@@ -487,7 +489,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                // make(T, n)
                // make(T, n, m)
                // (no argument evaluated yet)
-               arg0 := call.Args[0]
+               arg0 := argList[0]
                T := check.varType(arg0)
                if T == Typ[Invalid] {
                        return
@@ -500,7 +502,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                case *Map, *Chan:
                        min = 1
                case nil:
-                       check.errorf(arg0, InvalidMake, "cannot make %s: no core type", arg0)
+                       check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no core type", arg0)
                        return
                default:
                        check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
@@ -513,7 +515,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                types := []Type{T}
                var sizes []int64 // constant integer arguments, if any
-               for _, arg := range call.Args[1:] {
+               for _, arg := range argList[1:] {
                        typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
                        types = append(types, typ)
                        if size >= 0 {
@@ -521,26 +523,26 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        }
                }
                if len(sizes) == 2 && sizes[0] > sizes[1] {
-                       check.error(call.Args[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
+                       check.error(argList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
                        // safe to continue
                }
                x.mode = value
                x.typ = T
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
                }
 
        case _New:
                // new(T)
                // (no argument evaluated yet)
-               T := check.varType(call.Args[0])
+               T := check.varType(argList[0])
                if T == Typ[Invalid] {
                        return
                }
 
                x.mode = value
                x.typ = &Pointer{base: T}
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
                }
 
@@ -565,7 +567,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                x.mode = novalue
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
                }
 
@@ -586,7 +588,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
 
                x.mode = novalue
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(nil, params...))
                }
 
@@ -594,7 +596,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                // recover() interface{}
                x.mode = value
                x.typ = &emptyInterface
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ))
                }
 
@@ -616,7 +618,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = Typ[UnsafePointer]
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
                }
 
@@ -629,7 +631,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                if hasVarSize(x.typ, nil) {
                        x.mode = value
-                       if check.Types != nil {
+                       if check.recordTypes() {
                                check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
                        }
                } else {
@@ -642,7 +644,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
        case _Offsetof:
                // unsafe.Offsetof(x T) uintptr, where x must be a selector
                // (no argument evaluated yet)
-               arg0 := call.Args[0]
+               arg0 := argList[0]
                selx, _ := unparen(arg0).(*ast.SelectorExpr)
                if selx == nil {
                        check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
@@ -693,7 +695,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                // arranging struct fields if it wanted to.
                if hasVarSize(base, nil) {
                        x.mode = value
-                       if check.Types != nil {
+                       if check.recordTypes() {
                                check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
                        }
                } else {
@@ -717,7 +719,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                if hasVarSize(x.typ, nil) {
                        x.mode = value
-                       if check.Types != nil {
+                       if check.recordTypes() {
                                check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
                        }
                } else {
@@ -751,7 +753,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = NewSlice(ptr.base)
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
                }
 
@@ -769,7 +771,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = NewPointer(slice.elem)
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
                }
 
@@ -791,7 +793,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = Typ[String]
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
                }
 
@@ -808,7 +810,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
 
                x.mode = value
                x.typ = NewPointer(universeByte)
-               if check.Types != nil {
+               if check.recordTypes() {
                        check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
                }
 
@@ -843,7 +845,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                }
                var t operand
                x1 := x
-               for _, arg := range call.Args {
+               for _, arg := range argList {
                        check.rawExpr(nil, x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
                        check.dump("%v: %s", x1.Pos(), x1)
                        x1 = &t // use incoming x only for first argument