From: Robert Griesemer Date: Wed, 17 May 2023 03:05:13 +0000 (-0700) Subject: go/types, types2: reduce differences between go/types and types2 builtins.go X-Git-Tag: go1.21rc1~457 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=44b8f3907c034af0c3282f4ca888e2008d6ccb51;p=gostls13.git go/types, types2: reduce differences between go/types and types2 builtins.go Change-Id: I2946e061c70d31df3ba2aa3582700c3785b647e0 Reviewed-on: https://go-review.googlesource.com/c/go/+/495615 Reviewed-by: Robert Findley TryBot-Result: Gopher Robot Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer Run-TryBot: Robert Griesemer --- diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index de74da0bac..1d2780966a 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -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: diff --git a/src/go/types/api.go b/src/go/types/api.go index 14cd9cdcdb..3f83a8088a 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -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 { diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index 64d34e51cb..9f22fcf166 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -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