1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 Etop = 1 << iota // evaluated at statement level
17 Erv // evaluated in value context
18 Etype // evaluated in type context
19 Ecall // call-only expressions are ok
20 Efnstruct // multivalue function returns are ok
21 Easgn // assigning to expression
22 Ecomplit // type in composite literal
25 // type check the whole tree of an expression.
26 // calculates expression types.
27 // evaluates compile time constants.
28 // marks variables that escape the local frame.
29 // rewrites n->op to be more specific in some cases.
30 var typecheckdefstack []*Node
32 // resolve ONONAME to definition, if any.
33 func resolve(n *Node) *Node {
34 if n != nil && n.Op == ONONAME && n.Sym != nil {
39 } else if n.Iota() >= 0 {
40 n = nodintconst(n.Iota())
48 func typecheckslice(l []*Node, top int) {
50 l[i] = typecheck(l[i], top)
54 var _typekind = []string{
66 TCOMPLEX64: "complex64",
67 TCOMPLEX128: "complex128",
74 TUNSAFEPTR: "unsafe.Pointer",
83 TIDEAL: "untyped number",
86 func typekind(t *Type) string {
91 if int(et) < len(_typekind) {
97 return fmt.Sprintf("etype=%d", et)
100 // sprint_depchain prints a dependency chain of nodes into fmt.
101 // It is used by typecheck in the case of OLITERAL nodes
102 // to print constant definition loops.
103 func sprint_depchain(fmt_ *string, stack []*Node, cur *Node, first *Node) {
104 for i := len(stack) - 1; i >= 0; i-- {
105 if n := stack[i]; n.Op == cur.Op {
107 sprint_depchain(fmt_, stack[:i], n, first)
109 *fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cur)
115 var typecheck_tcstack []*Node
117 // typecheck type checks node n.
118 // The result of typecheck MUST be assigned back to n, e.g.
119 // n.Left = typecheck(n.Left, top)
120 func typecheck(n *Node, top int) *Node {
121 // cannot type check until all the source has been parsed
123 Fatalf("early typecheck")
137 // Resolve definition of name and value of iota lazily.
140 // Skip typecheck if already done.
141 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
142 if n.Typecheck == 1 {
144 case ONAME, OTYPE, OLITERAL, OPACK:
153 if n.Typecheck == 2 {
154 // Typechecking loop. Trying printing a meaningful message,
155 // otherwise a stack trace of typechecking.
158 // We can already diagnose variables used as types.
160 if top&(Erv|Etype) == Etype {
161 yyerror("%v is not a type", n)
165 if top&(Erv|Etype) == Etype {
166 yyerror("%v is not a type", n)
169 sprint_depchain(&fmt_, typecheck_tcstack, n, n)
170 yyerrorl(n.Pos, "constant definition loop%s", fmt_)
173 if nsavederrors+nerrors == 0 {
175 for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
176 x := typecheck_tcstack[i]
177 fmt_ += fmt.Sprintf("\n\t%v %v", x.Line(), x)
179 yyerror("typechecking loop involving %v%s", n, fmt_)
188 typecheck_tcstack = append(typecheck_tcstack, n)
189 n = typecheck1(n, top)
193 last := len(typecheck_tcstack) - 1
194 typecheck_tcstack[last] = nil
195 typecheck_tcstack = typecheck_tcstack[:last]
201 // does n contain a call or receive operation?
202 func callrecv(n *Node) bool {
222 return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.List) || callrecvlist(n.Rlist)
225 func callrecvlist(l Nodes) bool {
226 for _, n := range l.Slice() {
234 // indexlit implements typechecking of untyped values as
235 // array/slice indexes. It is equivalent to defaultlit
236 // except for constants of numerical kind, which are acceptable
237 // whenever they can be represented by a value of type int.
238 // The result of indexlit MUST be assigned back to n, e.g.
239 // n.Left = indexlit(n.Left)
240 func indexlit(n *Node) *Node {
241 if n == nil || !n.Type.IsUntyped() {
244 switch consttype(n) {
245 case CTINT, CTRUNE, CTFLT, CTCPLX:
246 n = defaultlit(n, Types[TINT])
249 n = defaultlit(n, nil)
253 // The result of typecheck1 MUST be assigned back to n, e.g.
254 // n.Left = typecheck1(n.Left, top)
255 func typecheck1(n *Node, top int) *Node {
257 case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER:
258 // n.Sym is a field/method name, not a variable.
261 if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
262 yyerror("use of builtin %v not in function call", n.Sym)
278 // until typecheck is complete, do nothing.
282 Fatalf("typecheck %v", n.Op)
288 if n.Type == nil && n.Val().Ctype() == CTSTR {
298 if n.Name.Decldepth == 0 {
299 n.Name.Decldepth = decldepth
307 // not a write to the variable
309 yyerror("cannot use _ as value")
321 yyerror("use of package %v without selector", n.Sym)
328 // types (OIND is with exprs)
338 r := typecheck(n.Right, Etype)
347 } else if n.Left.Op == ODDD {
348 if top&Ecomplit == 0 {
351 yyerror("use of [...] array outside of array literal")
356 t = typDDDArray(r.Type)
358 n.Left = indexlit(typecheck(n.Left, Erv))
360 if consttype(l) != CTINT {
361 if l.Type != nil && l.Type.IsInteger() && l.Op != OLITERAL {
362 yyerror("non-constant array bound %v", l)
364 yyerror("invalid array bound %v", l)
371 if doesoverflow(v, Types[TINT]) {
372 yyerror("array bound is too large")
377 bound := v.U.(*Mpint).Int64()
379 yyerror("array bound must be non-negative")
383 t = typArray(r.Type, bound)
396 n.Left = typecheck(n.Left, Etype)
397 n.Right = typecheck(n.Right, Etype)
400 if l.Type == nil || r.Type == nil {
404 if l.Type.NotInHeap {
405 yyerror("go:notinheap map key not allowed")
407 if r.Type.NotInHeap {
408 yyerror("go:notinheap map value not allowed")
411 n.Type = typMap(l.Type, r.Type)
413 // map key validation
414 alg, bad := algtype1(l.Type)
416 if bad.Etype == TFORW {
417 // queue check for map until all the types are done settling.
418 mapqueue = append(mapqueue, mapqueueval{l, n.Pos})
419 } else if bad.Etype != TANY {
420 // no need to queue, key is already bad
421 yyerror("invalid map key type %v", l.Type)
429 n.Left = typecheck(n.Left, Etype)
435 if l.Type.NotInHeap {
436 yyerror("chan of go:notinheap type not allowed")
438 t := typChan(l.Type, ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union.
447 n.Type = tostruct(n.List.Slice())
448 if n.Type == nil || n.Type.Broke {
457 n.Type = tointerface(n.List.Slice())
465 n.Type = functype(n.Left, n.List.Slice(), n.Rlist.Slice())
475 n.Left = typecheck(n.Left, Erv|Etype|top&Ecomplit)
485 n.Type = ptrto(l.Type)
491 if top&(Erv|Etop) != 0 {
492 yyerror("invalid indirect of %L", n.Left)
531 n.Left = typecheck(n.Left, Erv)
532 n.Right = typecheck(n.Right, Erv)
535 checkassign(n, n.Left)
536 if l.Type == nil || r.Type == nil {
540 if n.Implicit && !okforarith[l.Type.Etype] {
541 yyerror("invalid operation: %v (non-numeric type %v)", n, l.Type)
545 // TODO(marvin): Fix Node.EType type union.
549 n.Left = typecheck(n.Left, Erv)
550 n.Right = typecheck(n.Right, Erv)
553 if l.Type == nil || r.Type == nil {
559 if op == OLSH || op == ORSH {
560 r = defaultlit(r, Types[TUINT])
563 if !t.IsInteger() || t.IsSigned() {
564 yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", n, r.Type)
570 if t != nil && t.Etype != TIDEAL && !t.IsInteger() {
571 yyerror("invalid operation: %v (shift of type %v)", n, t)
576 // no defaultlit for left
577 // the outer context gives the type
583 // ideal mixed with non-ideal
584 l, r = defaultlit2(l, r, false)
588 if l.Type == nil || r.Type == nil {
593 if t.Etype == TIDEAL {
601 if iscmp[n.Op] && t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
602 // comparison is okay as long as one side is
603 // assignable to the other. convert so they have
606 // the only conversion that isn't a no-op is concrete == interface.
607 // in that case, check comparability of the concrete type.
608 // The conversion allocates, so only do it if the concrete type is huge.
609 if r.Type.Etype != TBLANK {
610 aop = assignop(l.Type, r.Type, nil)
612 if r.Type.IsInterface() && !l.Type.IsInterface() && !l.Type.IsComparable() {
613 yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type))
619 if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
631 if l.Type.Etype != TBLANK {
632 aop = assignop(r.Type, l.Type, nil)
634 if l.Type.IsInterface() && !r.Type.IsInterface() && !r.Type.IsComparable() {
635 yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type))
641 if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
656 if t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
657 l, r = defaultlit2(l, r, true)
658 if r.Type.IsInterface() == l.Type.IsInterface() || aop == 0 {
659 yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
666 yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
671 // okfor allows any array == array, map == map, func == func.
672 // restrict to slice/map/func == nil and nil == slice/map/func.
673 if l.Type.IsArray() && !l.Type.IsComparable() {
674 yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
679 if l.Type.IsSlice() && !isnil(l) && !isnil(r) {
680 yyerror("invalid operation: %v (slice can only be compared to nil)", n)
685 if l.Type.IsMap() && !isnil(l) && !isnil(r) {
686 yyerror("invalid operation: %v (map can only be compared to nil)", n)
691 if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) {
692 yyerror("invalid operation: %v (func can only be compared to nil)", n)
697 if l.Type.IsStruct() {
698 if f := l.Type.IncomparableField(); f != nil {
699 yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
709 if n.Op != OLITERAL {
710 l, r = defaultlit2(l, r, true)
718 // TODO(marvin): Fix Node.EType type union.
719 n.Etype = EType(n.Op)
721 } else if n.Op == OADD {
722 // create OADDSTR node with list of strings in x + y + z + (w + v) + ...
726 n.List.Set(l.List.Slice())
731 n.List.AppendNodes(&r.List)
741 if l.Op == OLITERAL && l.Val().Ctype() == CTNIL {
746 } else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
747 } else // leave alone for back end
748 if r.Type.IsInterface() == l.Type.IsInterface() {
749 // TODO(marvin): Fix Node.EType type union.
750 n.Etype = EType(n.Op)
755 if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
756 if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
757 yyerror("division by zero")
766 case OCOM, OMINUS, ONOT, OPLUS:
768 n.Left = typecheck(n.Left, Erv)
775 if !okfor[n.Op][t.Etype] {
776 yyerror("invalid operation: %v %v", n.Op, t)
788 n.Left = typecheck(n.Left, Erv)
789 if n.Left.Type == nil {
793 checklvalue(n.Left, "take the address of")
794 r := outervalue(n.Left)
796 for l = n.Left; l != r; l = l.Left {
798 if l.isClosureVar() {
799 l.Name.Defn.Addrtaken = true
803 if l.Orig != l && l.Op == ONAME {
804 Fatalf("found non-orig name node %v", l)
807 if l.isClosureVar() {
808 l.Name.Defn.Addrtaken = true
810 n.Left = defaultlit(n.Left, nil)
822 n = typecheckcomplit(n)
838 n.Left = typecheck(n.Left, Erv|Etype)
840 n.Left = defaultlit(n.Left, nil)
851 if n.Left.Op == OTYPE {
852 if !looktypedot(n, t, 0) {
853 if looktypedot(n, t, 1) {
854 yyerror("%v undefined (cannot refer to unexported method %v)", n, n.Sym)
856 yyerror("%v undefined (type %v has no method %v)", n, t, n.Sym)
862 if n.Type.Etype != TFUNC || !n.IsMethod() {
863 yyerror("type %v has no method %S", n.Left.Type, n.Right.Sym)
872 n.Right = newname(n.Sym)
873 n.Type = methodfunc(n.Type, n.Left.Type)
880 if t.IsPtr() && !t.Elem().IsInterface() {
890 if isblanksym(n.Sym) {
891 yyerror("cannot refer to blank field or method")
896 if lookdot(n, t, 0) == nil {
897 // Legitimate field or method lookup failed, try to explain the error
899 case t.IsEmptyInterface():
900 yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
902 case t.IsPtr() && t.Elem().IsInterface():
903 // Pointer to interface is almost always a mistake.
904 yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
906 case lookdot(n, t, 1) != nil:
907 // Field or method matches by name, but it is not exported.
908 yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
911 if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.
912 yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
914 yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
922 case ODOTINTER, ODOTMETH:
926 typecheckpartialcall(n, s)
938 n.Left = typecheck(n.Left, Erv)
939 n.Left = defaultlit(n.Left, nil)
946 if !t.IsInterface() {
947 yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
953 n.Right = typecheck(n.Right, Etype)
954 n.Type = n.Right.Type
961 if n.Type != nil && !n.Type.IsInterface() {
962 var missing, have *Field
964 if !implements(n.Type, t, &missing, &have, &ptr) {
965 if have != nil && have.Sym == missing.Sym {
966 yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
967 "\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
969 yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
970 } else if have != nil {
971 yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
972 "\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
974 yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
985 n.Left = typecheck(n.Left, Erv)
986 n.Left = defaultlit(n.Left, nil)
987 n.Left = implicitstar(n.Left)
989 n.Right = typecheck(n.Right, Erv)
992 if t == nil || r.Type == nil {
998 yyerror("invalid operation: %v (type %v does not support indexing)", n, t)
1002 case TSTRING, TARRAY, TSLICE:
1003 n.Right = indexlit(n.Right)
1012 } else if t.IsSlice() {
1016 if n.Right.Type != nil && !n.Right.Type.IsInteger() {
1017 yyerror("non-integer %s index %v", why, n.Right)
1021 if !n.Bounded && Isconst(n.Right, CTINT) {
1022 x := n.Right.Int64()
1024 yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
1025 } else if t.IsArray() && x >= t.NumElem() {
1026 yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
1027 } else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) {
1028 yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string)))
1029 } else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
1030 yyerror("invalid %s index %v (index too large)", why, n.Right)
1036 n.Right = defaultlit(n.Right, t.Key())
1037 if n.Right.Type != nil {
1038 n.Right = assignconv(n.Right, t.Key(), "map index")
1048 n.Left = typecheck(n.Left, Erv)
1049 n.Left = defaultlit(n.Left, nil)
1057 yyerror("invalid operation: %v (receive from non-chan type %v)", n, t)
1062 if !t.ChanDir().CanRecv() {
1063 yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
1073 n.Left = typecheck(n.Left, Erv)
1075 n.Right = typecheck(n.Right, Erv)
1076 n.Left = defaultlit(n.Left, nil)
1084 yyerror("invalid operation: %v (send to non-chan type %v)", n, t)
1089 if !t.ChanDir().CanSend() {
1090 yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
1095 n.Right = defaultlit(n.Right, t.Elem())
1101 n.Right = assignconv(r, l.Type.Elem(), "send")
1103 // TODO: more aggressive
1109 case OSLICE, OSLICE3:
1111 n.Left = typecheck(n.Left, top)
1112 low, high, max := n.SliceBounds()
1113 hasmax := n.Op.IsSlice3()
1114 low = typecheck(low, Erv)
1115 high = typecheck(high, Erv)
1116 max = typecheck(max, Erv)
1117 n.Left = defaultlit(n.Left, nil)
1119 high = indexlit(high)
1121 n.SetSliceBounds(low, high, max)
1123 if l.Type.IsArray() {
1124 if !islvalue(n.Left) {
1125 yyerror("invalid operation %v (slice of unaddressable value)", n)
1130 n.Left = nod(OADDR, n.Left, nil)
1131 n.Left.Implicit = true
1132 n.Left = typecheck(n.Left, Erv)
1144 yyerror("invalid operation %v (3-index slice of string)", n)
1150 } else if t.IsPtr() && t.Elem().IsArray() {
1152 n.Type = typSlice(tp.Elem())
1159 } else if t.IsSlice() {
1162 yyerror("cannot slice %v (type %v)", l, t)
1167 if low != nil && !checksliceindex(l, low, tp) {
1171 if high != nil && !checksliceindex(l, high, tp) {
1175 if max != nil && !checksliceindex(l, max, tp) {
1179 if !checksliceconst(low, high) || !checksliceconst(low, max) || !checksliceconst(high, max) {
1185 // call and call like
1187 n.Left = typecheck(n.Left, Erv|Etype|Ecall)
1194 if l.Op == ONAME && l.Etype != 0 {
1195 // TODO(marvin): Fix Node.EType type union.
1196 if n.Isddd && Op(l.Etype) != OAPPEND {
1197 yyerror("invalid use of ... with builtin %v", l)
1200 // builtin: OLEN, OCAP, etc.
1201 // TODO(marvin): Fix Node.EType type union.
1205 n = typecheck1(n, top)
1209 n.Left = defaultlit(n.Left, nil)
1212 if n.Isddd || l.Type.isDDDArray() {
1214 yyerror("invalid use of ... in type conversion to %v", l.Type)
1219 // pick off before type-checking arguments
1222 // turn CALL(type, arg) into CONV(arg) w/ type
1227 if !onearg(n, "conversion to %v", l.Type) {
1231 n = typecheck1(n, top)
1235 if n.List.Len() == 1 && !n.Isddd {
1236 n.List.SetIndex(0, typecheck(n.List.Index(0), Erv|Efnstruct))
1238 typecheckslice(n.List.Slice(), Erv)
1254 // typecheckaste was used here but there wasn't enough
1255 // information further down the call chain to know if we
1256 // were testing a method receiver for unexported fields.
1257 // It isn't necessary, so just do a sanity check.
1260 if l.Left == nil || !eqtype(l.Left.Type, tp) {
1261 Fatalf("method receiver")
1266 if t.Etype != TFUNC {
1267 yyerror("cannot call non-function %v (type %v)", l, t)
1273 typecheckaste(OCALL, n.Left, n.Isddd, t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
1275 if t.Results().NumFields() == 0 {
1279 if t.Results().NumFields() == 1 {
1280 n.Type = l.Type.Results().Field(0).Type
1282 if n.Op == OCALLFUNC && n.Left.Op == ONAME && (compiling_runtime || n.Left.Sym.Pkg == Runtimepkg) && n.Left.Sym.Name == "getg" {
1283 // Emit code for runtime.getg() directly instead of calling function.
1284 // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
1285 // so that the ordering pass can make sure to preserve the semantics of the original code
1286 // (in particular, the exact time of the function call) by introducing temporaries.
1287 // In this case, we know getg() always returns the same result within a given function
1288 // and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
1296 if top&(Efnstruct|Etop) == 0 {
1297 yyerror("multiple-value %v() in single-value context", l)
1301 n.Type = l.Type.Results()
1305 case OALIGNOF, OOFFSETOF, OSIZEOF:
1307 if !onearg(n, "%v", n.Op) {
1312 // any side effects disappear; ignore init
1314 Nodconst(&r, Types[TUINTPTR], evalunsafe(n))
1320 case OCAP, OLEN, OREAL, OIMAG:
1322 if !onearg(n, "%v", n.Op) {
1326 n.Left = typecheck(n.Left, Erv)
1327 n.Left = defaultlit(n.Left, nil)
1328 n.Left = implicitstar(n.Left)
1337 if !okforcap[t.Etype] {
1342 if !okforlen[t.Etype] {
1350 if Isconst(l, CTCPLX) {
1353 n = nodfltconst(&l.Val().U.(*Mpcplx).Real)
1355 n = nodfltconst(&l.Val().U.(*Mpcplx).Imag)
1360 n.Type = Types[cplxsubtype(t.Etype)]
1364 // might be constant
1367 if Isconst(l, CTSTR) {
1369 Nodconst(&r, Types[TINT], int64(len(l.Val().U.(string))))
1375 if callrecv(l) { // has call or receive
1379 Nodconst(&r, Types[TINT], t.NumElem())
1384 n.Type = Types[TINT]
1388 yyerror("invalid argument %L for %v", n.Left, n.Op)
1396 if n.List.Len() == 1 {
1397 typecheckslice(n.List.Slice(), Efnstruct)
1398 if n.List.First().Op != OCALLFUNC && n.List.First().Op != OCALLMETH {
1399 yyerror("invalid operation: complex expects two arguments")
1404 t := n.List.First().Left.Type
1405 if !t.IsKind(TFUNC) {
1406 // Bail. This error will be reported elsewhere.
1409 if t.Results().NumFields() != 2 {
1410 yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.Results().NumFields())
1415 t = n.List.First().Type
1416 l = t.Field(0).Nname
1417 r = t.Field(1).Nname
1423 n.Left = typecheck(n.Left, Erv)
1424 n.Right = typecheck(n.Right, Erv)
1427 if l.Type == nil || r.Type == nil {
1431 l, r = defaultlit2(l, r, false)
1432 if l.Type == nil || r.Type == nil {
1440 if !eqtype(l.Type, r.Type) {
1441 yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
1447 switch l.Type.Etype {
1449 yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type)
1457 t = Types[TCOMPLEX64]
1460 t = Types[TCOMPLEX128]
1463 if l.Op == OLITERAL && r.Op == OLITERAL {
1464 // make it a complex literal
1465 r = nodcplxlit(l.Val(), r.Val())
1475 if !onearg(n, "%v", n.Op) {
1479 n.Left = typecheck(n.Left, Erv)
1480 n.Left = defaultlit(n.Left, nil)
1488 yyerror("invalid operation: %v (non-chan type %v)", n, t)
1493 if !t.ChanDir().CanSend() {
1494 yyerror("invalid operation: %v (cannot close receive-only channel)", n)
1504 if args.Len() == 0 {
1505 yyerror("missing arguments to delete")
1510 if args.Len() == 1 {
1511 yyerror("missing second (key) argument to delete")
1516 if args.Len() != 2 {
1517 yyerror("too many arguments to delete")
1523 typecheckslice(args.Slice(), Erv)
1526 if l.Type != nil && !l.Type.IsMap() {
1527 yyerror("first argument to delete must be map; have %L", l.Type)
1532 args.SetIndex(1, assignconv(r, l.Type.Key(), "delete"))
1538 if args.Len() == 0 {
1539 yyerror("missing arguments to append")
1544 if args.Len() == 1 && !n.Isddd {
1545 args.SetIndex(0, typecheck(args.Index(0), Erv|Efnstruct))
1547 typecheckslice(args.Slice(), Erv)
1550 t := args.First().Type
1556 // Unpack multiple-return result before type-checking.
1558 if t.IsFuncArgStruct() {
1565 if Isconst(args.First(), CTNIL) {
1566 yyerror("first argument to append must be typed slice; have untyped nil")
1571 yyerror("first argument to append must be slice; have %L", t)
1577 if args.Len() == 1 {
1578 yyerror("cannot use ... on first argument to append")
1583 if args.Len() != 2 {
1584 yyerror("too many arguments to append")
1589 if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
1590 args.SetIndex(1, defaultlit(args.Index(1), Types[TSTRING]))
1594 args.SetIndex(1, assignconv(args.Index(1), t.Orig, "append"))
1599 _, it := iterFields(funarg) // Skip first field
1600 for t := it.Next(); t != nil; t = it.Next() {
1601 if assignop(t.Type, n.Type.Elem(), nil) == 0 {
1602 yyerror("cannot append %v value to []%v", t.Type, n.Type.Elem())
1606 as := args.Slice()[1:]
1607 for i, n := range as {
1611 as[i] = assignconv(n, t.Elem(), "append")
1621 yyerror("missing arguments to copy")
1627 yyerror("too many arguments to copy")
1632 n.Left = args.First()
1633 n.Right = args.Second()
1635 n.Type = Types[TINT]
1636 n.Left = typecheck(n.Left, Erv)
1637 n.Right = typecheck(n.Right, Erv)
1638 if n.Left.Type == nil || n.Right.Type == nil {
1642 n.Left = defaultlit(n.Left, nil)
1643 n.Right = defaultlit(n.Right, nil)
1644 if n.Left.Type == nil || n.Right.Type == nil {
1649 // copy([]byte, string)
1650 if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
1651 if eqtype(n.Left.Type.Elem(), bytetype) {
1654 yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
1659 if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
1660 if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
1661 yyerror("arguments to copy must be slices; have %L, %L", n.Left.Type, n.Right.Type)
1662 } else if !n.Left.Type.IsSlice() {
1663 yyerror("first argument to copy should be slice; have %L", n.Left.Type)
1665 yyerror("second argument to copy should be slice or string; have %L", n.Right.Type)
1671 if !eqtype(n.Left.Type.Elem(), n.Right.Type.Elem()) {
1672 yyerror("arguments to copy have different element types: %L and %L", n.Left.Type, n.Right.Type)
1682 n.Left = typecheck(n.Left, Erv)
1683 n.Left = convlit1(n.Left, n.Type, true, noReuse)
1685 if t == nil || n.Type == nil {
1690 n.Op = convertop(t, n.Type, &why)
1692 if !n.Diag && !n.Type.Broke {
1693 yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why)
1702 if n.Left.Op == OLITERAL {
1703 r := nod(OXXX, nil, nil)
1708 n.SetVal(n.Left.Val())
1711 // do not use stringtoarraylit.
1712 // generated code and compiler memory footprint is better without it.
1717 if n.Left.Op == OLITERAL {
1718 n = stringtoarraylit(n)
1726 args := n.List.Slice()
1728 yyerror("missing argument to make")
1735 l = typecheck(l, Etype)
1745 yyerror("cannot make type %v", t)
1751 yyerror("missing len argument to make(%v)", t)
1758 l = typecheck(l, Erv)
1763 r = typecheck(r, Erv)
1766 if l.Type == nil || (r != nil && r.Type == nil) {
1770 if !checkmake(t, "len", l) || r != nil && !checkmake(t, "cap", r) {
1774 if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && l.Val().U.(*Mpint).Cmp(r.Val().U.(*Mpint)) > 0 {
1775 yyerror("len larger than cap in make(%v)", t)
1788 l = typecheck(l, Erv)
1789 l = defaultlit(l, Types[TINT])
1794 if !checkmake(t, "size", l) {
1800 n.Left = nodintconst(0)
1809 l = typecheck(l, Erv)
1810 l = defaultlit(l, Types[TINT])
1815 if !checkmake(t, "buffer", l) {
1821 n.Left = nodintconst(0)
1827 yyerror("too many arguments to make(%v)", t)
1839 if args.Len() == 0 {
1840 yyerror("missing argument to new")
1846 l = typecheck(l, Etype)
1853 yyerror("too many arguments to new(%v)", t)
1862 case OPRINT, OPRINTN:
1864 typecheckslice(n.List.Slice(), Erv)
1865 ls := n.List.Slice()
1866 for i1, n1 := range ls {
1867 // Special case for print: int constant is int64, not int.
1868 if Isconst(n1, CTINT) {
1869 ls[i1] = defaultlit(ls[i1], Types[TINT64])
1871 ls[i1] = defaultlit(ls[i1], nil)
1879 if !onearg(n, "panic") {
1883 n.Left = typecheck(n.Left, Erv)
1884 n.Left = defaultlit(n.Left, Types[TINTER])
1885 if n.Left.Type == nil {
1893 if n.List.Len() != 0 {
1894 yyerror("too many arguments to recover")
1899 n.Type = Types[TINTER]
1904 typecheckclosure(n, top)
1912 n.Left = typecheck(n.Left, Erv)
1918 if !t.IsInterface() {
1919 Fatalf("OITAB of %v", t)
1921 n.Type = ptrto(Types[TUINTPTR])
1925 // Whoever creates the OIDATA node must know a priori the concrete type at that moment,
1926 // usually by just having checked the OITAB.
1927 Fatalf("cannot typecheck interface data %v", n)
1932 n.Left = typecheck(n.Left, Erv)
1938 if !t.IsSlice() && !t.IsString() {
1939 Fatalf("OSPTR of %v", t)
1942 n.Type = ptrto(Types[TUINT8])
1944 n.Type = ptrto(t.Elem())
1954 n.Left = typecheck(n.Left, Erv)
1955 n.Type = Types[TUINTPTR]
1960 n.Left = typecheck(n.Left, Erv)
1969 // Code that creates temps does not bother to set defn, so do it here.
1970 if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
1971 n.Left.Name.Defn = n
1998 n.Left = typecheck(n.Left, Etop|Erv)
2006 n.Left = typecheck(n.Left, Etop|Erv)
2012 typecheckslice(n.Ninit.Slice(), Etop)
2014 n.Left = typecheck(n.Left, Erv)
2017 if t != nil && !t.IsBoolean() {
2018 yyerror("non-bool %L used as for condition", n.Left)
2021 n.Right = typecheck(n.Right, Etop)
2022 typecheckslice(n.Nbody.Slice(), Etop)
2028 typecheckslice(n.Ninit.Slice(), Etop)
2029 n.Left = typecheck(n.Left, Erv)
2032 if t != nil && !t.IsBoolean() {
2033 yyerror("non-bool %L used as if condition", n.Left)
2036 typecheckslice(n.Nbody.Slice(), Etop)
2037 typecheckslice(n.Rlist.Slice(), Etop)
2042 if n.List.Len() == 1 {
2043 typecheckslice(n.List.Slice(), Erv|Efnstruct)
2045 typecheckslice(n.List.Slice(), Erv)
2048 yyerror("return outside function")
2053 if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
2056 typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
2079 yyerror("use of .(type) outside type switch")
2085 typecheckslice(n.List.Slice(), Erv)
2086 typecheckslice(n.Nbody.Slice(), Etop)
2096 n.Left = typecheck(n.Left, Erv)
2101 n.Left = typecheck(n.Left, Etype)
2102 checkwidth(n.Left.Type)
2103 if n.Left.Type != nil && n.Left.Type.NotInHeap && n.Left.Name.Param.Pragma&NotInHeap == 0 {
2104 // The type contains go:notinheap types, so it
2105 // must be marked as such (alternatively, we
2106 // could silently propagate go:notinheap).
2107 yyerror("type %v must be go:notinheap", n.Left.Type)
2113 if t != nil && !t.IsFuncArgStruct() && n.Op != OTYPE {
2115 case TFUNC, // might have TANY; wait until it's called
2116 TANY, TFORW, TIDEAL, TNIL, TBLANK:
2124 if safemode && importpkg == nil && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
2125 yyerror("cannot use unsafe.Pointer")
2129 if n.Op == OTYPE && top&Etype == 0 {
2130 yyerror("type %v is not an expression", n.Type)
2135 if top&(Erv|Etype) == Etype && n.Op != OTYPE {
2136 yyerror("%v is not a type", n)
2141 // TODO(rsc): simplify
2142 if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 {
2143 yyerror("%v used as value", n)
2148 if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 {
2150 yyerror("%v evaluated but not used", n)
2160 fatal("typecheck nil type");
2165 func checksliceindex(l *Node, r *Node, tp *Type) bool {
2171 yyerror("invalid slice index %v (type %v)", r, t)
2175 if r.Op == OLITERAL {
2177 yyerror("invalid slice index %v (index must be non-negative)", r)
2179 } else if tp != nil && tp.NumElem() > 0 && r.Int64() > tp.NumElem() {
2180 yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
2182 } else if Isconst(l, CTSTR) && r.Int64() > int64(len(l.Val().U.(string))) {
2183 yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.Val().U.(string)))
2185 } else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
2186 yyerror("invalid slice index %v (index too large)", r)
2194 func checksliceconst(lo *Node, hi *Node) bool {
2195 if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && lo.Val().U.(*Mpint).Cmp(hi.Val().U.(*Mpint)) > 0 {
2196 yyerror("invalid slice index: %v > %v", lo, hi)
2203 func checkdefergo(n *Node) {
2234 OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
2235 if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
2238 yyerror("%s discards result of %v", what, n.Left)
2242 // type is broken or missing, most likely a method call on a broken type
2243 // we will warn about the broken type elsewhere. no need to emit a potentially confusing error
2244 if n.Left.Type == nil || n.Left.Type.Broke {
2249 // The syntax made sure it was a call, so this must be
2252 yyerror("%s requires function call, not conversion", what)
2256 // The result of implicitstar MUST be assigned back to n, e.g.
2257 // n.Left = implicitstar(n.Left)
2258 func implicitstar(n *Node) *Node {
2259 // insert implicit * if needed for fixed array
2261 if t == nil || !t.IsPtr() {
2271 n = nod(OIND, n, nil)
2273 n = typecheck(n, Erv)
2277 func onearg(n *Node, f string, args ...interface{}) bool {
2281 if n.List.Len() == 0 {
2282 p := fmt.Sprintf(f, args...)
2283 yyerror("missing argument to %s: %v", p, n)
2287 if n.List.Len() > 1 {
2288 p := fmt.Sprintf(f, args...)
2289 yyerror("too many arguments to %s: %v", p, n)
2290 n.Left = n.List.First()
2295 n.Left = n.List.First()
2300 func twoarg(n *Node) bool {
2304 if n.List.Len() == 0 {
2305 yyerror("missing argument to %v - %v", n.Op, n)
2309 n.Left = n.List.First()
2310 if n.List.Len() == 1 {
2311 yyerror("missing argument to %v - %v", n.Op, n)
2316 if n.List.Len() > 2 {
2317 yyerror("too many arguments to %v - %v", n.Op, n)
2322 n.Right = n.List.Second()
2327 func lookdot1(errnode *Node, s *Sym, t *Type, fs *Fields, dostrcmp int) *Field {
2329 for _, f := range fs.Slice() {
2330 if dostrcmp != 0 && f.Sym.Name == s.Name {
2333 if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
2341 yyerror("ambiguous selector %v", errnode)
2342 } else if t.IsPtr() {
2343 yyerror("ambiguous selector (%v).%v", t, s)
2345 yyerror("ambiguous selector %v.%v", t, s)
2356 func looktypedot(n *Node, t *Type, dostrcmp int) bool {
2359 if t.IsInterface() {
2360 f1 := lookdot1(n, s, t, t.Fields(), dostrcmp)
2365 n.Sym = methodsym(n.Sym, t, 0)
2366 n.Xoffset = f1.Offset
2372 // Find the base type: methtype will fail if t
2373 // is not of the form T or *T.
2380 f2 := lookdot1(n, s, mt, mt.AllMethods(), dostrcmp)
2385 // disallow T.m if m requires *T receiver
2386 if f2.Type.Recv().Type.IsPtr() && !t.IsPtr() && f2.Embedded != 2 && !isifacemethod(f2.Type) {
2387 yyerror("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, f2.Sym)
2391 n.Sym = methodsym(n.Sym, t, 0)
2392 n.Xoffset = f2.Offset
2398 func derefall(t *Type) *Type {
2399 for t != nil && t.Etype == Tptr {
2405 type typeSym struct {
2410 // dotField maps (*Type, *Sym) pairs to the corresponding struct field (*Type with Etype==TFIELD).
2411 // It is a cache for use during usefield in walk.go, only enabled when field tracking.
2412 var dotField = map[typeSym]*Field{}
2414 func lookdot(n *Node, t *Type, dostrcmp int) *Field {
2419 if t.IsStruct() || t.IsInterface() {
2420 f1 = lookdot1(n, s, t, t.Fields(), dostrcmp)
2424 if n.Left.Type == t || n.Left.Type.Sym == nil {
2427 // Use f2->method, not f2->xmethod: adddot has
2428 // already inserted all the necessary embedded dots.
2429 f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp)
2435 // Already in the process of diagnosing an error.
2439 yyerror("%v is both field and method", n.Sym)
2441 if f1.Offset == BADWIDTH {
2442 Fatalf("lookdot badwidth %v %p", f1, f1)
2444 n.Xoffset = f1.Offset
2446 if obj.Fieldtrack_enabled > 0 {
2447 dotField[typeSym{t.Orig, s}] = f1
2449 if t.IsInterface() {
2450 if n.Left.Type.IsPtr() {
2451 n.Left = nod(OIND, n.Left, nil) // implicitstar
2452 n.Left.Implicit = true
2453 n.Left = typecheck(n.Left, Erv)
2464 // Already in the process of diagnosing an error.
2469 rcvr := f2.Type.Recv().Type
2470 if !eqtype(rcvr, tt) {
2471 if rcvr.Etype == Tptr && eqtype(rcvr.Elem(), tt) {
2472 checklvalue(n.Left, "call pointer method on")
2473 n.Left = nod(OADDR, n.Left, nil)
2474 n.Left.Implicit = true
2475 n.Left = typecheck(n.Left, Etype|Erv)
2476 } else if tt.Etype == Tptr && rcvr.Etype != Tptr && eqtype(tt.Elem(), rcvr) {
2477 n.Left = nod(OIND, n.Left, nil)
2478 n.Left.Implicit = true
2479 n.Left = typecheck(n.Left, Etype|Erv)
2480 } else if tt.Etype == Tptr && tt.Elem().Etype == Tptr && eqtype(derefall(tt), derefall(rcvr)) {
2481 yyerror("calling method %v with receiver %L requires explicit dereference", n.Sym, n.Left)
2482 for tt.Etype == Tptr {
2483 // Stop one level early for method with pointer receiver.
2484 if rcvr.Etype == Tptr && tt.Elem().Etype != Tptr {
2487 n.Left = nod(OIND, n.Left, nil)
2488 n.Left.Implicit = true
2489 n.Left = typecheck(n.Left, Etype|Erv)
2493 Fatalf("method mismatch: %v for %v", rcvr, tt)
2499 for ll.Left != nil && (ll.Op == ODOT || ll.Op == ODOTPTR || ll.Op == OIND) {
2503 if pll.Implicit && ll.Type.IsPtr() && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE {
2504 // It is invalid to automatically dereference a named pointer type when selecting a method.
2505 // Make n->left == ll to clarify error message.
2510 n.Sym = methodsym(n.Sym, n.Left.Type, 0)
2511 n.Xoffset = f2.Offset
2514 // print("lookdot found [%p] %T\n", f2->type, f2->type);
2523 func nokeys(l Nodes) bool {
2524 for _, n := range l.Slice() {
2525 if n.Op == OKEY || n.Op == OSTRUCTKEY {
2532 func hasddd(t *Type) bool {
2533 for _, tl := range t.Fields().Slice() {
2542 // typecheck assignment: type list = expression list
2543 func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc func() string) {
2560 if n.Type.IsFuncArgStruct() {
2561 if !hasddd(tstruct) {
2562 n1 := tstruct.NumFields()
2563 n2 := n.Type.NumFields()
2572 tn, it := iterFields(n.Type)
2574 for _, tl := range tstruct.Fields().Slice() {
2576 for ; tn != nil; tn = it.Next() {
2577 if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
2579 yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
2581 yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why)
2592 if assignop(tn.Type, tl.Type, &why) == 0 {
2594 yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
2596 yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
2611 n1 = tstruct.NumFields()
2613 if !hasddd(tstruct) {
2636 for _, tl := range tstruct.Fields().Slice() {
2649 nl.SetIndex(i, assignconvfn(n, t, desc))
2654 for ; i < nl.Len(); i++ {
2658 nl.SetIndex(i, assignconvfn(n, t.Elem(), desc))
2671 nl.SetIndex(i, assignconvfn(n, t, desc))
2681 yyerror("invalid use of ... in call to %v", call)
2683 yyerror("invalid use of ... in %v", op)
2692 if n == nil || !n.Diag {
2694 // call is the expression being called, not the overall call.
2695 // Method expressions have the form T.M, and the compiler has
2696 // rewritten those to ONAME nodes but left T in Left.
2697 if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
2698 yyerror("not enough arguments in call to method expression %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
2700 yyerror("not enough arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
2703 yyerror("not enough arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
2714 yyerror("too many arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
2716 yyerror("too many arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
2721 // sigrepr is a type's representation to the outside world,
2722 // in string representations of return signatures
2723 // e.g in error messages about wrong arguments to return.
2724 func (t *Type) sigrepr() string {
2730 // "untyped number" is not commonly used
2731 // outside of the compiler, so let's use "number".
2742 // retsigerr returns the signature of the types
2743 // at the respective return call site of a function.
2744 func (nl Nodes) retsigerr(isddd bool) string {
2749 var typeStrings []string
2750 if nl.Len() == 1 && nl.First().Type != nil && nl.First().Type.IsFuncArgStruct() {
2751 for _, f := range nl.First().Type.Fields().Slice() {
2752 typeStrings = append(typeStrings, f.Type.sigrepr())
2755 for _, n := range nl.Slice() {
2756 typeStrings = append(typeStrings, n.Type.sigrepr())
2764 return fmt.Sprintf("(%s%s)", strings.Join(typeStrings, ", "), ddd)
2767 // type check composite
2768 func fielddup(name string, hash map[string]bool) {
2770 yyerror("duplicate field name in struct literal: %s", name)
2776 func keydup(n *Node, hash map[uint32][]*Node) {
2778 if n.Op == OCONVIFACE {
2782 if n.Op != OLITERAL {
2783 return // we don't check variables
2789 switch v := n.Val().U.(type) {
2790 default: // unknown, bool, nil
2794 h = uint32(v.Int64())
2797 x := math.Float64bits(v.Float64())
2798 for i := 0; i < 8; i++ {
2799 h = h*PRIME1 + uint32(x&0xFF)
2804 for i := 0; i < len(v); i++ {
2805 h = h*PRIME1 + uint32(v[i])
2810 for _, a := range hash[h] {
2813 if a.Op == OCONVIFACE && orign.Op == OCONVIFACE {
2816 if !eqtype(a.Type, n.Type) {
2821 if cmp.Op != OLITERAL {
2822 // Sometimes evconst fails. See issue 12536.
2825 if cmp.Val().U.(bool) {
2826 yyerror("duplicate key %v in map literal", n)
2831 hash[h] = append(hash[h], orign)
2834 // iscomptype reports whether type t is a composite literal type
2835 // or a pointer to one.
2836 func iscomptype(t *Type) bool {
2842 case TARRAY, TSLICE, TSTRUCT, TMAP:
2849 func pushtype(n *Node, t *Type) {
2850 if n == nil || n.Op != OCOMPLIT || !iscomptype(t) {
2855 n.Right = typenod(t)
2856 n.Implicit = true // don't print
2857 n.Right.Implicit = true // * is okay
2858 } else if Debug['s'] != 0 {
2859 n.Right = typecheck(n.Right, Etype)
2860 if n.Right.Type != nil && eqtype(n.Right.Type, t) {
2861 fmt.Printf("%v: redundant type: %v\n", n.Line(), t)
2866 // The result of typecheckcomplit MUST be assigned back to n, e.g.
2867 // n.Left = typecheckcomplit(n.Left)
2868 func typecheckcomplit(n *Node) *Node {
2875 if n.List.Len() != 0 {
2876 setlineno(n.List.First())
2878 yyerror("missing type in composite literal")
2883 // Save original node (including n->right)
2884 norig := nod(n.Op, nil, nil)
2889 n.Right = typecheck(n.Right, Etype|Ecomplit)
2900 // For better or worse, we don't allow pointers as the composite literal type,
2901 // except when using the &T syntax, which sets implicit on the OIND.
2902 if !n.Right.Implicit {
2903 yyerror("invalid pointer type %v for composite literal (use &%v instead)", t, t.Elem())
2908 // Also, the underlying type must be a struct, map, slice, or array.
2910 yyerror("invalid pointer type %v for composite literal", t)
2920 yyerror("invalid type for composite literal: %v", t)
2923 case TARRAY, TSLICE:
2924 // If there are key/value pairs, create a map to keep seen
2925 // keys so we can check for duplicate indices.
2926 var indices map[int64]bool
2927 for _, n1 := range n.List.Slice() {
2929 indices = make(map[int64]bool)
2935 checkBounds := t.IsArray() && !t.isDDDArray()
2936 nl := n.List.Slice()
2937 for i2, l := range nl {
2941 l.Left = typecheck(l.Left, Erv)
2943 i = nonnegintconst(l.Left)
2944 if i < 0 && !l.Left.Diag {
2945 yyerror("index must be non-negative integer constant")
2947 i = -(1 << 30) // stay negative for a while
2952 if i >= 0 && indices != nil {
2954 yyerror("duplicate index in array literal: %d", i)
2961 pushtype(r, t.Elem())
2962 r = typecheck(r, Erv)
2963 r = defaultlit(r, t.Elem())
2964 *vp = assignconv(r, t.Elem(), "array or slice literal")
2969 if checkBounds && length > t.NumElem() {
2971 yyerror("array index %d out of bounds [0:%d]", length-1, t.NumElem())
2978 t.SetNumElem(length)
2981 n.Right = nodintconst(length)
2988 hash := make(map[uint32][]*Node)
2989 for i3, l := range n.List.Slice() {
2992 n.List.SetIndex(i3, typecheck(n.List.Index(i3), Erv))
2993 yyerror("missing key in map literal")
2998 pushtype(r, t.Key())
2999 r = typecheck(r, Erv)
3000 r = defaultlit(r, t.Key())
3001 l.Left = assignconv(r, t.Key(), "map key")
3002 if l.Left.Op != OCONV {
3003 keydup(l.Left, hash)
3007 pushtype(r, t.Val())
3008 r = typecheck(r, Erv)
3009 r = defaultlit(r, t.Val())
3010 l.Right = assignconv(r, t.Val(), "map value")
3016 // Need valid field offsets for Xoffset below.
3020 if n.List.Len() != 0 && nokeys(n.List) {
3021 // simple list of variables
3022 f, it := iterFields(t)
3024 ls := n.List.Slice()
3025 for i1, n1 := range ls {
3027 ls[i1] = typecheck(ls[i1], Erv)
3031 yyerror("too many values in struct initializer")
3038 if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
3039 yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
3041 // No pushtype allowed here. Must name fields for that.
3042 n1 = assignconv(n1, f.Type, "field value")
3043 n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
3044 n1.Xoffset = f.Offset
3050 yyerror("too few values in struct initializer")
3053 hash := make(map[string]bool)
3056 ls := n.List.Slice()
3057 for i, l := range ls {
3067 // An OXDOT uses the Sym field to hold
3068 // the field to the right of the dot,
3069 // so s will be non-nil, but an OXDOT
3070 // is never a valid struct literal key.
3071 if key.Sym == nil || key.Op == OXDOT {
3072 yyerror("invalid field name %v in struct initializer", key)
3073 l.Left = typecheck(l.Left, Erv)
3077 // Sym might have resolved to name in other top-level
3078 // package, because of import dot. Redirect to correct sym
3079 // before we do the lookup.
3081 if s.Pkg != localpkg && exportname(s.Name) {
3082 s1 := lookup(s.Name)
3083 if s1.Origpkg == s.Pkg {
3090 if l.Op != OSTRUCTKEY {
3092 yyerror("mixture of field:value and value initializers")
3095 ls[i] = typecheck(ls[i], Erv)
3099 f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
3101 yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
3104 fielddup(f.Sym.Name, hash)
3105 l.Xoffset = f.Offset
3107 // No pushtype allowed here. Tried and rejected.
3108 l.Left = typecheck(l.Left, Erv)
3109 l.Left = assignconv(l.Left, f.Type, "field value")
3116 if nerr != nerrors {
3122 n = nod(OPTRLIT, n, nil)
3124 n.Type = n.Left.Type
3126 n.Left.Typecheck = 1
3134 func islvalue(n *Node) bool {
3137 if n.Left.Type != nil && n.Left.Type.IsArray() {
3138 return islvalue(n.Left)
3140 if n.Left.Type != nil && n.Left.Type.IsString() {
3144 case OIND, ODOTPTR, OCLOSUREVAR:
3148 return islvalue(n.Left)
3151 if n.Class == PFUNC {
3160 func checklvalue(n *Node, verb string) {
3162 yyerror("cannot %s %v", verb, n)
3166 func checkassign(stmt *Node, n *Node) {
3167 // Variables declared in ORANGE are assigned on every iteration.
3168 if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ORANGE {
3171 for l = n; l != r; l = l.Left {
3173 if l.isClosureVar() {
3174 l.Name.Defn.Assigned = true
3179 if l.isClosureVar() {
3180 l.Name.Defn.Assigned = true
3187 if n.Op == OINDEXMAP {
3192 // have already complained about n being undefined
3193 if n.Op == ONONAME {
3197 if n.Op == ODOT && n.Left.Op == OINDEXMAP {
3198 yyerror("cannot assign to struct field %v in map", n)
3202 yyerror("cannot assign to %v", n)
3205 func checkassignlist(stmt *Node, l Nodes) {
3206 for _, n := range l.Slice() {
3207 checkassign(stmt, n)
3211 // Check whether l and r are the same side effect-free expression,
3212 // so that it is safe to reuse one instead of computing both.
3213 func samesafeexpr(l *Node, r *Node) bool {
3214 if l.Op != r.Op || !eqtype(l.Type, r.Type) {
3219 case ONAME, OCLOSUREVAR:
3223 return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left)
3225 case OIND, OCONVNOP:
3226 return samesafeexpr(l.Left, r.Left)
3229 // Some conversions can't be reused, such as []byte(str).
3230 // Allow only numeric-ish types. This is a bit conservative.
3231 return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left)
3234 return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
3237 return eqval(l.Val(), r.Val())
3243 // type check assignment.
3244 // if this assignment is the definition of a var on the left side,
3245 // fill in the var's type.
3246 func typecheckas(n *Node) {
3247 // delicate little dance.
3248 // the definition of n may refer to this assignment
3249 // as its definition, in which case it will call typecheckas.
3250 // in that case, do not call typecheck back, or it will cycle.
3251 // if the variable has a type (ntype) then typechecking
3252 // will not look at defn, so it is okay (and desirable,
3253 // so that the conversion below happens).
3254 n.Left = resolve(n.Left)
3256 if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil {
3257 n.Left = typecheck(n.Left, Erv|Easgn)
3260 n.Right = typecheck(n.Right, Erv)
3261 checkassign(n, n.Left)
3262 if n.Right != nil && n.Right.Type != nil {
3263 if n.Left.Type != nil {
3264 n.Right = assignconv(n.Right, n.Left.Type, "assignment")
3268 if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
3269 n.Right = defaultlit(n.Right, nil)
3270 n.Left.Type = n.Right.Type
3273 // second half of dance.
3274 // now that right is done, typecheck the left
3275 // just to get it over with. see dance above.
3278 if n.Left.Typecheck == 0 {
3279 n.Left = typecheck(n.Left, Erv|Easgn)
3283 func checkassignto(src *Type, dst *Node) {
3286 if assignop(src, dst.Type, &why) == 0 {
3287 yyerror("cannot assign %v to %L in multiple assignment%s", src, dst, why)
3292 func typecheckas2(n *Node) {
3293 ls := n.List.Slice()
3294 for i1, n1 := range ls {
3295 // delicate little dance.
3299 if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil {
3300 ls[i1] = typecheck(ls[i1], Erv|Easgn)
3306 if cl > 1 && cr == 1 {
3307 n.Rlist.SetIndex(0, typecheck(n.Rlist.Index(0), Erv|Efnstruct))
3309 typecheckslice(n.Rlist.Slice(), Erv)
3311 checkassignlist(n, n.List)
3317 ls := n.List.Slice()
3318 rs := n.Rlist.Slice()
3319 for il, nl := range ls {
3321 if nl.Type != nil && nr.Type != nil {
3322 rs[il] = assignconv(nr, nl.Type, "assignment")
3324 if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil {
3325 rs[il] = defaultlit(rs[il], nil)
3326 nl.Type = rs[il].Type
3342 case OCALLMETH, OCALLINTER, OCALLFUNC:
3343 if !r.Type.IsFuncArgStruct() {
3346 cr = r.Type.NumFields()
3351 t, s := iterFields(r.Type)
3352 for _, n3 := range n.List.Slice() {
3353 if t.Type != nil && n3.Type != nil {
3354 checkassignto(t.Type, n3)
3356 if n3.Name != nil && n3.Name.Defn == n && n3.Name.Param.Ntype == nil {
3367 if cl == 2 && cr == 1 {
3372 case OINDEXMAP, ORECV, ODOTTYPE:
3386 checkassignto(r.Type, l)
3388 if l.Name != nil && l.Name.Defn == n {
3391 l := n.List.Second()
3392 if l.Type != nil && !l.Type.IsBoolean() {
3393 checkassignto(Types[TBOOL], l)
3395 if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
3396 l.Type = Types[TBOOL]
3403 yyerror("assignment count mismatch: %d = %d", cl, cr)
3405 // second half of dance
3409 for i1, n1 := range ls {
3410 if n1.Typecheck == 0 {
3411 ls[i1] = typecheck(ls[i1], Erv|Easgn)
3416 // type check function definition
3417 func typecheckfunc(n *Node) {
3418 for _, ln := range n.Func.Dcl {
3419 if ln.Op == ONAME && (ln.Class == PPARAM || ln.Class == PPARAMOUT) {
3420 ln.Name.Decldepth = 1
3424 n.Func.Nname = typecheck(n.Func.Nname, Erv|Easgn)
3425 t := n.Func.Nname.Type
3430 t.SetNname(n.Func.Nname)
3432 if rcvr != nil && n.Func.Shortname != nil {
3433 addmethod(n.Func.Shortname.Sym, t, true, n.Func.Pragma&Nointerface != 0)
3437 // The result of stringtoarraylit MUST be assigned back to n, e.g.
3438 // n.Left = stringtoarraylit(n.Left)
3439 func stringtoarraylit(n *Node) *Node {
3440 if n.Left.Op != OLITERAL || n.Left.Val().Ctype() != CTSTR {
3441 Fatalf("stringtoarraylit %v", n)
3444 s := n.Left.Val().U.(string)
3446 if n.Type.Elem().Etype == TUINT8 {
3448 for i := 0; i < len(s); i++ {
3449 l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(s[0]))))
3454 for _, r := range s {
3455 l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
3460 nn := nod(OCOMPLIT, nil, typenod(n.Type))
3462 nn = typecheck(nn, Erv)
3466 var ntypecheckdeftype int
3468 var methodqueue []*Node
3470 func domethod(n *Node) {
3471 nt := n.Type.Nname()
3472 nt = typecheck(nt, Etype)
3474 // type check failed; leave empty func
3475 // TODO(mdempsky): Fix Type rekinding.
3476 n.Type.Etype = TFUNC
3482 // type I interface {
3485 // then even though I.M looks like it doesn't care about the
3486 // value of its argument, a specific implementation of I may
3487 // care. The _ would suppress the assignment to that argument
3488 // while generating a call, so remove it.
3489 for _, t := range nt.Type.Params().Fields().Slice() {
3490 if t.Sym != nil && t.Sym.Name == "_" {
3495 // TODO(mdempsky): Fix Type rekinding.
3501 type mapqueueval struct {
3506 // tracks the line numbers at which forward types are first used as map keys
3507 var mapqueue []mapqueueval
3509 func copytype(n *Node, t *Type) {
3510 if t.Etype == TFORW {
3511 // This type isn't computed yet; when it is, update n.
3512 t.ForwardType().Copyto = append(t.ForwardType().Copyto, n)
3516 embedlineno := n.Type.ForwardType().Embedlineno
3517 l := n.Type.ForwardType().Copyto
3519 ptrTo := n.Type.ptrTo
3520 sliceOf := n.Type.sliceOf
3522 // TODO(mdempsky): Fix Type rekinding.
3529 t.Vargen = n.Name.Vargen
3531 t.methods = Fields{}
3532 t.allMethods = Fields{}
3534 t.Deferwidth = false
3538 // Propagate go:notinheap pragma from the Name to the Type.
3539 if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma&NotInHeap != 0 {
3543 // Update nodes waiting on this type.
3544 for _, n := range l {
3548 // Double-check use of type as embedded type.
3551 if embedlineno.IsKnown() {
3552 lineno = embedlineno
3553 if t.IsPtr() || t.IsUnsafePtr() {
3554 yyerror("embedded type cannot be a pointer")
3561 func typecheckdeftype(n *Node) {
3567 n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3568 t := n.Name.Param.Ntype.Type
3580 // copy new type and clear fields
3581 // that don't come along.
3582 // anything zeroed here must be zeroed in
3589 // if there are no type definitions going on, it's safe to
3590 // try to resolve the method types for the interfaces
3592 if ntypecheckdeftype == 1 {
3599 for _, n := range s {
3603 for _, e := range mapqueue {
3605 if !e.n.Type.IsComparable() {
3606 yyerror("invalid map key type %v", e.n.Type)
3616 func queuemethod(n *Node) {
3617 if ntypecheckdeftype == 0 {
3622 methodqueue = append(methodqueue, n)
3625 func typecheckdef(n *Node) *Node {
3629 if n.Op == ONONAME {
3632 if n.Pos.IsKnown() {
3636 // Note: adderrorname looks for this string and
3637 // adds context about the outer expression
3638 yyerror("undefined: %v", n.Sym)
3648 typecheckdefstack = append(typecheckdefstack, n)
3651 fmt.Printf("typecheckdef loop:")
3652 for i := len(typecheckdefstack) - 1; i >= 0; i-- {
3653 n := typecheckdefstack[i]
3654 fmt.Printf(" %v", n.Sym)
3657 Fatalf("typecheckdef loop")
3662 if n.Type != nil || n.Sym == nil { // builtin or no name
3668 Fatalf("typecheckdef %v", n.Op)
3670 case OGOTO, OLABEL, OPACK:
3671 // nothing to do here
3674 if n.Name.Param.Ntype != nil {
3675 n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3676 n.Type = n.Name.Param.Ntype.Type
3677 n.Name.Param.Ntype = nil
3688 Dump("typecheckdef nil defn", n)
3692 e = typecheck(e, Erv)
3693 if Isconst(e, CTNIL) {
3694 yyerror("const initializer cannot be nil")
3698 if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) {
3700 yyerror("const initializer %v is not a constant", e)
3709 if !okforconst[t.Etype] {
3710 yyerror("invalid constant type %v", t)
3714 if !e.Type.IsUntyped() && !eqtype(t, e.Type) {
3715 yyerror("cannot use %L as type %v in const initializer", e, t)
3726 if n.Name.Param.Ntype != nil {
3727 n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3728 n.Type = n.Name.Param.Ntype.Type
3738 if n.Name.Defn == nil {
3739 if n.Etype != 0 { // like OPRINTN
3742 if nsavederrors+nerrors > 0 {
3743 // Can have undefined variables in x := foo
3744 // that make x have an n->ndefn == nil.
3745 // If there are other errors anyway, don't
3746 // bother adding to the noise.
3750 Fatalf("var without type, init: %v", n.Sym)
3753 if n.Name.Defn.Op == ONAME {
3754 n.Name.Defn = typecheck(n.Name.Defn, Erv)
3755 n.Type = n.Name.Defn.Type
3759 n.Name.Defn = typecheck(n.Name.Defn, Etop) // fills in n->type
3770 if n.Type.Etype == TFORW && nerrors > nerrors0 {
3771 // Something went wrong during type-checking,
3772 // but it was reported. Silence future errors.
3782 if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
3783 Fatalf("got %v for %v", n.Type, n)
3785 last := len(typecheckdefstack) - 1
3786 if typecheckdefstack[last] != n {
3787 Fatalf("typecheckdefstack mismatch")
3789 typecheckdefstack[last] = nil
3790 typecheckdefstack = typecheckdefstack[:last]
3797 func checkmake(t *Type, arg string, n *Node) bool {
3798 if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
3799 yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
3803 // Do range checks for constants before defaultlit
3804 // to avoid redundant "constant NNN overflows int" errors.
3805 switch consttype(n) {
3806 case CTINT, CTRUNE, CTFLT, CTCPLX:
3807 n.SetVal(toint(n.Val()))
3808 if n.Val().U.(*Mpint).CmpInt64(0) < 0 {
3809 yyerror("negative %s argument in make(%v)", arg, t)
3812 if n.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
3813 yyerror("%s argument too large in make(%v)", arg, t)
3818 // defaultlit is necessary for non-constants too: n might be 1.1<<k.
3819 n = defaultlit(n, Types[TINT])
3824 func markbreak(n *Node, implicit *Node) {
3832 if implicit != nil {
3833 implicit.SetHasBreak(true)
3836 lab := n.Left.Sym.Label
3838 lab.SetHasBreak(true)
3850 markbreak(n.Left, implicit)
3851 markbreak(n.Right, implicit)
3852 markbreaklist(n.Ninit, implicit)
3853 markbreaklist(n.Nbody, implicit)
3854 markbreaklist(n.List, implicit)
3855 markbreaklist(n.Rlist, implicit)
3859 func markbreaklist(l Nodes, implicit *Node) {
3861 for i := 0; i < len(s); i++ {
3866 if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
3867 switch n.Name.Defn.Op {
3868 case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE:
3869 n.Left.Sym.Label = n.Name.Defn
3870 markbreak(n.Name.Defn, n.Name.Defn)
3871 n.Left.Sym.Label = nil
3877 markbreak(n, implicit)
3881 // Isterminating whether the Nodes list ends with a terminating
3883 func (l Nodes) isterminating() bool {
3889 return s[c-1].isterminating()
3892 // Isterminating returns whether the node n, the last one in a
3893 // statement list, is a terminating statement.
3894 func (n *Node) isterminating() bool {
3896 // NOTE: OLABEL is treated as a separate statement,
3897 // not a separate prefix, so skipping to the last statement
3898 // in the block handles the labeled statement case by
3899 // skipping over the label. No case OLABEL here.
3902 return n.List.isterminating()
3921 return n.Nbody.isterminating() && n.Rlist.isterminating()
3923 case OSWITCH, OTYPESW, OSELECT:
3928 for _, n1 := range n.List.Slice() {
3929 if !n1.Nbody.isterminating() {
3932 if n1.List.Len() == 0 { // default
3937 if n.Op != OSELECT && def == 0 {
3946 func checkreturn(fn *Node) {
3947 if fn.Type.Results().NumFields() != 0 && fn.Nbody.Len() != 0 {
3948 markbreaklist(fn.Nbody, nil)
3949 if !fn.Nbody.isterminating() {
3950 yyerrorl(fn.Func.Endlineno, "missing return at end of function")