Home | History | Annotate | Download | only in gc
      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.
      4 
      5 package gc
      6 
      7 import (
      8 	"cmd/compile/internal/types"
      9 	"cmd/internal/objabi"
     10 	"fmt"
     11 	"math"
     12 	"strings"
     13 )
     14 
     15 const (
     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
     23 )
     24 
     25 // type checks 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 
     31 var typecheckdefstack []*Node
     32 
     33 // resolve ONONAME to definition, if any.
     34 func resolve(n *Node) *Node {
     35 	if n != nil && n.Op == ONONAME && n.Sym != nil {
     36 		r := asNode(n.Sym.Def)
     37 		if r != nil {
     38 			if r.Op != OIOTA {
     39 				n = r
     40 			} else if len(typecheckdefstack) > 0 {
     41 				x := typecheckdefstack[len(typecheckdefstack)-1]
     42 				if x.Op == OLITERAL {
     43 					n = nodintconst(x.Iota())
     44 				}
     45 			}
     46 		}
     47 	}
     48 
     49 	return n
     50 }
     51 
     52 func typecheckslice(l []*Node, top int) {
     53 	for i := range l {
     54 		l[i] = typecheck(l[i], top)
     55 	}
     56 }
     57 
     58 var _typekind = []string{
     59 	TINT:        "int",
     60 	TUINT:       "uint",
     61 	TINT8:       "int8",
     62 	TUINT8:      "uint8",
     63 	TINT16:      "int16",
     64 	TUINT16:     "uint16",
     65 	TINT32:      "int32",
     66 	TUINT32:     "uint32",
     67 	TINT64:      "int64",
     68 	TUINT64:     "uint64",
     69 	TUINTPTR:    "uintptr",
     70 	TCOMPLEX64:  "complex64",
     71 	TCOMPLEX128: "complex128",
     72 	TFLOAT32:    "float32",
     73 	TFLOAT64:    "float64",
     74 	TBOOL:       "bool",
     75 	TSTRING:     "string",
     76 	TPTR32:      "pointer",
     77 	TPTR64:      "pointer",
     78 	TUNSAFEPTR:  "unsafe.Pointer",
     79 	TSTRUCT:     "struct",
     80 	TINTER:      "interface",
     81 	TCHAN:       "chan",
     82 	TMAP:        "map",
     83 	TARRAY:      "array",
     84 	TSLICE:      "slice",
     85 	TFUNC:       "func",
     86 	TNIL:        "nil",
     87 	TIDEAL:      "untyped number",
     88 }
     89 
     90 func typekind(t *types.Type) string {
     91 	if t.IsSlice() {
     92 		return "slice"
     93 	}
     94 	et := t.Etype
     95 	if int(et) < len(_typekind) {
     96 		s := _typekind[et]
     97 		if s != "" {
     98 			return s
     99 		}
    100 	}
    101 	return fmt.Sprintf("etype=%d", et)
    102 }
    103 
    104 // sprint_depchain prints a dependency chain of nodes into trace.
    105 // It is used by typecheck in the case of OLITERAL nodes
    106 // to print constant definition loops.
    107 func sprint_depchain(trace *string, stack []*Node, cur *Node, first *Node) {
    108 	for i := len(stack) - 1; i >= 0; i-- {
    109 		if n := stack[i]; n.Op == cur.Op {
    110 			if n != first {
    111 				sprint_depchain(trace, stack[:i], n, first)
    112 			}
    113 			*trace += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cur)
    114 			return
    115 		}
    116 	}
    117 }
    118 
    119 var typecheck_tcstack []*Node
    120 
    121 // typecheck type checks node n.
    122 // The result of typecheck MUST be assigned back to n, e.g.
    123 // 	n.Left = typecheck(n.Left, top)
    124 func typecheck(n *Node, top int) *Node {
    125 	// cannot type check until all the source has been parsed
    126 	if !typecheckok {
    127 		Fatalf("early typecheck")
    128 	}
    129 
    130 	if n == nil {
    131 		return nil
    132 	}
    133 
    134 	lno := setlineno(n)
    135 
    136 	// Skip over parens.
    137 	for n.Op == OPAREN {
    138 		n = n.Left
    139 	}
    140 
    141 	// Resolve definition of name and value of iota lazily.
    142 	n = resolve(n)
    143 
    144 	// Skip typecheck if already done.
    145 	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
    146 	if n.Typecheck() == 1 {
    147 		switch n.Op {
    148 		case ONAME, OTYPE, OLITERAL, OPACK:
    149 			break
    150 
    151 		default:
    152 			lineno = lno
    153 			return n
    154 		}
    155 	}
    156 
    157 	if n.Typecheck() == 2 {
    158 		// Typechecking loop. Trying printing a meaningful message,
    159 		// otherwise a stack trace of typechecking.
    160 		switch n.Op {
    161 		// We can already diagnose variables used as types.
    162 		case ONAME:
    163 			if top&(Erv|Etype) == Etype {
    164 				yyerror("%v is not a type", n)
    165 			}
    166 
    167 		case OTYPE:
    168 			if top&Etype == Etype {
    169 				var trace string
    170 				sprint_depchain(&trace, typecheck_tcstack, n, n)
    171 				yyerrorl(n.Pos, "invalid recursive type alias %v%s", n, trace)
    172 			}
    173 
    174 		case OLITERAL:
    175 			if top&(Erv|Etype) == Etype {
    176 				yyerror("%v is not a type", n)
    177 				break
    178 			}
    179 			var trace string
    180 			sprint_depchain(&trace, typecheck_tcstack, n, n)
    181 			yyerrorl(n.Pos, "constant definition loop%s", trace)
    182 		}
    183 
    184 		if nsavederrors+nerrors == 0 {
    185 			var trace string
    186 			for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
    187 				x := typecheck_tcstack[i]
    188 				trace += fmt.Sprintf("\n\t%v %v", x.Line(), x)
    189 			}
    190 			yyerror("typechecking loop involving %v%s", n, trace)
    191 		}
    192 
    193 		lineno = lno
    194 		return n
    195 	}
    196 
    197 	n.SetTypecheck(2)
    198 
    199 	typecheck_tcstack = append(typecheck_tcstack, n)
    200 	n = typecheck1(n, top)
    201 
    202 	n.SetTypecheck(1)
    203 
    204 	last := len(typecheck_tcstack) - 1
    205 	typecheck_tcstack[last] = nil
    206 	typecheck_tcstack = typecheck_tcstack[:last]
    207 
    208 	lineno = lno
    209 	return n
    210 }
    211 
    212 // does n contain a call or receive operation?
    213 func callrecv(n *Node) bool {
    214 	if n == nil {
    215 		return false
    216 	}
    217 
    218 	switch n.Op {
    219 	case OCALL,
    220 		OCALLMETH,
    221 		OCALLINTER,
    222 		OCALLFUNC,
    223 		ORECV,
    224 		OCAP,
    225 		OLEN,
    226 		OCOPY,
    227 		ONEW,
    228 		OAPPEND,
    229 		ODELETE:
    230 		return true
    231 	}
    232 
    233 	return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.List) || callrecvlist(n.Rlist)
    234 }
    235 
    236 func callrecvlist(l Nodes) bool {
    237 	for _, n := range l.Slice() {
    238 		if callrecv(n) {
    239 			return true
    240 		}
    241 	}
    242 	return false
    243 }
    244 
    245 // indexlit implements typechecking of untyped values as
    246 // array/slice indexes. It is almost equivalent to defaultlit
    247 // but also accepts untyped numeric values representable as
    248 // value of type int (see also checkmake for comparison).
    249 // The result of indexlit MUST be assigned back to n, e.g.
    250 // 	n.Left = indexlit(n.Left)
    251 func indexlit(n *Node) *Node {
    252 	if n != nil && n.Type != nil && n.Type.Etype == TIDEAL {
    253 		return defaultlit(n, types.Types[TINT])
    254 	}
    255 	return n
    256 }
    257 
    258 // The result of typecheck1 MUST be assigned back to n, e.g.
    259 // 	n.Left = typecheck1(n.Left, top)
    260 func typecheck1(n *Node, top int) *Node {
    261 	switch n.Op {
    262 	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ORETJMP:
    263 		// n.Sym is a field/method name, not a variable.
    264 	default:
    265 		if n.Sym != nil {
    266 			if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
    267 				yyerror("use of builtin %v not in function call", n.Sym)
    268 				n.Type = nil
    269 				return n
    270 			}
    271 
    272 			typecheckdef(n)
    273 			if n.Op == ONONAME {
    274 				n.Type = nil
    275 				return n
    276 			}
    277 		}
    278 	}
    279 
    280 	ok := 0
    281 	switch n.Op {
    282 	// until typecheck is complete, do nothing.
    283 	default:
    284 		Dump("typecheck", n)
    285 
    286 		Fatalf("typecheck %v", n.Op)
    287 
    288 	// names
    289 	case OLITERAL:
    290 		ok |= Erv
    291 
    292 		if n.Type == nil && n.Val().Ctype() == CTSTR {
    293 			n.Type = types.Idealstring
    294 		}
    295 
    296 	case ONONAME:
    297 		ok |= Erv
    298 
    299 	case ONAME:
    300 		if n.Name.Decldepth == 0 {
    301 			n.Name.Decldepth = decldepth
    302 		}
    303 		if n.Etype != 0 {
    304 			ok |= Ecall
    305 			break
    306 		}
    307 
    308 		if top&Easgn == 0 {
    309 			// not a write to the variable
    310 			if isblank(n) {
    311 				yyerror("cannot use _ as value")
    312 				n.Type = nil
    313 				return n
    314 			}
    315 
    316 			n.Name.SetUsed(true)
    317 		}
    318 
    319 		ok |= Erv
    320 
    321 	case OPACK:
    322 		yyerror("use of package %v without selector", n.Sym)
    323 		n.Type = nil
    324 		return n
    325 
    326 	case ODDD:
    327 		break
    328 
    329 	// types (OIND is with exprs)
    330 	case OTYPE:
    331 		ok |= Etype
    332 
    333 		if n.Type == nil {
    334 			return n
    335 		}
    336 
    337 	case OTARRAY:
    338 		ok |= Etype
    339 		r := typecheck(n.Right, Etype)
    340 		if r.Type == nil {
    341 			n.Type = nil
    342 			return n
    343 		}
    344 
    345 		var t *types.Type
    346 		if n.Left == nil {
    347 			t = types.NewSlice(r.Type)
    348 		} else if n.Left.Op == ODDD {
    349 			if top&Ecomplit == 0 {
    350 				if !n.Diag() {
    351 					n.SetDiag(true)
    352 					yyerror("use of [...] array outside of array literal")
    353 				}
    354 				n.Type = nil
    355 				return n
    356 			}
    357 			t = types.NewDDDArray(r.Type)
    358 		} else {
    359 			n.Left = indexlit(typecheck(n.Left, Erv))
    360 			l := n.Left
    361 			if consttype(l) != CTINT {
    362 				switch {
    363 				case l.Type == nil:
    364 					// Error already reported elsewhere.
    365 				case l.Type.IsInteger() && l.Op != OLITERAL:
    366 					yyerror("non-constant array bound %v", l)
    367 				default:
    368 					yyerror("invalid array bound %v", l)
    369 				}
    370 				n.Type = nil
    371 				return n
    372 			}
    373 
    374 			v := l.Val()
    375 			if doesoverflow(v, types.Types[TINT]) {
    376 				yyerror("array bound is too large")
    377 				n.Type = nil
    378 				return n
    379 			}
    380 
    381 			bound := v.U.(*Mpint).Int64()
    382 			if bound < 0 {
    383 				yyerror("array bound must be non-negative")
    384 				n.Type = nil
    385 				return n
    386 			}
    387 			t = types.NewArray(r.Type, bound)
    388 		}
    389 
    390 		n.Op = OTYPE
    391 		n.Type = t
    392 		n.Left = nil
    393 		n.Right = nil
    394 		if !t.IsDDDArray() {
    395 			checkwidth(t)
    396 		}
    397 
    398 	case OTMAP:
    399 		ok |= Etype
    400 		n.Left = typecheck(n.Left, Etype)
    401 		n.Right = typecheck(n.Right, Etype)
    402 		l := n.Left
    403 		r := n.Right
    404 		if l.Type == nil || r.Type == nil {
    405 			n.Type = nil
    406 			return n
    407 		}
    408 		if l.Type.NotInHeap() {
    409 			yyerror("go:notinheap map key not allowed")
    410 		}
    411 		if r.Type.NotInHeap() {
    412 			yyerror("go:notinheap map value not allowed")
    413 		}
    414 		n.Op = OTYPE
    415 		n.Type = types.NewMap(l.Type, r.Type)
    416 		mapqueue = append(mapqueue, n) // check map keys when all types are settled
    417 		n.Left = nil
    418 		n.Right = nil
    419 
    420 	case OTCHAN:
    421 		ok |= Etype
    422 		n.Left = typecheck(n.Left, Etype)
    423 		l := n.Left
    424 		if l.Type == nil {
    425 			n.Type = nil
    426 			return n
    427 		}
    428 		if l.Type.NotInHeap() {
    429 			yyerror("chan of go:notinheap type not allowed")
    430 		}
    431 		t := types.NewChan(l.Type, types.ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union.
    432 		n.Op = OTYPE
    433 		n.Type = t
    434 		n.Left = nil
    435 		n.Etype = 0
    436 
    437 	case OTSTRUCT:
    438 		ok |= Etype
    439 		n.Op = OTYPE
    440 		n.Type = tostruct(n.List.Slice())
    441 		if n.Type == nil || n.Type.Broke() {
    442 			n.Type = nil
    443 			return n
    444 		}
    445 		n.List.Set(nil)
    446 
    447 	case OTINTER:
    448 		ok |= Etype
    449 		n.Op = OTYPE
    450 		n.Type = tointerface(n.List.Slice())
    451 		if n.Type == nil {
    452 			return n
    453 		}
    454 
    455 	case OTFUNC:
    456 		ok |= Etype
    457 		n.Op = OTYPE
    458 		n.Type = functype(n.Left, n.List.Slice(), n.Rlist.Slice())
    459 		if n.Type == nil {
    460 			return n
    461 		}
    462 		n.Left = nil
    463 		n.List.Set(nil)
    464 		n.Rlist.Set(nil)
    465 
    466 	// type or expr
    467 	case OIND:
    468 		n.Left = typecheck(n.Left, Erv|Etype|top&Ecomplit)
    469 		l := n.Left
    470 		t := l.Type
    471 		if t == nil {
    472 			n.Type = nil
    473 			return n
    474 		}
    475 		if l.Op == OTYPE {
    476 			ok |= Etype
    477 			n.Op = OTYPE
    478 			n.Type = types.NewPtr(l.Type)
    479 			// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
    480 			// Don't checkwidth [...] arrays, though, since they
    481 			// will be replaced by concrete-sized arrays. Issue 20333.
    482 			if !l.Type.IsDDDArray() {
    483 				checkwidth(l.Type)
    484 			}
    485 			n.Left = nil
    486 			break
    487 		}
    488 
    489 		if !t.IsPtr() {
    490 			if top&(Erv|Etop) != 0 {
    491 				yyerror("invalid indirect of %L", n.Left)
    492 				n.Type = nil
    493 				return n
    494 			}
    495 
    496 			break
    497 		}
    498 
    499 		ok |= Erv
    500 		n.Type = t.Elem()
    501 
    502 	// arithmetic exprs
    503 	case OASOP,
    504 		OADD,
    505 		OAND,
    506 		OANDAND,
    507 		OANDNOT,
    508 		ODIV,
    509 		OEQ,
    510 		OGE,
    511 		OGT,
    512 		OLE,
    513 		OLT,
    514 		OLSH,
    515 		ORSH,
    516 		OMOD,
    517 		OMUL,
    518 		ONE,
    519 		OOR,
    520 		OOROR,
    521 		OSUB,
    522 		OXOR:
    523 		var l *Node
    524 		var op Op
    525 		var r *Node
    526 		if n.Op == OASOP {
    527 			ok |= Etop
    528 			n.Left = typecheck(n.Left, Erv)
    529 			n.Right = typecheck(n.Right, Erv)
    530 			l = n.Left
    531 			r = n.Right
    532 			checkassign(n, n.Left)
    533 			if l.Type == nil || r.Type == nil {
    534 				n.Type = nil
    535 				return n
    536 			}
    537 			if n.Implicit() && !okforarith[l.Type.Etype] {
    538 				yyerror("invalid operation: %v (non-numeric type %v)", n, l.Type)
    539 				n.Type = nil
    540 				return n
    541 			}
    542 			// TODO(marvin): Fix Node.EType type union.
    543 			op = Op(n.Etype)
    544 		} else {
    545 			ok |= Erv
    546 			n.Left = typecheck(n.Left, Erv)
    547 			n.Right = typecheck(n.Right, Erv)
    548 			l = n.Left
    549 			r = n.Right
    550 			if l.Type == nil || r.Type == nil {
    551 				n.Type = nil
    552 				return n
    553 			}
    554 			op = n.Op
    555 		}
    556 		if op == OLSH || op == ORSH {
    557 			r = defaultlit(r, types.Types[TUINT])
    558 			n.Right = r
    559 			t := r.Type
    560 			if !t.IsInteger() || t.IsSigned() {
    561 				yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", n, r.Type)
    562 				n.Type = nil
    563 				return n
    564 			}
    565 
    566 			t = l.Type
    567 			if t != nil && t.Etype != TIDEAL && !t.IsInteger() {
    568 				yyerror("invalid operation: %v (shift of type %v)", n, t)
    569 				n.Type = nil
    570 				return n
    571 			}
    572 
    573 			// no defaultlit for left
    574 			// the outer context gives the type
    575 			n.Type = l.Type
    576 
    577 			break
    578 		}
    579 
    580 		// ideal mixed with non-ideal
    581 		l, r = defaultlit2(l, r, false)
    582 
    583 		n.Left = l
    584 		n.Right = r
    585 		if l.Type == nil || r.Type == nil {
    586 			n.Type = nil
    587 			return n
    588 		}
    589 		t := l.Type
    590 		if t.Etype == TIDEAL {
    591 			t = r.Type
    592 		}
    593 		et := t.Etype
    594 		if et == TIDEAL {
    595 			et = TINT
    596 		}
    597 		aop := OXXX
    598 		if iscmp[n.Op] && t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
    599 			// comparison is okay as long as one side is
    600 			// assignable to the other.  convert so they have
    601 			// the same type.
    602 			//
    603 			// the only conversion that isn't a no-op is concrete == interface.
    604 			// in that case, check comparability of the concrete type.
    605 			// The conversion allocates, so only do it if the concrete type is huge.
    606 			converted := false
    607 			if r.Type.Etype != TBLANK {
    608 				aop = assignop(l.Type, r.Type, nil)
    609 				if aop != 0 {
    610 					if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) {
    611 						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type))
    612 						n.Type = nil
    613 						return n
    614 					}
    615 
    616 					dowidth(l.Type)
    617 					if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
    618 						l = nod(aop, l, nil)
    619 						l.Type = r.Type
    620 						l.SetTypecheck(1)
    621 						n.Left = l
    622 					}
    623 
    624 					t = r.Type
    625 					converted = true
    626 				}
    627 			}
    628 
    629 			if !converted && l.Type.Etype != TBLANK {
    630 				aop = assignop(r.Type, l.Type, nil)
    631 				if aop != 0 {
    632 					if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) {
    633 						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type))
    634 						n.Type = nil
    635 						return n
    636 					}
    637 
    638 					dowidth(r.Type)
    639 					if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
    640 						r = nod(aop, r, nil)
    641 						r.Type = l.Type
    642 						r.SetTypecheck(1)
    643 						n.Right = r
    644 					}
    645 
    646 					t = l.Type
    647 				}
    648 			}
    649 
    650 			et = t.Etype
    651 		}
    652 
    653 		if t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
    654 			l, r = defaultlit2(l, r, true)
    655 			if r.Type.IsInterface() == l.Type.IsInterface() || aop == 0 {
    656 				yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
    657 				n.Type = nil
    658 				return n
    659 			}
    660 		}
    661 
    662 		if !okfor[op][et] {
    663 			yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
    664 			n.Type = nil
    665 			return n
    666 		}
    667 
    668 		// okfor allows any array == array, map == map, func == func.
    669 		// restrict to slice/map/func == nil and nil == slice/map/func.
    670 		if l.Type.IsArray() && !IsComparable(l.Type) {
    671 			yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
    672 			n.Type = nil
    673 			return n
    674 		}
    675 
    676 		if l.Type.IsSlice() && !isnil(l) && !isnil(r) {
    677 			yyerror("invalid operation: %v (slice can only be compared to nil)", n)
    678 			n.Type = nil
    679 			return n
    680 		}
    681 
    682 		if l.Type.IsMap() && !isnil(l) && !isnil(r) {
    683 			yyerror("invalid operation: %v (map can only be compared to nil)", n)
    684 			n.Type = nil
    685 			return n
    686 		}
    687 
    688 		if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) {
    689 			yyerror("invalid operation: %v (func can only be compared to nil)", n)
    690 			n.Type = nil
    691 			return n
    692 		}
    693 
    694 		if l.Type.IsStruct() {
    695 			if f := IncomparableField(l.Type); f != nil {
    696 				yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
    697 				n.Type = nil
    698 				return n
    699 			}
    700 		}
    701 
    702 		t = l.Type
    703 		if iscmp[n.Op] {
    704 			evconst(n)
    705 			t = types.Idealbool
    706 			if n.Op != OLITERAL {
    707 				l, r = defaultlit2(l, r, true)
    708 				n.Left = l
    709 				n.Right = r
    710 			}
    711 		}
    712 
    713 		if et == TSTRING {
    714 			if iscmp[n.Op] {
    715 				// TODO(marvin): Fix Node.EType type union.
    716 				n.Etype = types.EType(n.Op)
    717 				n.Op = OCMPSTR
    718 			} else if n.Op == OADD {
    719 				// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
    720 				n.Op = OADDSTR
    721 
    722 				if l.Op == OADDSTR {
    723 					n.List.Set(l.List.Slice())
    724 				} else {
    725 					n.List.Set1(l)
    726 				}
    727 				if r.Op == OADDSTR {
    728 					n.List.AppendNodes(&r.List)
    729 				} else {
    730 					n.List.Append(r)
    731 				}
    732 				n.Left = nil
    733 				n.Right = nil
    734 			}
    735 		}
    736 
    737 		if et == TINTER {
    738 			if l.Op == OLITERAL && l.Val().Ctype() == CTNIL {
    739 				// swap for back end
    740 				n.Left = r
    741 
    742 				n.Right = l
    743 			} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
    744 			} else // leave alone for back end
    745 			if r.Type.IsInterface() == l.Type.IsInterface() {
    746 				// TODO(marvin): Fix Node.EType type union.
    747 				n.Etype = types.EType(n.Op)
    748 				n.Op = OCMPIFACE
    749 			}
    750 		}
    751 
    752 		if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
    753 			if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
    754 				yyerror("division by zero")
    755 				n.Type = nil
    756 				return n
    757 			}
    758 		}
    759 
    760 		n.Type = t
    761 
    762 	case OCOM, OMINUS, ONOT, OPLUS:
    763 		ok |= Erv
    764 		n.Left = typecheck(n.Left, Erv)
    765 		l := n.Left
    766 		t := l.Type
    767 		if t == nil {
    768 			n.Type = nil
    769 			return n
    770 		}
    771 		if !okfor[n.Op][t.Etype] {
    772 			yyerror("invalid operation: %v %v", n.Op, t)
    773 			n.Type = nil
    774 			return n
    775 		}
    776 
    777 		n.Type = t
    778 
    779 	// exprs
    780 	case OADDR:
    781 		ok |= Erv
    782 
    783 		n.Left = typecheck(n.Left, Erv)
    784 		if n.Left.Type == nil {
    785 			n.Type = nil
    786 			return n
    787 		}
    788 		checklvalue(n.Left, "take the address of")
    789 		r := outervalue(n.Left)
    790 		var l *Node
    791 		for l = n.Left; l != r; l = l.Left {
    792 			l.SetAddrtaken(true)
    793 			if l.IsClosureVar() && !capturevarscomplete {
    794 				// Mark the original variable as Addrtaken so that capturevars
    795 				// knows not to pass it by value.
    796 				// But if the capturevars phase is complete, don't touch it,
    797 				// in case l.Name's containing function has not yet been compiled.
    798 				l.Name.Defn.SetAddrtaken(true)
    799 			}
    800 		}
    801 
    802 		if l.Orig != l && l.Op == ONAME {
    803 			Fatalf("found non-orig name node %v", l)
    804 		}
    805 		l.SetAddrtaken(true)
    806 		if l.IsClosureVar() && !capturevarscomplete {
    807 			// See comments above about closure variables.
    808 			l.Name.Defn.SetAddrtaken(true)
    809 		}
    810 		n.Left = defaultlit(n.Left, nil)
    811 		l = n.Left
    812 		t := l.Type
    813 		if t == nil {
    814 			n.Type = nil
    815 			return n
    816 		}
    817 		n.Type = types.NewPtr(t)
    818 
    819 	case OCOMPLIT:
    820 		ok |= Erv
    821 		n = typecheckcomplit(n)
    822 		if n.Type == nil {
    823 			return n
    824 		}
    825 
    826 	case OXDOT, ODOT:
    827 		if n.Op == OXDOT {
    828 			n = adddot(n)
    829 			n.Op = ODOT
    830 			if n.Left == nil {
    831 				n.Type = nil
    832 				return n
    833 			}
    834 		}
    835 
    836 		n.Left = typecheck(n.Left, Erv|Etype)
    837 
    838 		n.Left = defaultlit(n.Left, nil)
    839 
    840 		t := n.Left.Type
    841 		if t == nil {
    842 			adderrorname(n)
    843 			n.Type = nil
    844 			return n
    845 		}
    846 
    847 		s := n.Sym
    848 
    849 		if n.Left.Op == OTYPE {
    850 			if !looktypedot(n, t, 0) {
    851 				if looktypedot(n, t, 1) {
    852 					yyerror("%v undefined (cannot refer to unexported method %v)", n, n.Sym)
    853 				} else {
    854 					yyerror("%v undefined (type %v has no method %v)", n, t, n.Sym)
    855 				}
    856 				n.Type = nil
    857 				return n
    858 			}
    859 
    860 			if n.Type.Etype != TFUNC || !n.IsMethod() {
    861 				yyerror("type %v has no method %S", n.Left.Type, n.Sym)
    862 				n.Type = nil
    863 				return n
    864 			}
    865 
    866 			n.Op = ONAME
    867 			if n.Name == nil {
    868 				n.Name = new(Name)
    869 			}
    870 			n.Right = newname(n.Sym)
    871 			n.Type = methodfunc(n.Type, n.Left.Type)
    872 			n.Xoffset = 0
    873 			n.SetClass(PFUNC)
    874 			ok = Erv
    875 			break
    876 		}
    877 
    878 		if t.IsPtr() && !t.Elem().IsInterface() {
    879 			t = t.Elem()
    880 			if t == nil {
    881 				n.Type = nil
    882 				return n
    883 			}
    884 			n.Op = ODOTPTR
    885 			checkwidth(t)
    886 		}
    887 
    888 		if n.Sym.IsBlank() {
    889 			yyerror("cannot refer to blank field or method")
    890 			n.Type = nil
    891 			return n
    892 		}
    893 
    894 		if lookdot(n, t, 0) == nil {
    895 			// Legitimate field or method lookup failed, try to explain the error
    896 			switch {
    897 			case t.IsEmptyInterface():
    898 				yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
    899 
    900 			case t.IsPtr() && t.Elem().IsInterface():
    901 				// Pointer to interface is almost always a mistake.
    902 				yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
    903 
    904 			case lookdot(n, t, 1) != nil:
    905 				// Field or method matches by name, but it is not exported.
    906 				yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
    907 
    908 			default:
    909 				if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.
    910 					yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
    911 				} else {
    912 					yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
    913 				}
    914 			}
    915 			n.Type = nil
    916 			return n
    917 		}
    918 
    919 		switch n.Op {
    920 		case ODOTINTER, ODOTMETH:
    921 			if top&Ecall != 0 {
    922 				ok |= Ecall
    923 			} else {
    924 				typecheckpartialcall(n, s)
    925 				ok |= Erv
    926 			}
    927 
    928 		default:
    929 			ok |= Erv
    930 		}
    931 
    932 	case ODOTTYPE:
    933 		ok |= Erv
    934 		n.Left = typecheck(n.Left, Erv)
    935 		n.Left = defaultlit(n.Left, nil)
    936 		l := n.Left
    937 		t := l.Type
    938 		if t == nil {
    939 			n.Type = nil
    940 			return n
    941 		}
    942 		if !t.IsInterface() {
    943 			yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
    944 			n.Type = nil
    945 			return n
    946 		}
    947 
    948 		if n.Right != nil {
    949 			n.Right = typecheck(n.Right, Etype)
    950 			n.Type = n.Right.Type
    951 			n.Right = nil
    952 			if n.Type == nil {
    953 				return n
    954 			}
    955 		}
    956 
    957 		if n.Type != nil && !n.Type.IsInterface() {
    958 			var missing, have *types.Field
    959 			var ptr int
    960 			if !implements(n.Type, t, &missing, &have, &ptr) {
    961 				if have != nil && have.Sym == missing.Sym {
    962 					yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
    963 						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
    964 				} else if ptr != 0 {
    965 					yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
    966 				} else if have != nil {
    967 					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
    968 						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
    969 				} else {
    970 					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
    971 				}
    972 				n.Type = nil
    973 				return n
    974 			}
    975 		}
    976 
    977 	case OINDEX:
    978 		ok |= Erv
    979 		n.Left = typecheck(n.Left, Erv)
    980 		n.Left = defaultlit(n.Left, nil)
    981 		n.Left = implicitstar(n.Left)
    982 		l := n.Left
    983 		n.Right = typecheck(n.Right, Erv)
    984 		r := n.Right
    985 		t := l.Type
    986 		if t == nil || r.Type == nil {
    987 			n.Type = nil
    988 			return n
    989 		}
    990 		switch t.Etype {
    991 		default:
    992 			yyerror("invalid operation: %v (type %v does not support indexing)", n, t)
    993 			n.Type = nil
    994 			return n
    995 
    996 		case TSTRING, TARRAY, TSLICE:
    997 			n.Right = indexlit(n.Right)
    998 			if t.IsString() {
    999 				n.Type = types.Bytetype
   1000 			} else {
   1001 				n.Type = t.Elem()
   1002 			}
   1003 			why := "string"
   1004 			if t.IsArray() {
   1005 				why = "array"
   1006 			} else if t.IsSlice() {
   1007 				why = "slice"
   1008 			}
   1009 
   1010 			if n.Right.Type != nil && !n.Right.Type.IsInteger() {
   1011 				yyerror("non-integer %s index %v", why, n.Right)
   1012 				break
   1013 			}
   1014 
   1015 			if !n.Bounded() && Isconst(n.Right, CTINT) {
   1016 				x := n.Right.Int64()
   1017 				if x < 0 {
   1018 					yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
   1019 				} else if t.IsArray() && x >= t.NumElem() {
   1020 					yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
   1021 				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) {
   1022 					yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string)))
   1023 				} else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
   1024 					yyerror("invalid %s index %v (index too large)", why, n.Right)
   1025 				}
   1026 			}
   1027 
   1028 		case TMAP:
   1029 			n.Etype = 0
   1030 			n.Right = defaultlit(n.Right, t.Key())
   1031 			if n.Right.Type != nil {
   1032 				n.Right = assignconv(n.Right, t.Key(), "map index")
   1033 			}
   1034 			n.Type = t.Val()
   1035 			n.Op = OINDEXMAP
   1036 		}
   1037 
   1038 	case ORECV:
   1039 		ok |= Etop | Erv
   1040 		n.Left = typecheck(n.Left, Erv)
   1041 		n.Left = defaultlit(n.Left, nil)
   1042 		l := n.Left
   1043 		t := l.Type
   1044 		if t == nil {
   1045 			n.Type = nil
   1046 			return n
   1047 		}
   1048 		if !t.IsChan() {
   1049 			yyerror("invalid operation: %v (receive from non-chan type %v)", n, t)
   1050 			n.Type = nil
   1051 			return n
   1052 		}
   1053 
   1054 		if !t.ChanDir().CanRecv() {
   1055 			yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
   1056 			n.Type = nil
   1057 			return n
   1058 		}
   1059 
   1060 		n.Type = t.Elem()
   1061 
   1062 	case OSEND:
   1063 		ok |= Etop
   1064 		n.Left = typecheck(n.Left, Erv)
   1065 		n.Right = typecheck(n.Right, Erv)
   1066 		n.Left = defaultlit(n.Left, nil)
   1067 		t := n.Left.Type
   1068 		if t == nil {
   1069 			n.Type = nil
   1070 			return n
   1071 		}
   1072 		if !t.IsChan() {
   1073 			yyerror("invalid operation: %v (send to non-chan type %v)", n, t)
   1074 			n.Type = nil
   1075 			return n
   1076 		}
   1077 
   1078 		if !t.ChanDir().CanSend() {
   1079 			yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
   1080 			n.Type = nil
   1081 			return n
   1082 		}
   1083 
   1084 		n.Right = defaultlit(n.Right, t.Elem())
   1085 		r := n.Right
   1086 		if r.Type == nil {
   1087 			n.Type = nil
   1088 			return n
   1089 		}
   1090 		n.Right = assignconv(r, t.Elem(), "send")
   1091 
   1092 		// TODO: more aggressive
   1093 		n.Etype = 0
   1094 
   1095 		n.Type = nil
   1096 
   1097 	case OSLICE, OSLICE3:
   1098 		ok |= Erv
   1099 		n.Left = typecheck(n.Left, Erv)
   1100 		low, high, max := n.SliceBounds()
   1101 		hasmax := n.Op.IsSlice3()
   1102 		low = typecheck(low, Erv)
   1103 		high = typecheck(high, Erv)
   1104 		max = typecheck(max, Erv)
   1105 		n.Left = defaultlit(n.Left, nil)
   1106 		low = indexlit(low)
   1107 		high = indexlit(high)
   1108 		max = indexlit(max)
   1109 		n.SetSliceBounds(low, high, max)
   1110 		l := n.Left
   1111 		if l.Type == nil {
   1112 			n.Type = nil
   1113 			return n
   1114 		}
   1115 		if l.Type.IsArray() {
   1116 			if !islvalue(n.Left) {
   1117 				yyerror("invalid operation %v (slice of unaddressable value)", n)
   1118 				n.Type = nil
   1119 				return n
   1120 			}
   1121 
   1122 			n.Left = nod(OADDR, n.Left, nil)
   1123 			n.Left.SetImplicit(true)
   1124 			n.Left = typecheck(n.Left, Erv)
   1125 			l = n.Left
   1126 		}
   1127 		t := l.Type
   1128 		var tp *types.Type
   1129 		if t.IsString() {
   1130 			if hasmax {
   1131 				yyerror("invalid operation %v (3-index slice of string)", n)
   1132 				n.Type = nil
   1133 				return n
   1134 			}
   1135 			n.Type = t
   1136 			n.Op = OSLICESTR
   1137 		} else if t.IsPtr() && t.Elem().IsArray() {
   1138 			tp = t.Elem()
   1139 			n.Type = types.NewSlice(tp.Elem())
   1140 			dowidth(n.Type)
   1141 			if hasmax {
   1142 				n.Op = OSLICE3ARR
   1143 			} else {
   1144 				n.Op = OSLICEARR
   1145 			}
   1146 		} else if t.IsSlice() {
   1147 			n.Type = t
   1148 		} else {
   1149 			yyerror("cannot slice %v (type %v)", l, t)
   1150 			n.Type = nil
   1151 			return n
   1152 		}
   1153 
   1154 		if low != nil && !checksliceindex(l, low, tp) {
   1155 			n.Type = nil
   1156 			return n
   1157 		}
   1158 		if high != nil && !checksliceindex(l, high, tp) {
   1159 			n.Type = nil
   1160 			return n
   1161 		}
   1162 		if max != nil && !checksliceindex(l, max, tp) {
   1163 			n.Type = nil
   1164 			return n
   1165 		}
   1166 		if !checksliceconst(low, high) || !checksliceconst(low, max) || !checksliceconst(high, max) {
   1167 			n.Type = nil
   1168 			return n
   1169 		}
   1170 
   1171 	// call and call like
   1172 	case OCALL:
   1173 		n.Left = typecheck(n.Left, Erv|Etype|Ecall)
   1174 		if n.Left.Diag() {
   1175 			n.SetDiag(true)
   1176 		}
   1177 
   1178 		l := n.Left
   1179 
   1180 		if l.Op == ONAME && l.Etype != 0 {
   1181 			// TODO(marvin): Fix Node.EType type union.
   1182 			if n.Isddd() && Op(l.Etype) != OAPPEND {
   1183 				yyerror("invalid use of ... with builtin %v", l)
   1184 			}
   1185 
   1186 			// builtin: OLEN, OCAP, etc.
   1187 			// TODO(marvin): Fix Node.EType type union.
   1188 			n.Op = Op(l.Etype)
   1189 			n.Left = n.Right
   1190 			n.Right = nil
   1191 			n = typecheck1(n, top)
   1192 			return n
   1193 		}
   1194 
   1195 		n.Left = defaultlit(n.Left, nil)
   1196 		l = n.Left
   1197 		if l.Op == OTYPE {
   1198 			if n.Isddd() || l.Type.IsDDDArray() {
   1199 				if !l.Type.Broke() {
   1200 					yyerror("invalid use of ... in type conversion to %v", l.Type)
   1201 				}
   1202 				n.SetDiag(true)
   1203 			}
   1204 
   1205 			// pick off before type-checking arguments
   1206 			ok |= Erv
   1207 
   1208 			// turn CALL(type, arg) into CONV(arg) w/ type
   1209 			n.Left = nil
   1210 
   1211 			n.Op = OCONV
   1212 			n.Type = l.Type
   1213 			if !onearg(n, "conversion to %v", l.Type) {
   1214 				n.Type = nil
   1215 				return n
   1216 			}
   1217 			n = typecheck1(n, top)
   1218 			return n
   1219 		}
   1220 
   1221 		if n.List.Len() == 1 && !n.Isddd() {
   1222 			n.List.SetFirst(typecheck(n.List.First(), Erv|Efnstruct))
   1223 		} else {
   1224 			typecheckslice(n.List.Slice(), Erv)
   1225 		}
   1226 		t := l.Type
   1227 		if t == nil {
   1228 			n.Type = nil
   1229 			return n
   1230 		}
   1231 		checkwidth(t)
   1232 
   1233 		switch l.Op {
   1234 		case ODOTINTER:
   1235 			n.Op = OCALLINTER
   1236 
   1237 		case ODOTMETH:
   1238 			n.Op = OCALLMETH
   1239 
   1240 			// typecheckaste was used here but there wasn't enough
   1241 			// information further down the call chain to know if we
   1242 			// were testing a method receiver for unexported fields.
   1243 			// It isn't necessary, so just do a sanity check.
   1244 			tp := t.Recv().Type
   1245 
   1246 			if l.Left == nil || !eqtype(l.Left.Type, tp) {
   1247 				Fatalf("method receiver")
   1248 			}
   1249 
   1250 		default:
   1251 			n.Op = OCALLFUNC
   1252 			if t.Etype != TFUNC {
   1253 				yyerror("cannot call non-function %v (type %v)", l, t)
   1254 				n.Type = nil
   1255 				return n
   1256 			}
   1257 		}
   1258 
   1259 		typecheckaste(OCALL, n.Left, n.Isddd(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
   1260 		ok |= Etop
   1261 		if t.NumResults() == 0 {
   1262 			break
   1263 		}
   1264 		ok |= Erv
   1265 		if t.NumResults() == 1 {
   1266 			n.Type = l.Type.Results().Field(0).Type
   1267 
   1268 			if n.Op == OCALLFUNC && n.Left.Op == ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" {
   1269 				// Emit code for runtime.getg() directly instead of calling function.
   1270 				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
   1271 				// so that the ordering pass can make sure to preserve the semantics of the original code
   1272 				// (in particular, the exact time of the function call) by introducing temporaries.
   1273 				// In this case, we know getg() always returns the same result within a given function
   1274 				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
   1275 				n.Op = OGETG
   1276 			}
   1277 
   1278 			break
   1279 		}
   1280 
   1281 		// multiple return
   1282 		if top&(Efnstruct|Etop) == 0 {
   1283 			yyerror("multiple-value %v() in single-value context", l)
   1284 			break
   1285 		}
   1286 
   1287 		n.Type = l.Type.Results()
   1288 
   1289 	case OALIGNOF, OOFFSETOF, OSIZEOF:
   1290 		ok |= Erv
   1291 		if !onearg(n, "%v", n.Op) {
   1292 			n.Type = nil
   1293 			return n
   1294 		}
   1295 
   1296 		// any side effects disappear; ignore init
   1297 		var r Node
   1298 		nodconst(&r, types.Types[TUINTPTR], evalunsafe(n))
   1299 		r.Orig = n
   1300 		n = &r
   1301 
   1302 	case OCAP, OLEN:
   1303 		ok |= Erv
   1304 		if !onearg(n, "%v", n.Op) {
   1305 			n.Type = nil
   1306 			return n
   1307 		}
   1308 
   1309 		n.Left = typecheck(n.Left, Erv)
   1310 		n.Left = defaultlit(n.Left, nil)
   1311 		n.Left = implicitstar(n.Left)
   1312 		l := n.Left
   1313 		t := l.Type
   1314 		if t == nil {
   1315 			n.Type = nil
   1316 			return n
   1317 		}
   1318 
   1319 		var ok bool
   1320 		if n.Op == OLEN {
   1321 			ok = okforlen[t.Etype]
   1322 		} else {
   1323 			ok = okforcap[t.Etype]
   1324 		}
   1325 		if !ok {
   1326 			yyerror("invalid argument %L for %v", l, n.Op)
   1327 			n.Type = nil
   1328 			return n
   1329 		}
   1330 
   1331 		// result might be constant
   1332 		var res int64 = -1 // valid if >= 0
   1333 		switch t.Etype {
   1334 		case TSTRING:
   1335 			if Isconst(l, CTSTR) {
   1336 				res = int64(len(l.Val().U.(string)))
   1337 			}
   1338 
   1339 		case TARRAY:
   1340 			if !callrecv(l) {
   1341 				res = t.NumElem()
   1342 			}
   1343 		}
   1344 		if res >= 0 {
   1345 			var r Node
   1346 			nodconst(&r, types.Types[TINT], res)
   1347 			r.Orig = n
   1348 			n = &r
   1349 		}
   1350 
   1351 		n.Type = types.Types[TINT]
   1352 
   1353 	case OREAL, OIMAG:
   1354 		ok |= Erv
   1355 		if !onearg(n, "%v", n.Op) {
   1356 			n.Type = nil
   1357 			return n
   1358 		}
   1359 
   1360 		n.Left = typecheck(n.Left, Erv)
   1361 		l := n.Left
   1362 		t := l.Type
   1363 		if t == nil {
   1364 			n.Type = nil
   1365 			return n
   1366 		}
   1367 
   1368 		if t.Etype != TIDEAL && !t.IsComplex() {
   1369 			yyerror("invalid argument %L for %v", l, n.Op)
   1370 			n.Type = nil
   1371 			return n
   1372 		}
   1373 
   1374 		// if the argument is a constant, the result is a constant
   1375 		// (any untyped numeric constant can be represented as a
   1376 		// complex number)
   1377 		if l.Op == OLITERAL {
   1378 			var re, im *Mpflt
   1379 			switch consttype(l) {
   1380 			case CTINT, CTRUNE:
   1381 				re = newMpflt()
   1382 				re.SetInt(l.Val().U.(*Mpint))
   1383 				// im = 0
   1384 			case CTFLT:
   1385 				re = l.Val().U.(*Mpflt)
   1386 				// im = 0
   1387 			case CTCPLX:
   1388 				re = &l.Val().U.(*Mpcplx).Real
   1389 				im = &l.Val().U.(*Mpcplx).Imag
   1390 			default:
   1391 				yyerror("invalid argument %L for %v", l, n.Op)
   1392 				n.Type = nil
   1393 				return n
   1394 			}
   1395 			if n.Op == OIMAG {
   1396 				if im == nil {
   1397 					im = newMpflt()
   1398 				}
   1399 				re = im
   1400 			}
   1401 			orig := n
   1402 			n = nodfltconst(re)
   1403 			n.Orig = orig
   1404 		}
   1405 
   1406 		// determine result type
   1407 		et := t.Etype
   1408 		switch et {
   1409 		case TIDEAL:
   1410 			// result is ideal
   1411 		case TCOMPLEX64:
   1412 			et = TFLOAT32
   1413 		case TCOMPLEX128:
   1414 			et = TFLOAT64
   1415 		default:
   1416 			Fatalf("unexpected Etype: %v\n", et)
   1417 		}
   1418 		n.Type = types.Types[et]
   1419 
   1420 	case OCOMPLEX:
   1421 		ok |= Erv
   1422 		var r *Node
   1423 		var l *Node
   1424 		if n.List.Len() == 1 {
   1425 			typecheckslice(n.List.Slice(), Efnstruct)
   1426 			if n.List.First().Op != OCALLFUNC && n.List.First().Op != OCALLMETH {
   1427 				yyerror("invalid operation: complex expects two arguments")
   1428 				n.Type = nil
   1429 				return n
   1430 			}
   1431 
   1432 			t := n.List.First().Left.Type
   1433 			if !t.IsKind(TFUNC) {
   1434 				// Bail. This error will be reported elsewhere.
   1435 				return n
   1436 			}
   1437 			if t.NumResults() != 2 {
   1438 				yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.NumResults())
   1439 				n.Type = nil
   1440 				return n
   1441 			}
   1442 
   1443 			t = n.List.First().Type
   1444 			l = asNode(t.Field(0).Nname)
   1445 			r = asNode(t.Field(1).Nname)
   1446 		} else {
   1447 			if !twoarg(n) {
   1448 				n.Type = nil
   1449 				return n
   1450 			}
   1451 			n.Left = typecheck(n.Left, Erv)
   1452 			n.Right = typecheck(n.Right, Erv)
   1453 			l = n.Left
   1454 			r = n.Right
   1455 			if l.Type == nil || r.Type == nil {
   1456 				n.Type = nil
   1457 				return n
   1458 			}
   1459 			l, r = defaultlit2(l, r, false)
   1460 			if l.Type == nil || r.Type == nil {
   1461 				n.Type = nil
   1462 				return n
   1463 			}
   1464 			n.Left = l
   1465 			n.Right = r
   1466 		}
   1467 
   1468 		if !eqtype(l.Type, r.Type) {
   1469 			yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
   1470 			n.Type = nil
   1471 			return n
   1472 		}
   1473 
   1474 		var t *types.Type
   1475 		switch l.Type.Etype {
   1476 		default:
   1477 			yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type)
   1478 			n.Type = nil
   1479 			return n
   1480 
   1481 		case TIDEAL:
   1482 			t = types.Types[TIDEAL]
   1483 
   1484 		case TFLOAT32:
   1485 			t = types.Types[TCOMPLEX64]
   1486 
   1487 		case TFLOAT64:
   1488 			t = types.Types[TCOMPLEX128]
   1489 		}
   1490 
   1491 		if l.Op == OLITERAL && r.Op == OLITERAL {
   1492 			// make it a complex literal
   1493 			r = nodcplxlit(l.Val(), r.Val())
   1494 
   1495 			r.Orig = n
   1496 			n = r
   1497 		}
   1498 
   1499 		n.Type = t
   1500 
   1501 	case OCLOSE:
   1502 		if !onearg(n, "%v", n.Op) {
   1503 			n.Type = nil
   1504 			return n
   1505 		}
   1506 		n.Left = typecheck(n.Left, Erv)
   1507 		n.Left = defaultlit(n.Left, nil)
   1508 		l := n.Left
   1509 		t := l.Type
   1510 		if t == nil {
   1511 			n.Type = nil
   1512 			return n
   1513 		}
   1514 		if !t.IsChan() {
   1515 			yyerror("invalid operation: %v (non-chan type %v)", n, t)
   1516 			n.Type = nil
   1517 			return n
   1518 		}
   1519 
   1520 		if !t.ChanDir().CanSend() {
   1521 			yyerror("invalid operation: %v (cannot close receive-only channel)", n)
   1522 			n.Type = nil
   1523 			return n
   1524 		}
   1525 
   1526 		ok |= Etop
   1527 
   1528 	case ODELETE:
   1529 		args := n.List
   1530 		if args.Len() == 0 {
   1531 			yyerror("missing arguments to delete")
   1532 			n.Type = nil
   1533 			return n
   1534 		}
   1535 
   1536 		if args.Len() == 1 {
   1537 			yyerror("missing second (key) argument to delete")
   1538 			n.Type = nil
   1539 			return n
   1540 		}
   1541 
   1542 		if args.Len() != 2 {
   1543 			yyerror("too many arguments to delete")
   1544 			n.Type = nil
   1545 			return n
   1546 		}
   1547 
   1548 		ok |= Etop
   1549 		typecheckslice(args.Slice(), Erv)
   1550 		l := args.First()
   1551 		r := args.Second()
   1552 		if l.Type != nil && !l.Type.IsMap() {
   1553 			yyerror("first argument to delete must be map; have %L", l.Type)
   1554 			n.Type = nil
   1555 			return n
   1556 		}
   1557 
   1558 		args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
   1559 
   1560 	case OAPPEND:
   1561 		ok |= Erv
   1562 		args := n.List
   1563 		if args.Len() == 0 {
   1564 			yyerror("missing arguments to append")
   1565 			n.Type = nil
   1566 			return n
   1567 		}
   1568 
   1569 		if args.Len() == 1 && !n.Isddd() {
   1570 			args.SetFirst(typecheck(args.First(), Erv|Efnstruct))
   1571 		} else {
   1572 			typecheckslice(args.Slice(), Erv)
   1573 		}
   1574 
   1575 		t := args.First().Type
   1576 		if t == nil {
   1577 			n.Type = nil
   1578 			return n
   1579 		}
   1580 
   1581 		// Unpack multiple-return result before type-checking.
   1582 		var funarg *types.Type
   1583 		if t.IsFuncArgStruct() {
   1584 			funarg = t
   1585 			t = t.Field(0).Type
   1586 		}
   1587 
   1588 		n.Type = t
   1589 		if !t.IsSlice() {
   1590 			if Isconst(args.First(), CTNIL) {
   1591 				yyerror("first argument to append must be typed slice; have untyped nil")
   1592 				n.Type = nil
   1593 				return n
   1594 			}
   1595 
   1596 			yyerror("first argument to append must be slice; have %L", t)
   1597 			n.Type = nil
   1598 			return n
   1599 		}
   1600 
   1601 		if n.Isddd() {
   1602 			if args.Len() == 1 {
   1603 				yyerror("cannot use ... on first argument to append")
   1604 				n.Type = nil
   1605 				return n
   1606 			}
   1607 
   1608 			if args.Len() != 2 {
   1609 				yyerror("too many arguments to append")
   1610 				n.Type = nil
   1611 				return n
   1612 			}
   1613 
   1614 			if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
   1615 				args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
   1616 				break
   1617 			}
   1618 
   1619 			args.SetSecond(assignconv(args.Second(), t.Orig, "append"))
   1620 			break
   1621 		}
   1622 
   1623 		if funarg != nil {
   1624 			for _, t := range funarg.FieldSlice()[1:] {
   1625 				if assignop(t.Type, n.Type.Elem(), nil) == 0 {
   1626 					yyerror("cannot append %v value to []%v", t.Type, n.Type.Elem())
   1627 				}
   1628 			}
   1629 		} else {
   1630 			as := args.Slice()[1:]
   1631 			for i, n := range as {
   1632 				if n.Type == nil {
   1633 					continue
   1634 				}
   1635 				as[i] = assignconv(n, t.Elem(), "append")
   1636 				checkwidth(as[i].Type) // ensure width is calculated for backend
   1637 			}
   1638 		}
   1639 
   1640 	case OCOPY:
   1641 		ok |= Etop | Erv
   1642 		args := n.List
   1643 		if args.Len() < 2 {
   1644 			yyerror("missing arguments to copy")
   1645 			n.Type = nil
   1646 			return n
   1647 		}
   1648 
   1649 		if args.Len() > 2 {
   1650 			yyerror("too many arguments to copy")
   1651 			n.Type = nil
   1652 			return n
   1653 		}
   1654 
   1655 		n.Left = args.First()
   1656 		n.Right = args.Second()
   1657 		n.List.Set(nil)
   1658 		n.Type = types.Types[TINT]
   1659 		n.Left = typecheck(n.Left, Erv)
   1660 		n.Right = typecheck(n.Right, Erv)
   1661 		if n.Left.Type == nil || n.Right.Type == nil {
   1662 			n.Type = nil
   1663 			return n
   1664 		}
   1665 		n.Left = defaultlit(n.Left, nil)
   1666 		n.Right = defaultlit(n.Right, nil)
   1667 		if n.Left.Type == nil || n.Right.Type == nil {
   1668 			n.Type = nil
   1669 			return n
   1670 		}
   1671 
   1672 		// copy([]byte, string)
   1673 		if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
   1674 			if eqtype(n.Left.Type.Elem(), types.Bytetype) {
   1675 				break
   1676 			}
   1677 			yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
   1678 			n.Type = nil
   1679 			return n
   1680 		}
   1681 
   1682 		if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
   1683 			if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
   1684 				yyerror("arguments to copy must be slices; have %L, %L", n.Left.Type, n.Right.Type)
   1685 			} else if !n.Left.Type.IsSlice() {
   1686 				yyerror("first argument to copy should be slice; have %L", n.Left.Type)
   1687 			} else {
   1688 				yyerror("second argument to copy should be slice or string; have %L", n.Right.Type)
   1689 			}
   1690 			n.Type = nil
   1691 			return n
   1692 		}
   1693 
   1694 		if !eqtype(n.Left.Type.Elem(), n.Right.Type.Elem()) {
   1695 			yyerror("arguments to copy have different element types: %L and %L", n.Left.Type, n.Right.Type)
   1696 			n.Type = nil
   1697 			return n
   1698 		}
   1699 
   1700 	case OCONV:
   1701 		ok |= Erv
   1702 		saveorignode(n)
   1703 		checkwidth(n.Type) // ensure width is calculated for backend
   1704 		n.Left = typecheck(n.Left, Erv)
   1705 		n.Left = convlit1(n.Left, n.Type, true, noReuse)
   1706 		t := n.Left.Type
   1707 		if t == nil || n.Type == nil {
   1708 			n.Type = nil
   1709 			return n
   1710 		}
   1711 		var why string
   1712 		n.Op = convertop(t, n.Type, &why)
   1713 		if n.Op == 0 {
   1714 			if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() {
   1715 				yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why)
   1716 				n.SetDiag(true)
   1717 			}
   1718 
   1719 			n.Op = OCONV
   1720 		}
   1721 
   1722 		switch n.Op {
   1723 		case OCONVNOP:
   1724 			if n.Left.Op == OLITERAL {
   1725 				r := nod(OXXX, nil, nil)
   1726 				n.Op = OCONV
   1727 				n.Orig = r
   1728 				*r = *n
   1729 				n.Op = OLITERAL
   1730 				n.SetVal(n.Left.Val())
   1731 			} else if t.Etype == n.Type.Etype {
   1732 				switch t.Etype {
   1733 				case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
   1734 					// Floating point casts imply rounding and
   1735 					// so the conversion must be kept.
   1736 					n.Op = OCONV
   1737 				}
   1738 			}
   1739 
   1740 		// do not use stringtoarraylit.
   1741 		// generated code and compiler memory footprint is better without it.
   1742 		case OSTRARRAYBYTE:
   1743 			break
   1744 
   1745 		case OSTRARRAYRUNE:
   1746 			if n.Left.Op == OLITERAL {
   1747 				n = stringtoarraylit(n)
   1748 			}
   1749 		}
   1750 
   1751 	case OMAKE:
   1752 		ok |= Erv
   1753 		args := n.List.Slice()
   1754 		if len(args) == 0 {
   1755 			yyerror("missing argument to make")
   1756 			n.Type = nil
   1757 			return n
   1758 		}
   1759 
   1760 		n.List.Set(nil)
   1761 		l := args[0]
   1762 		l = typecheck(l, Etype)
   1763 		t := l.Type
   1764 		if t == nil {
   1765 			n.Type = nil
   1766 			return n
   1767 		}
   1768 
   1769 		i := 1
   1770 		switch t.Etype {
   1771 		default:
   1772 			yyerror("cannot make type %v", t)
   1773 			n.Type = nil
   1774 			return n
   1775 
   1776 		case TSLICE:
   1777 			if i >= len(args) {
   1778 				yyerror("missing len argument to make(%v)", t)
   1779 				n.Type = nil
   1780 				return n
   1781 			}
   1782 
   1783 			l = args[i]
   1784 			i++
   1785 			l = typecheck(l, Erv)
   1786 			var r *Node
   1787 			if i < len(args) {
   1788 				r = args[i]
   1789 				i++
   1790 				r = typecheck(r, Erv)
   1791 			}
   1792 
   1793 			if l.Type == nil || (r != nil && r.Type == nil) {
   1794 				n.Type = nil
   1795 				return n
   1796 			}
   1797 			if !checkmake(t, "len", l) || r != nil && !checkmake(t, "cap", r) {
   1798 				n.Type = nil
   1799 				return n
   1800 			}
   1801 			if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && l.Val().U.(*Mpint).Cmp(r.Val().U.(*Mpint)) > 0 {
   1802 				yyerror("len larger than cap in make(%v)", t)
   1803 				n.Type = nil
   1804 				return n
   1805 			}
   1806 
   1807 			n.Left = l
   1808 			n.Right = r
   1809 			n.Op = OMAKESLICE
   1810 
   1811 		case TMAP:
   1812 			if i < len(args) {
   1813 				l = args[i]
   1814 				i++
   1815 				l = typecheck(l, Erv)
   1816 				l = defaultlit(l, types.Types[TINT])
   1817 				if l.Type == nil {
   1818 					n.Type = nil
   1819 					return n
   1820 				}
   1821 				if !checkmake(t, "size", l) {
   1822 					n.Type = nil
   1823 					return n
   1824 				}
   1825 				n.Left = l
   1826 			} else {
   1827 				n.Left = nodintconst(0)
   1828 			}
   1829 			n.Op = OMAKEMAP
   1830 
   1831 		case TCHAN:
   1832 			l = nil
   1833 			if i < len(args) {
   1834 				l = args[i]
   1835 				i++
   1836 				l = typecheck(l, Erv)
   1837 				l = defaultlit(l, types.Types[TINT])
   1838 				if l.Type == nil {
   1839 					n.Type = nil
   1840 					return n
   1841 				}
   1842 				if !checkmake(t, "buffer", l) {
   1843 					n.Type = nil
   1844 					return n
   1845 				}
   1846 				n.Left = l
   1847 			} else {
   1848 				n.Left = nodintconst(0)
   1849 			}
   1850 			n.Op = OMAKECHAN
   1851 		}
   1852 
   1853 		if i < len(args) {
   1854 			yyerror("too many arguments to make(%v)", t)
   1855 			n.Op = OMAKE
   1856 			n.Type = nil
   1857 			return n
   1858 		}
   1859 
   1860 		n.Type = t
   1861 
   1862 	case ONEW:
   1863 		ok |= Erv
   1864 		args := n.List
   1865 		if args.Len() == 0 {
   1866 			yyerror("missing argument to new")
   1867 			n.Type = nil
   1868 			return n
   1869 		}
   1870 
   1871 		l := args.First()
   1872 		l = typecheck(l, Etype)
   1873 		t := l.Type
   1874 		if t == nil {
   1875 			n.Type = nil
   1876 			return n
   1877 		}
   1878 		if args.Len() > 1 {
   1879 			yyerror("too many arguments to new(%v)", t)
   1880 			n.Type = nil
   1881 			return n
   1882 		}
   1883 
   1884 		n.Left = l
   1885 		n.Type = types.NewPtr(t)
   1886 
   1887 	case OPRINT, OPRINTN:
   1888 		ok |= Etop
   1889 		typecheckslice(n.List.Slice(), Erv)
   1890 		ls := n.List.Slice()
   1891 		for i1, n1 := range ls {
   1892 			// Special case for print: int constant is int64, not int.
   1893 			if Isconst(n1, CTINT) {
   1894 				ls[i1] = defaultlit(ls[i1], types.Types[TINT64])
   1895 			} else {
   1896 				ls[i1] = defaultlit(ls[i1], nil)
   1897 			}
   1898 		}
   1899 
   1900 	case OPANIC:
   1901 		ok |= Etop
   1902 		if !onearg(n, "panic") {
   1903 			n.Type = nil
   1904 			return n
   1905 		}
   1906 		n.Left = typecheck(n.Left, Erv)
   1907 		n.Left = defaultlit(n.Left, types.Types[TINTER])
   1908 		if n.Left.Type == nil {
   1909 			n.Type = nil
   1910 			return n
   1911 		}
   1912 
   1913 	case ORECOVER:
   1914 		ok |= Erv | Etop
   1915 		if n.List.Len() != 0 {
   1916 			yyerror("too many arguments to recover")
   1917 			n.Type = nil
   1918 			return n
   1919 		}
   1920 
   1921 		n.Type = types.Types[TINTER]
   1922 
   1923 	case OCLOSURE:
   1924 		ok |= Erv
   1925 		typecheckclosure(n, top)
   1926 		if n.Type == nil {
   1927 			return n
   1928 		}
   1929 
   1930 	case OITAB:
   1931 		ok |= Erv
   1932 		n.Left = typecheck(n.Left, Erv)
   1933 		t := n.Left.Type
   1934 		if t == nil {
   1935 			n.Type = nil
   1936 			return n
   1937 		}
   1938 		if !t.IsInterface() {
   1939 			Fatalf("OITAB of %v", t)
   1940 		}
   1941 		n.Type = types.NewPtr(types.Types[TUINTPTR])
   1942 
   1943 	case OIDATA:
   1944 		// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
   1945 		// usually by just having checked the OITAB.
   1946 		Fatalf("cannot typecheck interface data %v", n)
   1947 
   1948 	case OSPTR:
   1949 		ok |= Erv
   1950 		n.Left = typecheck(n.Left, Erv)
   1951 		t := n.Left.Type
   1952 		if t == nil {
   1953 			n.Type = nil
   1954 			return n
   1955 		}
   1956 		if !t.IsSlice() && !t.IsString() {
   1957 			Fatalf("OSPTR of %v", t)
   1958 		}
   1959 		if t.IsString() {
   1960 			n.Type = types.NewPtr(types.Types[TUINT8])
   1961 		} else {
   1962 			n.Type = types.NewPtr(t.Elem())
   1963 		}
   1964 
   1965 	case OCLOSUREVAR:
   1966 		ok |= Erv
   1967 
   1968 	case OCFUNC:
   1969 		ok |= Erv
   1970 		n.Left = typecheck(n.Left, Erv)
   1971 		n.Type = types.Types[TUINTPTR]
   1972 
   1973 	case OCONVNOP:
   1974 		ok |= Erv
   1975 		n.Left = typecheck(n.Left, Erv)
   1976 
   1977 	// statements
   1978 	case OAS:
   1979 		ok |= Etop
   1980 
   1981 		typecheckas(n)
   1982 
   1983 		// Code that creates temps does not bother to set defn, so do it here.
   1984 		if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
   1985 			n.Left.Name.Defn = n
   1986 		}
   1987 
   1988 	case OAS2:
   1989 		ok |= Etop
   1990 		typecheckas2(n)
   1991 
   1992 	case OBREAK,
   1993 		OCONTINUE,
   1994 		ODCL,
   1995 		OEMPTY,
   1996 		OGOTO,
   1997 		OFALL,
   1998 		OVARKILL,
   1999 		OVARLIVE:
   2000 		ok |= Etop
   2001 
   2002 	case OLABEL:
   2003 		ok |= Etop
   2004 		decldepth++
   2005 		if n.Left.Sym.IsBlank() {
   2006 			// Empty identifier is valid but useless.
   2007 			// Eliminate now to simplify life later.
   2008 			// See issues 7538, 11589, 11593.
   2009 			n.Op = OEMPTY
   2010 			n.Left = nil
   2011 		}
   2012 
   2013 	case ODEFER:
   2014 		ok |= Etop
   2015 		n.Left = typecheck(n.Left, Etop|Erv)
   2016 		if !n.Left.Diag() {
   2017 			checkdefergo(n)
   2018 		}
   2019 
   2020 	case OPROC:
   2021 		ok |= Etop
   2022 		n.Left = typecheck(n.Left, Etop|Erv)
   2023 		checkdefergo(n)
   2024 
   2025 	case OFOR, OFORUNTIL:
   2026 		ok |= Etop
   2027 		typecheckslice(n.Ninit.Slice(), Etop)
   2028 		decldepth++
   2029 		n.Left = typecheck(n.Left, Erv)
   2030 		if n.Left != nil {
   2031 			t := n.Left.Type
   2032 			if t != nil && !t.IsBoolean() {
   2033 				yyerror("non-bool %L used as for condition", n.Left)
   2034 			}
   2035 		}
   2036 		n.Right = typecheck(n.Right, Etop)
   2037 		typecheckslice(n.Nbody.Slice(), Etop)
   2038 		decldepth--
   2039 
   2040 	case OIF:
   2041 		ok |= Etop
   2042 		typecheckslice(n.Ninit.Slice(), Etop)
   2043 		n.Left = typecheck(n.Left, Erv)
   2044 		if n.Left != nil {
   2045 			t := n.Left.Type
   2046 			if t != nil && !t.IsBoolean() {
   2047 				yyerror("non-bool %L used as if condition", n.Left)
   2048 			}
   2049 		}
   2050 		typecheckslice(n.Nbody.Slice(), Etop)
   2051 		typecheckslice(n.Rlist.Slice(), Etop)
   2052 
   2053 	case ORETURN:
   2054 		ok |= Etop
   2055 		if n.List.Len() == 1 {
   2056 			typecheckslice(n.List.Slice(), Erv|Efnstruct)
   2057 		} else {
   2058 			typecheckslice(n.List.Slice(), Erv)
   2059 		}
   2060 		if Curfn == nil {
   2061 			yyerror("return outside function")
   2062 			n.Type = nil
   2063 			return n
   2064 		}
   2065 
   2066 		if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
   2067 			break
   2068 		}
   2069 		typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
   2070 
   2071 	case ORETJMP:
   2072 		ok |= Etop
   2073 
   2074 	case OSELECT:
   2075 		ok |= Etop
   2076 		typecheckselect(n)
   2077 
   2078 	case OSWITCH:
   2079 		ok |= Etop
   2080 		typecheckswitch(n)
   2081 
   2082 	case ORANGE:
   2083 		ok |= Etop
   2084 		typecheckrange(n)
   2085 
   2086 	case OTYPESW:
   2087 		yyerror("use of .(type) outside type switch")
   2088 		n.Type = nil
   2089 		return n
   2090 
   2091 	case OXCASE:
   2092 		ok |= Etop
   2093 		typecheckslice(n.List.Slice(), Erv)
   2094 		typecheckslice(n.Nbody.Slice(), Etop)
   2095 
   2096 	case ODCLFUNC:
   2097 		ok |= Etop
   2098 		typecheckfunc(n)
   2099 
   2100 	case ODCLCONST:
   2101 		ok |= Etop
   2102 		n.Left = typecheck(n.Left, Erv)
   2103 
   2104 	case ODCLTYPE:
   2105 		ok |= Etop
   2106 		n.Left = typecheck(n.Left, Etype)
   2107 		checkwidth(n.Left.Type)
   2108 		if n.Left.Type != nil && n.Left.Type.NotInHeap() && n.Left.Name.Param.Pragma&NotInHeap == 0 {
   2109 			// The type contains go:notinheap types, so it
   2110 			// must be marked as such (alternatively, we
   2111 			// could silently propagate go:notinheap).
   2112 			yyerror("type %v must be go:notinheap", n.Left.Type)
   2113 		}
   2114 	}
   2115 
   2116 	t := n.Type
   2117 	if t != nil && !t.IsFuncArgStruct() && n.Op != OTYPE {
   2118 		switch t.Etype {
   2119 		case TFUNC, // might have TANY; wait until it's called
   2120 			TANY, TFORW, TIDEAL, TNIL, TBLANK:
   2121 			break
   2122 
   2123 		default:
   2124 			checkwidth(t)
   2125 		}
   2126 	}
   2127 
   2128 	if safemode && !inimport && !compiling_wrappers && t != nil && t.Etype == TUNSAFEPTR {
   2129 		yyerror("cannot use unsafe.Pointer")
   2130 	}
   2131 
   2132 	evconst(n)
   2133 	if n.Op == OTYPE && top&Etype == 0 {
   2134 		if !n.Type.Broke() {
   2135 			yyerror("type %v is not an expression", n.Type)
   2136 		}
   2137 		n.Type = nil
   2138 		return n
   2139 	}
   2140 
   2141 	if top&(Erv|Etype) == Etype && n.Op != OTYPE {
   2142 		yyerror("%v is not a type", n)
   2143 		n.Type = nil
   2144 		return n
   2145 	}
   2146 
   2147 	// TODO(rsc): simplify
   2148 	if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 {
   2149 		yyerror("%v used as value", n)
   2150 		n.Type = nil
   2151 		return n
   2152 	}
   2153 
   2154 	if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 {
   2155 		if !n.Diag() {
   2156 			yyerror("%v evaluated but not used", n)
   2157 			n.SetDiag(true)
   2158 		}
   2159 
   2160 		n.Type = nil
   2161 		return n
   2162 	}
   2163 
   2164 	return n
   2165 }
   2166 
   2167 func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
   2168 	t := r.Type
   2169 	if t == nil {
   2170 		return false
   2171 	}
   2172 	if !t.IsInteger() {
   2173 		yyerror("invalid slice index %v (type %v)", r, t)
   2174 		return false
   2175 	}
   2176 
   2177 	if r.Op == OLITERAL {
   2178 		if r.Int64() < 0 {
   2179 			yyerror("invalid slice index %v (index must be non-negative)", r)
   2180 			return false
   2181 		} else if tp != nil && tp.NumElem() >= 0 && r.Int64() > tp.NumElem() {
   2182 			yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
   2183 			return false
   2184 		} else if Isconst(l, CTSTR) && r.Int64() > int64(len(l.Val().U.(string))) {
   2185 			yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.Val().U.(string)))
   2186 			return false
   2187 		} else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
   2188 			yyerror("invalid slice index %v (index too large)", r)
   2189 			return false
   2190 		}
   2191 	}
   2192 
   2193 	return true
   2194 }
   2195 
   2196 func checksliceconst(lo *Node, hi *Node) bool {
   2197 	if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && lo.Val().U.(*Mpint).Cmp(hi.Val().U.(*Mpint)) > 0 {
   2198 		yyerror("invalid slice index: %v > %v", lo, hi)
   2199 		return false
   2200 	}
   2201 
   2202 	return true
   2203 }
   2204 
   2205 func checkdefergo(n *Node) {
   2206 	what := "defer"
   2207 	if n.Op == OPROC {
   2208 		what = "go"
   2209 	}
   2210 
   2211 	switch n.Left.Op {
   2212 	// ok
   2213 	case OCALLINTER,
   2214 		OCALLMETH,
   2215 		OCALLFUNC,
   2216 		OCLOSE,
   2217 		OCOPY,
   2218 		ODELETE,
   2219 		OPANIC,
   2220 		OPRINT,
   2221 		OPRINTN,
   2222 		ORECOVER:
   2223 		return
   2224 
   2225 	case OAPPEND,
   2226 		OCAP,
   2227 		OCOMPLEX,
   2228 		OIMAG,
   2229 		OLEN,
   2230 		OMAKE,
   2231 		OMAKESLICE,
   2232 		OMAKECHAN,
   2233 		OMAKEMAP,
   2234 		ONEW,
   2235 		OREAL,
   2236 		OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
   2237 		if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
   2238 			break
   2239 		}
   2240 		yyerror("%s discards result of %v", what, n.Left)
   2241 		return
   2242 	}
   2243 
   2244 	// type is broken or missing, most likely a method call on a broken type
   2245 	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
   2246 	if n.Left.Type == nil || n.Left.Type.Broke() {
   2247 		return
   2248 	}
   2249 
   2250 	if !n.Diag() {
   2251 		// The syntax made sure it was a call, so this must be
   2252 		// a conversion.
   2253 		n.SetDiag(true)
   2254 		yyerror("%s requires function call, not conversion", what)
   2255 	}
   2256 }
   2257 
   2258 // The result of implicitstar MUST be assigned back to n, e.g.
   2259 // 	n.Left = implicitstar(n.Left)
   2260 func implicitstar(n *Node) *Node {
   2261 	// insert implicit * if needed for fixed array
   2262 	t := n.Type
   2263 	if t == nil || !t.IsPtr() {
   2264 		return n
   2265 	}
   2266 	t = t.Elem()
   2267 	if t == nil {
   2268 		return n
   2269 	}
   2270 	if !t.IsArray() {
   2271 		return n
   2272 	}
   2273 	n = nod(OIND, n, nil)
   2274 	n.SetImplicit(true)
   2275 	n = typecheck(n, Erv)
   2276 	return n
   2277 }
   2278 
   2279 func onearg(n *Node, f string, args ...interface{}) bool {
   2280 	if n.Left != nil {
   2281 		return true
   2282 	}
   2283 	if n.List.Len() == 0 {
   2284 		p := fmt.Sprintf(f, args...)
   2285 		yyerror("missing argument to %s: %v", p, n)
   2286 		return false
   2287 	}
   2288 
   2289 	if n.List.Len() > 1 {
   2290 		p := fmt.Sprintf(f, args...)
   2291 		yyerror("too many arguments to %s: %v", p, n)
   2292 		n.Left = n.List.First()
   2293 		n.List.Set(nil)
   2294 		return false
   2295 	}
   2296 
   2297 	n.Left = n.List.First()
   2298 	n.List.Set(nil)
   2299 	return true
   2300 }
   2301 
   2302 func twoarg(n *Node) bool {
   2303 	if n.Left != nil {
   2304 		return true
   2305 	}
   2306 	if n.List.Len() == 0 {
   2307 		yyerror("missing argument to %v - %v", n.Op, n)
   2308 		return false
   2309 	}
   2310 
   2311 	n.Left = n.List.First()
   2312 	if n.List.Len() == 1 {
   2313 		yyerror("missing argument to %v - %v", n.Op, n)
   2314 		n.List.Set(nil)
   2315 		return false
   2316 	}
   2317 
   2318 	if n.List.Len() > 2 {
   2319 		yyerror("too many arguments to %v - %v", n.Op, n)
   2320 		n.List.Set(nil)
   2321 		return false
   2322 	}
   2323 
   2324 	n.Right = n.List.Second()
   2325 	n.List.Set(nil)
   2326 	return true
   2327 }
   2328 
   2329 func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
   2330 	var r *types.Field
   2331 	for _, f := range fs.Slice() {
   2332 		if dostrcmp != 0 && f.Sym.Name == s.Name {
   2333 			return f
   2334 		}
   2335 		if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
   2336 			return f
   2337 		}
   2338 		if f.Sym != s {
   2339 			continue
   2340 		}
   2341 		if r != nil {
   2342 			if errnode != nil {
   2343 				yyerror("ambiguous selector %v", errnode)
   2344 			} else if t.IsPtr() {
   2345 				yyerror("ambiguous selector (%v).%v", t, s)
   2346 			} else {
   2347 				yyerror("ambiguous selector %v.%v", t, s)
   2348 			}
   2349 			break
   2350 		}
   2351 
   2352 		r = f
   2353 	}
   2354 
   2355 	return r
   2356 }
   2357 
   2358 func looktypedot(n *Node, t *types.Type, dostrcmp int) bool {
   2359 	s := n.Sym
   2360 
   2361 	if t.IsInterface() {
   2362 		f1 := lookdot1(n, s, t, t.Fields(), dostrcmp)
   2363 		if f1 == nil {
   2364 			return false
   2365 		}
   2366 
   2367 		n.Sym = methodsym(n.Sym, t, false)
   2368 		n.Xoffset = f1.Offset
   2369 		n.Type = f1.Type
   2370 		n.Op = ODOTINTER
   2371 		return true
   2372 	}
   2373 
   2374 	// Find the base type: methtype will fail if t
   2375 	// is not of the form T or *T.
   2376 	mt := methtype(t)
   2377 	if mt == nil {
   2378 		return false
   2379 	}
   2380 
   2381 	expandmeth(mt)
   2382 	f2 := lookdot1(n, s, mt, mt.AllMethods(), dostrcmp)
   2383 	if f2 == nil {
   2384 		return false
   2385 	}
   2386 
   2387 	// disallow T.m if m requires *T receiver
   2388 	if f2.Type.Recv().Type.IsPtr() && !t.IsPtr() && f2.Embedded != 2 && !isifacemethod(f2.Type) {
   2389 		yyerror("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, f2.Sym)
   2390 		return false
   2391 	}
   2392 
   2393 	n.Sym = methodsym(n.Sym, t, false)
   2394 	n.Xoffset = f2.Offset
   2395 	n.Type = f2.Type
   2396 	n.Op = ODOTMETH
   2397 	return true
   2398 }
   2399 
   2400 func derefall(t *types.Type) *types.Type {
   2401 	for t != nil && t.Etype == types.Tptr {
   2402 		t = t.Elem()
   2403 	}
   2404 	return t
   2405 }
   2406 
   2407 type typeSymKey struct {
   2408 	t *types.Type
   2409 	s *types.Sym
   2410 }
   2411 
   2412 // dotField maps (*types.Type, *types.Sym) pairs to the corresponding struct field (*types.Type with Etype==TFIELD).
   2413 // It is a cache for use during usefield in walk.go, only enabled when field tracking.
   2414 var dotField = map[typeSymKey]*types.Field{}
   2415 
   2416 func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
   2417 	s := n.Sym
   2418 
   2419 	dowidth(t)
   2420 	var f1 *types.Field
   2421 	if t.IsStruct() || t.IsInterface() {
   2422 		f1 = lookdot1(n, s, t, t.Fields(), dostrcmp)
   2423 	}
   2424 
   2425 	var f2 *types.Field
   2426 	if n.Left.Type == t || n.Left.Type.Sym == nil {
   2427 		mt := methtype(t)
   2428 		if mt != nil {
   2429 			f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp)
   2430 		}
   2431 	}
   2432 
   2433 	if f1 != nil {
   2434 		if dostrcmp > 1 {
   2435 			// Already in the process of diagnosing an error.
   2436 			return f1
   2437 		}
   2438 		if f2 != nil {
   2439 			yyerror("%v is both field and method", n.Sym)
   2440 		}
   2441 		if f1.Offset == BADWIDTH {
   2442 			Fatalf("lookdot badwidth %v %p", f1, f1)
   2443 		}
   2444 		n.Xoffset = f1.Offset
   2445 		n.Type = f1.Type
   2446 		if objabi.Fieldtrack_enabled > 0 {
   2447 			dotField[typeSymKey{t.Orig, s}] = f1
   2448 		}
   2449 		if t.IsInterface() {
   2450 			if n.Left.Type.IsPtr() {
   2451 				n.Left = nod(OIND, n.Left, nil) // implicitstar
   2452 				n.Left.SetImplicit(true)
   2453 				n.Left = typecheck(n.Left, Erv)
   2454 			}
   2455 
   2456 			n.Op = ODOTINTER
   2457 		}
   2458 
   2459 		return f1
   2460 	}
   2461 
   2462 	if f2 != nil {
   2463 		if dostrcmp > 1 {
   2464 			// Already in the process of diagnosing an error.
   2465 			return f2
   2466 		}
   2467 		tt := n.Left.Type
   2468 		dowidth(tt)
   2469 		rcvr := f2.Type.Recv().Type
   2470 		if !eqtype(rcvr, tt) {
   2471 			if rcvr.Etype == types.Tptr && eqtype(rcvr.Elem(), tt) {
   2472 				checklvalue(n.Left, "call pointer method on")
   2473 				n.Left = nod(OADDR, n.Left, nil)
   2474 				n.Left.SetImplicit(true)
   2475 				n.Left = typecheck(n.Left, Etype|Erv)
   2476 			} else if tt.Etype == types.Tptr && rcvr.Etype != types.Tptr && eqtype(tt.Elem(), rcvr) {
   2477 				n.Left = nod(OIND, n.Left, nil)
   2478 				n.Left.SetImplicit(true)
   2479 				n.Left = typecheck(n.Left, Etype|Erv)
   2480 			} else if tt.Etype == types.Tptr && tt.Elem().Etype == types.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 == types.Tptr {
   2483 					// Stop one level early for method with pointer receiver.
   2484 					if rcvr.Etype == types.Tptr && tt.Elem().Etype != types.Tptr {
   2485 						break
   2486 					}
   2487 					n.Left = nod(OIND, n.Left, nil)
   2488 					n.Left.SetImplicit(true)
   2489 					n.Left = typecheck(n.Left, Etype|Erv)
   2490 					tt = tt.Elem()
   2491 				}
   2492 			} else {
   2493 				Fatalf("method mismatch: %v for %v", rcvr, tt)
   2494 			}
   2495 		}
   2496 
   2497 		pll := n
   2498 		ll := n.Left
   2499 		for ll.Left != nil && (ll.Op == ODOT || ll.Op == ODOTPTR || ll.Op == OIND) {
   2500 			pll = ll
   2501 			ll = ll.Left
   2502 		}
   2503 		if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && asNode(ll.Type.Sym.Def) != nil && asNode(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.
   2506 			n.Left = ll
   2507 			return nil
   2508 		}
   2509 
   2510 		n.Sym = methodsym(n.Sym, n.Left.Type, false)
   2511 		n.Xoffset = f2.Offset
   2512 		n.Type = f2.Type
   2513 
   2514 		n.Op = ODOTMETH
   2515 
   2516 		return f2
   2517 	}
   2518 
   2519 	return nil
   2520 }
   2521 
   2522 func nokeys(l Nodes) bool {
   2523 	for _, n := range l.Slice() {
   2524 		if n.Op == OKEY || n.Op == OSTRUCTKEY {
   2525 			return false
   2526 		}
   2527 	}
   2528 	return true
   2529 }
   2530 
   2531 func hasddd(t *types.Type) bool {
   2532 	for _, tl := range t.Fields().Slice() {
   2533 		if tl.Isddd() {
   2534 			return true
   2535 		}
   2536 	}
   2537 
   2538 	return false
   2539 }
   2540 
   2541 // typecheck assignment: type list = expression list
   2542 func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, desc func() string) {
   2543 	var t *types.Type
   2544 	var n1 int
   2545 	var n2 int
   2546 	var i int
   2547 
   2548 	lno := lineno
   2549 	defer func() { lineno = lno }()
   2550 
   2551 	if tstruct.Broke() {
   2552 		return
   2553 	}
   2554 
   2555 	var n *Node
   2556 	if nl.Len() == 1 {
   2557 		n = nl.First()
   2558 		if n.Type != nil && n.Type.IsFuncArgStruct() {
   2559 			if !hasddd(tstruct) {
   2560 				n1 := tstruct.NumFields()
   2561 				n2 := n.Type.NumFields()
   2562 				if n2 > n1 {
   2563 					goto toomany
   2564 				}
   2565 				if n2 < n1 {
   2566 					goto notenough
   2567 				}
   2568 			}
   2569 
   2570 			lfs := tstruct.FieldSlice()
   2571 			rfs := n.Type.FieldSlice()
   2572 			var why string
   2573 			for i, tl := range lfs {
   2574 				if tl.Isddd() {
   2575 					for _, tn := range rfs[i:] {
   2576 						if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
   2577 							if call != nil {
   2578 								yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
   2579 							} else {
   2580 								yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why)
   2581 							}
   2582 						}
   2583 					}
   2584 					return
   2585 				}
   2586 
   2587 				if i >= len(rfs) {
   2588 					goto notenough
   2589 				}
   2590 				tn := rfs[i]
   2591 				if assignop(tn.Type, tl.Type, &why) == 0 {
   2592 					if call != nil {
   2593 						yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
   2594 					} else {
   2595 						yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
   2596 					}
   2597 				}
   2598 			}
   2599 
   2600 			if len(rfs) > len(lfs) {
   2601 				goto toomany
   2602 			}
   2603 			return
   2604 		}
   2605 	}
   2606 
   2607 	n1 = tstruct.NumFields()
   2608 	n2 = nl.Len()
   2609 	if !hasddd(tstruct) {
   2610 		if n2 > n1 {
   2611 			goto toomany
   2612 		}
   2613 		if n2 < n1 {
   2614 			goto notenough
   2615 		}
   2616 	} else {
   2617 		if !isddd {
   2618 			if n2 < n1-1 {
   2619 				goto notenough
   2620 			}
   2621 		} else {
   2622 			if n2 > n1 {
   2623 				goto toomany
   2624 			}
   2625 			if n2 < n1 {
   2626 				goto notenough
   2627 			}
   2628 		}
   2629 	}
   2630 
   2631 	i = 0
   2632 	for _, tl := range tstruct.Fields().Slice() {
   2633 		t = tl.Type
   2634 		if tl.Isddd() {
   2635 			if isddd {
   2636 				if i >= nl.Len() {
   2637 					goto notenough
   2638 				}
   2639 				if nl.Len()-i > 1 {
   2640 					goto toomany
   2641 				}
   2642 				n = nl.Index(i)
   2643 				setlineno(n)
   2644 				if n.Type != nil {
   2645 					nl.SetIndex(i, assignconvfn(n, t, desc))
   2646 				}
   2647 				return
   2648 			}
   2649 
   2650 			for ; i < nl.Len(); i++ {
   2651 				n = nl.Index(i)
   2652 				setlineno(n)
   2653 				if n.Type != nil {
   2654 					nl.SetIndex(i, assignconvfn(n, t.Elem(), desc))
   2655 				}
   2656 			}
   2657 			return
   2658 		}
   2659 
   2660 		if i >= nl.Len() {
   2661 			goto notenough
   2662 		}
   2663 		n = nl.Index(i)
   2664 		setlineno(n)
   2665 		if n.Type != nil {
   2666 			nl.SetIndex(i, assignconvfn(n, t, desc))
   2667 		}
   2668 		i++
   2669 	}
   2670 
   2671 	if i < nl.Len() {
   2672 		goto toomany
   2673 	}
   2674 	if isddd {
   2675 		if call != nil {
   2676 			yyerror("invalid use of ... in call to %v", call)
   2677 		} else {
   2678 			yyerror("invalid use of ... in %v", op)
   2679 		}
   2680 	}
   2681 	return
   2682 
   2683 notenough:
   2684 	if n == nil || !n.Diag() {
   2685 		details := errorDetails(nl, tstruct, isddd)
   2686 		if call != nil {
   2687 			// call is the expression being called, not the overall call.
   2688 			// Method expressions have the form T.M, and the compiler has
   2689 			// rewritten those to ONAME nodes but left T in Left.
   2690 			if call.isMethodExpression() {
   2691 				yyerror("not enough arguments in call to method expression %v%s", call, details)
   2692 			} else {
   2693 				yyerror("not enough arguments in call to %v%s", call, details)
   2694 			}
   2695 		} else {
   2696 			yyerror("not enough arguments to %v%s", op, details)
   2697 		}
   2698 		if n != nil {
   2699 			n.SetDiag(true)
   2700 		}
   2701 	}
   2702 	return
   2703 
   2704 toomany:
   2705 	details := errorDetails(nl, tstruct, isddd)
   2706 	if call != nil {
   2707 		yyerror("too many arguments in call to %v%s", call, details)
   2708 	} else {
   2709 		yyerror("too many arguments to %v%s", op, details)
   2710 	}
   2711 }
   2712 
   2713 func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
   2714 	// If we don't know any type at a call site, let's suppress any return
   2715 	// message signatures. See Issue https://golang.org/issues/19012.
   2716 	if tstruct == nil {
   2717 		return ""
   2718 	}
   2719 	// If any node has an unknown type, suppress it as well
   2720 	for _, n := range nl.Slice() {
   2721 		if n.Type == nil {
   2722 			return ""
   2723 		}
   2724 	}
   2725 	return fmt.Sprintf("\n\thave %s\n\twant %v", nl.retsigerr(isddd), tstruct)
   2726 }
   2727 
   2728 // sigrepr is a type's representation to the outside world,
   2729 // in string representations of return signatures
   2730 // e.g in error messages about wrong arguments to return.
   2731 func sigrepr(t *types.Type) string {
   2732 	switch t {
   2733 	default:
   2734 		return t.String()
   2735 
   2736 	case types.Types[TIDEAL]:
   2737 		// "untyped number" is not commonly used
   2738 		// outside of the compiler, so let's use "number".
   2739 		return "number"
   2740 
   2741 	case types.Idealstring:
   2742 		return "string"
   2743 
   2744 	case types.Idealbool:
   2745 		return "bool"
   2746 	}
   2747 }
   2748 
   2749 // retsigerr returns the signature of the types
   2750 // at the respective return call site of a function.
   2751 func (nl Nodes) retsigerr(isddd bool) string {
   2752 	if nl.Len() < 1 {
   2753 		return "()"
   2754 	}
   2755 
   2756 	var typeStrings []string
   2757 	if nl.Len() == 1 && nl.First().Type != nil && nl.First().Type.IsFuncArgStruct() {
   2758 		for _, f := range nl.First().Type.Fields().Slice() {
   2759 			typeStrings = append(typeStrings, sigrepr(f.Type))
   2760 		}
   2761 	} else {
   2762 		for _, n := range nl.Slice() {
   2763 			typeStrings = append(typeStrings, sigrepr(n.Type))
   2764 		}
   2765 	}
   2766 
   2767 	ddd := ""
   2768 	if isddd {
   2769 		ddd = "..."
   2770 	}
   2771 	return fmt.Sprintf("(%s%s)", strings.Join(typeStrings, ", "), ddd)
   2772 }
   2773 
   2774 // type check composite
   2775 func fielddup(name string, hash map[string]bool) {
   2776 	if hash[name] {
   2777 		yyerror("duplicate field name in struct literal: %s", name)
   2778 		return
   2779 	}
   2780 	hash[name] = true
   2781 }
   2782 
   2783 func keydup(n *Node, hash map[uint32][]*Node) {
   2784 	orign := n
   2785 	if n.Op == OCONVIFACE {
   2786 		n = n.Left
   2787 	}
   2788 	evconst(n)
   2789 	if n.Op != OLITERAL {
   2790 		return // we don't check variables
   2791 	}
   2792 
   2793 	const PRIME1 = 3
   2794 
   2795 	var h uint32
   2796 	switch v := n.Val().U.(type) {
   2797 	default: // unknown, bool, nil
   2798 		h = 23
   2799 
   2800 	case *Mpint:
   2801 		h = uint32(v.Int64())
   2802 
   2803 	case *Mpflt:
   2804 		x := math.Float64bits(v.Float64())
   2805 		for i := 0; i < 8; i++ {
   2806 			h = h*PRIME1 + uint32(x&0xFF)
   2807 			x >>= 8
   2808 		}
   2809 
   2810 	case string:
   2811 		for i := 0; i < len(v); i++ {
   2812 			h = h*PRIME1 + uint32(v[i])
   2813 		}
   2814 	}
   2815 
   2816 	var cmp Node
   2817 	for _, a := range hash[h] {
   2818 		cmp.Op = OEQ
   2819 		cmp.Left = n
   2820 		if a.Op == OCONVIFACE && orign.Op == OCONVIFACE {
   2821 			a = a.Left
   2822 		}
   2823 		if !eqtype(a.Type, n.Type) {
   2824 			continue
   2825 		}
   2826 		cmp.Right = a
   2827 		evconst(&cmp)
   2828 		if cmp.Op != OLITERAL {
   2829 			// Sometimes evconst fails. See issue 12536.
   2830 			continue
   2831 		}
   2832 		if cmp.Val().U.(bool) {
   2833 			yyerror("duplicate key %v in map literal", n)
   2834 			return
   2835 		}
   2836 	}
   2837 
   2838 	hash[h] = append(hash[h], orign)
   2839 }
   2840 
   2841 // iscomptype reports whether type t is a composite literal type
   2842 // or a pointer to one.
   2843 func iscomptype(t *types.Type) bool {
   2844 	if t.IsPtr() {
   2845 		t = t.Elem()
   2846 	}
   2847 
   2848 	switch t.Etype {
   2849 	case TARRAY, TSLICE, TSTRUCT, TMAP:
   2850 		return true
   2851 	default:
   2852 		return false
   2853 	}
   2854 }
   2855 
   2856 func pushtype(n *Node, t *types.Type) {
   2857 	if n == nil || n.Op != OCOMPLIT || !iscomptype(t) {
   2858 		return
   2859 	}
   2860 
   2861 	if n.Right == nil {
   2862 		n.Right = typenod(t)
   2863 		n.SetImplicit(true)       // don't print
   2864 		n.Right.SetImplicit(true) // * is okay
   2865 	} else if Debug['s'] != 0 {
   2866 		n.Right = typecheck(n.Right, Etype)
   2867 		if n.Right.Type != nil && eqtype(n.Right.Type, t) {
   2868 			fmt.Printf("%v: redundant type: %v\n", n.Line(), t)
   2869 		}
   2870 	}
   2871 }
   2872 
   2873 // The result of typecheckcomplit MUST be assigned back to n, e.g.
   2874 // 	n.Left = typecheckcomplit(n.Left)
   2875 func typecheckcomplit(n *Node) *Node {
   2876 	lno := lineno
   2877 	defer func() {
   2878 		lineno = lno
   2879 	}()
   2880 
   2881 	if n.Right == nil {
   2882 		yyerrorl(n.Pos, "missing type in composite literal")
   2883 		n.Type = nil
   2884 		return n
   2885 	}
   2886 
   2887 	// Save original node (including n.Right)
   2888 	norig := nod(n.Op, nil, nil)
   2889 
   2890 	*norig = *n
   2891 
   2892 	setlineno(n.Right)
   2893 	n.Right = typecheck(n.Right, Etype|Ecomplit)
   2894 	l := n.Right // sic
   2895 	t := l.Type
   2896 	if t == nil {
   2897 		n.Type = nil
   2898 		return n
   2899 	}
   2900 	nerr := nerrors
   2901 	n.Type = t
   2902 
   2903 	if t.IsPtr() {
   2904 		// For better or worse, we don't allow pointers as the composite literal type,
   2905 		// except when using the &T syntax, which sets implicit on the OIND.
   2906 		if !n.Right.Implicit() {
   2907 			yyerror("invalid pointer type %v for composite literal (use &%v instead)", t, t.Elem())
   2908 			n.Type = nil
   2909 			return n
   2910 		}
   2911 
   2912 		// Also, the underlying type must be a struct, map, slice, or array.
   2913 		if !iscomptype(t) {
   2914 			yyerror("invalid pointer type %v for composite literal", t)
   2915 			n.Type = nil
   2916 			return n
   2917 		}
   2918 
   2919 		t = t.Elem()
   2920 	}
   2921 
   2922 	switch t.Etype {
   2923 	default:
   2924 		yyerror("invalid type for composite literal: %v", t)
   2925 		n.Type = nil
   2926 
   2927 	case TARRAY, TSLICE:
   2928 		// If there are key/value pairs, create a map to keep seen
   2929 		// keys so we can check for duplicate indices.
   2930 		var indices map[int64]bool
   2931 		for _, n1 := range n.List.Slice() {
   2932 			if n1.Op == OKEY {
   2933 				indices = make(map[int64]bool)
   2934 				break
   2935 			}
   2936 		}
   2937 
   2938 		var length, i int64
   2939 		checkBounds := t.IsArray() && !t.IsDDDArray()
   2940 		nl := n.List.Slice()
   2941 		for i2, l := range nl {
   2942 			setlineno(l)
   2943 			vp := &nl[i2]
   2944 			if l.Op == OKEY {
   2945 				l.Left = typecheck(l.Left, Erv)
   2946 				evconst(l.Left)
   2947 				i = nonnegintconst(l.Left)
   2948 				if i < 0 && !l.Left.Diag() {
   2949 					yyerror("index must be non-negative integer constant")
   2950 					l.Left.SetDiag(true)
   2951 					i = -(1 << 30) // stay negative for a while
   2952 				}
   2953 				vp = &l.Right
   2954 			}
   2955 
   2956 			if i >= 0 && indices != nil {
   2957 				if indices[i] {
   2958 					yyerror("duplicate index in array literal: %d", i)
   2959 				} else {
   2960 					indices[i] = true
   2961 				}
   2962 			}
   2963 
   2964 			r := *vp
   2965 			pushtype(r, t.Elem())
   2966 			r = typecheck(r, Erv)
   2967 			r = defaultlit(r, t.Elem())
   2968 			*vp = assignconv(r, t.Elem(), "array or slice literal")
   2969 
   2970 			i++
   2971 			if i > length {
   2972 				length = i
   2973 				if checkBounds && length > t.NumElem() {
   2974 					setlineno(l)
   2975 					yyerror("array index %d out of bounds [0:%d]", length-1, t.NumElem())
   2976 					checkBounds = false
   2977 				}
   2978 			}
   2979 		}
   2980 
   2981 		if t.IsDDDArray() {
   2982 			t.SetNumElem(length)
   2983 		}
   2984 		if t.IsSlice() {
   2985 			n.Right = nodintconst(length)
   2986 			n.Op = OSLICELIT
   2987 		} else {
   2988 			n.Op = OARRAYLIT
   2989 		}
   2990 
   2991 	case TMAP:
   2992 		hash := make(map[uint32][]*Node)
   2993 		for i3, l := range n.List.Slice() {
   2994 			setlineno(l)
   2995 			if l.Op != OKEY {
   2996 				n.List.SetIndex(i3, typecheck(l, Erv))
   2997 				yyerror("missing key in map literal")
   2998 				continue
   2999 			}
   3000 
   3001 			r := l.Left
   3002 			pushtype(r, t.Key())
   3003 			r = typecheck(r, Erv)
   3004 			r = defaultlit(r, t.Key())
   3005 			l.Left = assignconv(r, t.Key(), "map key")
   3006 			if l.Left.Op != OCONV {
   3007 				keydup(l.Left, hash)
   3008 			}
   3009 
   3010 			r = l.Right
   3011 			pushtype(r, t.Val())
   3012 			r = typecheck(r, Erv)
   3013 			r = defaultlit(r, t.Val())
   3014 			l.Right = assignconv(r, t.Val(), "map value")
   3015 		}
   3016 
   3017 		n.Op = OMAPLIT
   3018 
   3019 	case TSTRUCT:
   3020 		// Need valid field offsets for Xoffset below.
   3021 		dowidth(t)
   3022 
   3023 		errored := false
   3024 		if n.List.Len() != 0 && nokeys(n.List) {
   3025 			// simple list of variables
   3026 			ls := n.List.Slice()
   3027 			for i, n1 := range ls {
   3028 				setlineno(n1)
   3029 				n1 = typecheck(n1, Erv)
   3030 				ls[i] = n1
   3031 				if i >= t.NumFields() {
   3032 					if !errored {
   3033 						yyerror("too many values in struct initializer")
   3034 						errored = true
   3035 					}
   3036 					continue
   3037 				}
   3038 
   3039 				f := t.Field(i)
   3040 				s := f.Sym
   3041 				if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
   3042 					yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
   3043 				}
   3044 				// No pushtype allowed here. Must name fields for that.
   3045 				n1 = assignconv(n1, f.Type, "field value")
   3046 				n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
   3047 				n1.Xoffset = f.Offset
   3048 				ls[i] = n1
   3049 			}
   3050 			if len(ls) < t.NumFields() {
   3051 				yyerror("too few values in struct initializer")
   3052 			}
   3053 		} else {
   3054 			hash := make(map[string]bool)
   3055 
   3056 			// keyed list
   3057 			ls := n.List.Slice()
   3058 			for i, l := range ls {
   3059 				setlineno(l)
   3060 
   3061 				if l.Op == OKEY {
   3062 					key := l.Left
   3063 
   3064 					l.Op = OSTRUCTKEY
   3065 					l.Left = l.Right
   3066 					l.Right = nil
   3067 
   3068 					// An OXDOT uses the Sym field to hold
   3069 					// the field to the right of the dot,
   3070 					// so s will be non-nil, but an OXDOT
   3071 					// is never a valid struct literal key.
   3072 					if key.Sym == nil || key.Op == OXDOT || key.Sym.IsBlank() {
   3073 						yyerror("invalid field name %v in struct initializer", key)
   3074 						l.Left = typecheck(l.Left, Erv)
   3075 						continue
   3076 					}
   3077 
   3078 					// Sym might have resolved to name in other top-level
   3079 					// package, because of import dot. Redirect to correct sym
   3080 					// before we do the lookup.
   3081 					s := key.Sym
   3082 					if s.Pkg != localpkg && exportname(s.Name) {
   3083 						s1 := lookup(s.Name)
   3084 						if s1.Origpkg == s.Pkg {
   3085 							s = s1
   3086 						}
   3087 					}
   3088 					l.Sym = s
   3089 				}
   3090 
   3091 				if l.Op != OSTRUCTKEY {
   3092 					if !errored {
   3093 						yyerror("mixture of field:value and value initializers")
   3094 						errored = true
   3095 					}
   3096 					ls[i] = typecheck(ls[i], Erv)
   3097 					continue
   3098 				}
   3099 
   3100 				f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
   3101 				if f == nil {
   3102 					if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
   3103 						yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
   3104 					} else {
   3105 						yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
   3106 					}
   3107 					continue
   3108 				}
   3109 				fielddup(f.Sym.Name, hash)
   3110 				l.Xoffset = f.Offset
   3111 
   3112 				// No pushtype allowed here. Tried and rejected.
   3113 				l.Left = typecheck(l.Left, Erv)
   3114 				l.Left = assignconv(l.Left, f.Type, "field value")
   3115 			}
   3116 		}
   3117 
   3118 		n.Op = OSTRUCTLIT
   3119 	}
   3120 
   3121 	if nerr != nerrors {
   3122 		return n
   3123 	}
   3124 
   3125 	n.Orig = norig
   3126 	if n.Type.IsPtr() {
   3127 		n = nod(OPTRLIT, n, nil)
   3128 		n.SetTypecheck(1)
   3129 		n.Type = n.Left.Type
   3130 		n.Left.Type = t
   3131 		n.Left.SetTypecheck(1)
   3132 	}
   3133 
   3134 	n.Orig = norig
   3135 	return n
   3136 }
   3137 
   3138 // lvalue etc
   3139 func islvalue(n *Node) bool {
   3140 	switch n.Op {
   3141 	case OINDEX:
   3142 		if n.Left.Type != nil && n.Left.Type.IsArray() {
   3143 			return islvalue(n.Left)
   3144 		}
   3145 		if n.Left.Type != nil && n.Left.Type.IsString() {
   3146 			return false
   3147 		}
   3148 		fallthrough
   3149 	case OIND, ODOTPTR, OCLOSUREVAR:
   3150 		return true
   3151 
   3152 	case ODOT:
   3153 		return islvalue(n.Left)
   3154 
   3155 	case ONAME:
   3156 		if n.Class() == PFUNC {
   3157 			return false
   3158 		}
   3159 		return true
   3160 	}
   3161 
   3162 	return false
   3163 }
   3164 
   3165 func checklvalue(n *Node, verb string) {
   3166 	if !islvalue(n) {
   3167 		yyerror("cannot %s %v", verb, n)
   3168 	}
   3169 }
   3170 
   3171 func checkassign(stmt *Node, n *Node) {
   3172 	// Variables declared in ORANGE are assigned on every iteration.
   3173 	if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ORANGE {
   3174 		r := outervalue(n)
   3175 		var l *Node
   3176 		for l = n; l != r; l = l.Left {
   3177 			l.SetAssigned(true)
   3178 			if l.IsClosureVar() {
   3179 				l.Name.Defn.SetAssigned(true)
   3180 			}
   3181 		}
   3182 
   3183 		l.SetAssigned(true)
   3184 		if l.IsClosureVar() {
   3185 			l.Name.Defn.SetAssigned(true)
   3186 		}
   3187 	}
   3188 
   3189 	if islvalue(n) {
   3190 		return
   3191 	}
   3192 	if n.Op == OINDEXMAP {
   3193 		n.Etype = 1
   3194 		return
   3195 	}
   3196 
   3197 	// have already complained about n being invalid
   3198 	if n.Type == nil {
   3199 		return
   3200 	}
   3201 
   3202 	if n.Op == ODOT && n.Left.Op == OINDEXMAP {
   3203 		yyerror("cannot assign to struct field %v in map", n)
   3204 	} else {
   3205 		yyerror("cannot assign to %v", n)
   3206 	}
   3207 	n.Type = nil
   3208 }
   3209 
   3210 func checkassignlist(stmt *Node, l Nodes) {
   3211 	for _, n := range l.Slice() {
   3212 		checkassign(stmt, n)
   3213 	}
   3214 }
   3215 
   3216 // Check whether l and r are the same side effect-free expression,
   3217 // so that it is safe to reuse one instead of computing both.
   3218 func samesafeexpr(l *Node, r *Node) bool {
   3219 	if l.Op != r.Op || !eqtype(l.Type, r.Type) {
   3220 		return false
   3221 	}
   3222 
   3223 	switch l.Op {
   3224 	case ONAME, OCLOSUREVAR:
   3225 		return l == r
   3226 
   3227 	case ODOT, ODOTPTR:
   3228 		return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left)
   3229 
   3230 	case OIND, OCONVNOP:
   3231 		return samesafeexpr(l.Left, r.Left)
   3232 
   3233 	case OCONV:
   3234 		// Some conversions can't be reused, such as []byte(str).
   3235 		// Allow only numeric-ish types. This is a bit conservative.
   3236 		return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left)
   3237 
   3238 	case OINDEX:
   3239 		return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
   3240 
   3241 	case OLITERAL:
   3242 		return eqval(l.Val(), r.Val())
   3243 	}
   3244 
   3245 	return false
   3246 }
   3247 
   3248 // type check assignment.
   3249 // if this assignment is the definition of a var on the left side,
   3250 // fill in the var's type.
   3251 func typecheckas(n *Node) {
   3252 	// delicate little dance.
   3253 	// the definition of n may refer to this assignment
   3254 	// as its definition, in which case it will call typecheckas.
   3255 	// in that case, do not call typecheck back, or it will cycle.
   3256 	// if the variable has a type (ntype) then typechecking
   3257 	// will not look at defn, so it is okay (and desirable,
   3258 	// so that the conversion below happens).
   3259 	n.Left = resolve(n.Left)
   3260 
   3261 	if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil {
   3262 		n.Left = typecheck(n.Left, Erv|Easgn)
   3263 	}
   3264 
   3265 	n.Right = typecheck(n.Right, Erv)
   3266 	checkassign(n, n.Left)
   3267 	if n.Right != nil && n.Right.Type != nil {
   3268 		if n.Left.Type != nil {
   3269 			n.Right = assignconv(n.Right, n.Left.Type, "assignment")
   3270 		}
   3271 	}
   3272 
   3273 	if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
   3274 		n.Right = defaultlit(n.Right, nil)
   3275 		n.Left.Type = n.Right.Type
   3276 	}
   3277 
   3278 	// second half of dance.
   3279 	// now that right is done, typecheck the left
   3280 	// just to get it over with.  see dance above.
   3281 	n.SetTypecheck(1)
   3282 
   3283 	if n.Left.Typecheck() == 0 {
   3284 		n.Left = typecheck(n.Left, Erv|Easgn)
   3285 	}
   3286 	if !isblank(n.Left) {
   3287 		checkwidth(n.Left.Type) // ensure width is calculated for backend
   3288 	}
   3289 }
   3290 
   3291 func checkassignto(src *types.Type, dst *Node) {
   3292 	var why string
   3293 
   3294 	if assignop(src, dst.Type, &why) == 0 {
   3295 		yyerror("cannot assign %v to %L in multiple assignment%s", src, dst, why)
   3296 		return
   3297 	}
   3298 }
   3299 
   3300 func typecheckas2(n *Node) {
   3301 	ls := n.List.Slice()
   3302 	for i1, n1 := range ls {
   3303 		// delicate little dance.
   3304 		n1 = resolve(n1)
   3305 		ls[i1] = n1
   3306 
   3307 		if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil {
   3308 			ls[i1] = typecheck(ls[i1], Erv|Easgn)
   3309 		}
   3310 	}
   3311 
   3312 	cl := n.List.Len()
   3313 	cr := n.Rlist.Len()
   3314 	if cl > 1 && cr == 1 {
   3315 		n.Rlist.SetFirst(typecheck(n.Rlist.First(), Erv|Efnstruct))
   3316 	} else {
   3317 		typecheckslice(n.Rlist.Slice(), Erv)
   3318 	}
   3319 	checkassignlist(n, n.List)
   3320 
   3321 	var l *Node
   3322 	var r *Node
   3323 	if cl == cr {
   3324 		// easy
   3325 		ls := n.List.Slice()
   3326 		rs := n.Rlist.Slice()
   3327 		for il, nl := range ls {
   3328 			nr := rs[il]
   3329 			if nl.Type != nil && nr.Type != nil {
   3330 				rs[il] = assignconv(nr, nl.Type, "assignment")
   3331 			}
   3332 			if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil {
   3333 				rs[il] = defaultlit(rs[il], nil)
   3334 				nl.Type = rs[il].Type
   3335 			}
   3336 		}
   3337 
   3338 		goto out
   3339 	}
   3340 
   3341 	l = n.List.First()
   3342 	r = n.Rlist.First()
   3343 
   3344 	// x,y,z = f()
   3345 	if cr == 1 {
   3346 		if r.Type == nil {
   3347 			goto out
   3348 		}
   3349 		switch r.Op {
   3350 		case OCALLMETH, OCALLINTER, OCALLFUNC:
   3351 			if !r.Type.IsFuncArgStruct() {
   3352 				break
   3353 			}
   3354 			cr = r.Type.NumFields()
   3355 			if cr != cl {
   3356 				goto mismatch
   3357 			}
   3358 			n.Op = OAS2FUNC
   3359 			for i, l := range n.List.Slice() {
   3360 				f := r.Type.Field(i)
   3361 				if f.Type != nil && l.Type != nil {
   3362 					checkassignto(f.Type, l)
   3363 				}
   3364 				if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
   3365 					l.Type = f.Type
   3366 				}
   3367 			}
   3368 			goto out
   3369 		}
   3370 	}
   3371 
   3372 	// x, ok = y
   3373 	if cl == 2 && cr == 1 {
   3374 		if r.Type == nil {
   3375 			goto out
   3376 		}
   3377 		switch r.Op {
   3378 		case OINDEXMAP, ORECV, ODOTTYPE:
   3379 			switch r.Op {
   3380 			case OINDEXMAP:
   3381 				n.Op = OAS2MAPR
   3382 
   3383 			case ORECV:
   3384 				n.Op = OAS2RECV
   3385 
   3386 			case ODOTTYPE:
   3387 				n.Op = OAS2DOTTYPE
   3388 				r.Op = ODOTTYPE2
   3389 			}
   3390 
   3391 			if l.Type != nil {
   3392 				checkassignto(r.Type, l)
   3393 			}
   3394 			if l.Name != nil && l.Name.Defn == n {
   3395 				l.Type = r.Type
   3396 			}
   3397 			l := n.List.Second()
   3398 			if l.Type != nil && !l.Type.IsBoolean() {
   3399 				checkassignto(types.Types[TBOOL], l)
   3400 			}
   3401 			if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
   3402 				l.Type = types.Types[TBOOL]
   3403 			}
   3404 			goto out
   3405 		}
   3406 	}
   3407 
   3408 mismatch:
   3409 	yyerror("assignment mismatch: %d variables but %d values", cl, cr)
   3410 
   3411 	// second half of dance
   3412 out:
   3413 	n.SetTypecheck(1)
   3414 	ls = n.List.Slice()
   3415 	for i1, n1 := range ls {
   3416 		if n1.Typecheck() == 0 {
   3417 			ls[i1] = typecheck(ls[i1], Erv|Easgn)
   3418 		}
   3419 	}
   3420 }
   3421 
   3422 // type check function definition
   3423 func typecheckfunc(n *Node) {
   3424 	for _, ln := range n.Func.Dcl {
   3425 		if ln.Op == ONAME && (ln.Class() == PPARAM || ln.Class() == PPARAMOUT) {
   3426 			ln.Name.Decldepth = 1
   3427 		}
   3428 	}
   3429 
   3430 	n.Func.Nname = typecheck(n.Func.Nname, Erv|Easgn)
   3431 	t := n.Func.Nname.Type
   3432 	if t == nil {
   3433 		return
   3434 	}
   3435 	n.Type = t
   3436 	t.FuncType().Nname = asTypesNode(n.Func.Nname)
   3437 	rcvr := t.Recv()
   3438 	if rcvr != nil && n.Func.Shortname != nil {
   3439 		n.Func.Nname.Sym = methodname(n.Func.Shortname, rcvr.Type)
   3440 		declare(n.Func.Nname, PFUNC)
   3441 
   3442 		addmethod(n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
   3443 	}
   3444 
   3445 	if Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil {
   3446 		makefuncsym(n.Func.Nname.Sym)
   3447 	}
   3448 }
   3449 
   3450 // The result of stringtoarraylit MUST be assigned back to n, e.g.
   3451 // 	n.Left = stringtoarraylit(n.Left)
   3452 func stringtoarraylit(n *Node) *Node {
   3453 	if n.Left.Op != OLITERAL || n.Left.Val().Ctype() != CTSTR {
   3454 		Fatalf("stringtoarraylit %v", n)
   3455 	}
   3456 
   3457 	s := n.Left.Val().U.(string)
   3458 	var l []*Node
   3459 	if n.Type.Elem().Etype == TUINT8 {
   3460 		// []byte
   3461 		for i := 0; i < len(s); i++ {
   3462 			l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(s[0]))))
   3463 		}
   3464 	} else {
   3465 		// []rune
   3466 		i := 0
   3467 		for _, r := range s {
   3468 			l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
   3469 			i++
   3470 		}
   3471 	}
   3472 
   3473 	nn := nod(OCOMPLIT, nil, typenod(n.Type))
   3474 	nn.List.Set(l)
   3475 	nn = typecheck(nn, Erv)
   3476 	return nn
   3477 }
   3478 
   3479 var mapqueue []*Node
   3480 
   3481 func checkMapKeys() {
   3482 	for _, n := range mapqueue {
   3483 		k := n.Type.MapType().Key
   3484 		if !k.Broke() && !IsComparable(k) {
   3485 			yyerrorl(n.Pos, "invalid map key type %v", k)
   3486 		}
   3487 	}
   3488 	mapqueue = nil
   3489 }
   3490 
   3491 func copytype(n *Node, t *types.Type) {
   3492 	if t.Etype == TFORW {
   3493 		// This type isn't computed yet; when it is, update n.
   3494 		t.ForwardType().Copyto = append(t.ForwardType().Copyto, asTypesNode(n))
   3495 		return
   3496 	}
   3497 
   3498 	embedlineno := n.Type.ForwardType().Embedlineno
   3499 	l := n.Type.ForwardType().Copyto
   3500 
   3501 	ptrBase := n.Type.PtrBase
   3502 	sliceOf := n.Type.SliceOf
   3503 
   3504 	// TODO(mdempsky): Fix Type rekinding.
   3505 	*n.Type = *t
   3506 
   3507 	t = n.Type
   3508 	t.Sym = n.Sym
   3509 	if n.Name != nil {
   3510 		t.Vargen = n.Name.Vargen
   3511 	}
   3512 
   3513 	// spec: "The declared type does not inherit any methods bound
   3514 	// to the existing type, but the method set of an interface
   3515 	// type [...] remains unchanged."
   3516 	if !t.IsInterface() {
   3517 		*t.Methods() = types.Fields{}
   3518 		*t.AllMethods() = types.Fields{}
   3519 	}
   3520 
   3521 	t.Nod = asTypesNode(n)
   3522 	t.SetDeferwidth(false)
   3523 	t.PtrBase = ptrBase
   3524 	t.SliceOf = sliceOf
   3525 
   3526 	// Propagate go:notinheap pragma from the Name to the Type.
   3527 	if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma&NotInHeap != 0 {
   3528 		t.SetNotInHeap(true)
   3529 	}
   3530 
   3531 	// Update nodes waiting on this type.
   3532 	for _, n := range l {
   3533 		copytype(asNode(n), t)
   3534 	}
   3535 
   3536 	// Double-check use of type as embedded type.
   3537 	lno := lineno
   3538 
   3539 	if embedlineno.IsKnown() {
   3540 		lineno = embedlineno
   3541 		if t.IsPtr() || t.IsUnsafePtr() {
   3542 			yyerror("embedded type cannot be a pointer")
   3543 		}
   3544 	}
   3545 
   3546 	lineno = lno
   3547 }
   3548 
   3549 func typecheckdeftype(n *Node) {
   3550 	lno := lineno
   3551 	setlineno(n)
   3552 	n.Type.Sym = n.Sym
   3553 	n.SetTypecheck(1)
   3554 	n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
   3555 	t := n.Name.Param.Ntype.Type
   3556 	if t == nil {
   3557 		n.SetDiag(true)
   3558 		n.Type = nil
   3559 	} else if n.Type == nil {
   3560 		n.SetDiag(true)
   3561 	} else {
   3562 		// copy new type and clear fields
   3563 		// that don't come along.
   3564 		copytype(n, t)
   3565 	}
   3566 
   3567 	lineno = lno
   3568 }
   3569 
   3570 func typecheckdef(n *Node) {
   3571 	lno := lineno
   3572 	setlineno(n)
   3573 
   3574 	if n.Op == ONONAME {
   3575 		if !n.Diag() {
   3576 			n.SetDiag(true)
   3577 			if n.Pos.IsKnown() {
   3578 				lineno = n.Pos
   3579 			}
   3580 
   3581 			// Note: adderrorname looks for this string and
   3582 			// adds context about the outer expression
   3583 			yyerror("undefined: %v", n.Sym)
   3584 		}
   3585 
   3586 		return
   3587 	}
   3588 
   3589 	if n.Walkdef() == 1 {
   3590 		return
   3591 	}
   3592 
   3593 	typecheckdefstack = append(typecheckdefstack, n)
   3594 	if n.Walkdef() == 2 {
   3595 		flusherrors()
   3596 		fmt.Printf("typecheckdef loop:")
   3597 		for i := len(typecheckdefstack) - 1; i >= 0; i-- {
   3598 			n := typecheckdefstack[i]
   3599 			fmt.Printf(" %v", n.Sym)
   3600 		}
   3601 		fmt.Printf("\n")
   3602 		Fatalf("typecheckdef loop")
   3603 	}
   3604 
   3605 	n.SetWalkdef(2)
   3606 
   3607 	if n.Type != nil || n.Sym == nil { // builtin or no name
   3608 		goto ret
   3609 	}
   3610 
   3611 	switch n.Op {
   3612 	default:
   3613 		Fatalf("typecheckdef %v", n.Op)
   3614 
   3615 	case OGOTO, OLABEL, OPACK:
   3616 		// nothing to do here
   3617 
   3618 	case OLITERAL:
   3619 		if n.Name.Param.Ntype != nil {
   3620 			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
   3621 			n.Type = n.Name.Param.Ntype.Type
   3622 			n.Name.Param.Ntype = nil
   3623 			if n.Type == nil {
   3624 				n.SetDiag(true)
   3625 				goto ret
   3626 			}
   3627 		}
   3628 
   3629 		e := n.Name.Defn
   3630 		n.Name.Defn = nil
   3631 		if e == nil {
   3632 			lineno = n.Pos
   3633 			Dump("typecheckdef nil defn", n)
   3634 			yyerror("xxx")
   3635 		}
   3636 
   3637 		e = typecheck(e, Erv)
   3638 		if Isconst(e, CTNIL) {
   3639 			yyerror("const initializer cannot be nil")
   3640 			goto ret
   3641 		}
   3642 
   3643 		if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) {
   3644 			if !e.Diag() {
   3645 				yyerror("const initializer %v is not a constant", e)
   3646 				e.SetDiag(true)
   3647 			}
   3648 
   3649 			goto ret
   3650 		}
   3651 
   3652 		t := n.Type
   3653 		if t != nil {
   3654 			if !okforconst[t.Etype] {
   3655 				yyerror("invalid constant type %v", t)
   3656 				goto ret
   3657 			}
   3658 
   3659 			if !e.Type.IsUntyped() && !eqtype(t, e.Type) {
   3660 				yyerror("cannot use %L as type %v in const initializer", e, t)
   3661 				goto ret
   3662 			}
   3663 
   3664 			e = convlit(e, t)
   3665 		}
   3666 
   3667 		n.SetVal(e.Val())
   3668 		n.Type = e.Type
   3669 
   3670 	case ONAME:
   3671 		if n.Name.Param.Ntype != nil {
   3672 			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
   3673 			n.Type = n.Name.Param.Ntype.Type
   3674 			if n.Type == nil {
   3675 				n.SetDiag(true)
   3676 				goto ret
   3677 			}
   3678 		}
   3679 
   3680 		if n.Type != nil {
   3681 			break
   3682 		}
   3683 		if n.Name.Defn == nil {
   3684 			if n.Etype != 0 { // like OPRINTN
   3685 				break
   3686 			}
   3687 			if nsavederrors+nerrors > 0 {
   3688 				// Can have undefined variables in x := foo
   3689 				// that make x have an n.name.Defn == nil.
   3690 				// If there are other errors anyway, don't
   3691 				// bother adding to the noise.
   3692 				break
   3693 			}
   3694 
   3695 			Fatalf("var without type, init: %v", n.Sym)
   3696 		}
   3697 
   3698 		if n.Name.Defn.Op == ONAME {
   3699 			n.Name.Defn = typecheck(n.Name.Defn, Erv)
   3700 			n.Type = n.Name.Defn.Type
   3701 			break
   3702 		}
   3703 
   3704 		n.Name.Defn = typecheck(n.Name.Defn, Etop) // fills in n.Type
   3705 
   3706 	case OTYPE:
   3707 		if p := n.Name.Param; p.Alias {
   3708 			// Type alias declaration: Simply use the rhs type - no need
   3709 			// to create a new type.
   3710 			// If we have a syntax error, p.Ntype may be nil.
   3711 			if p.Ntype != nil {
   3712 				p.Ntype = typecheck(p.Ntype, Etype)
   3713 				n.Type = p.Ntype.Type
   3714 				if n.Type == nil {
   3715 					n.SetDiag(true)
   3716 					goto ret
   3717 				}
   3718 				n.Sym.Def = asTypesNode(p.Ntype)
   3719 			}
   3720 			break
   3721 		}
   3722 
   3723 		// regular type declaration
   3724 		if Curfn != nil {
   3725 			defercheckwidth()
   3726 		}
   3727 		n.SetWalkdef(1)
   3728 		n.Type = types.New(TFORW)
   3729 		n.Type.Nod = asTypesNode(n)
   3730 		n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
   3731 		nerrors0 := nerrors
   3732 		typecheckdeftype(n)
   3733 		if n.Type.Etype == TFORW && nerrors > nerrors0 {
   3734 			// Something went wrong during type-checking,
   3735 			// but it was reported. Silence future errors.
   3736 			n.Type.SetBroke(true)
   3737 		}
   3738 		if Curfn != nil {
   3739 			resumecheckwidth()
   3740 		}
   3741 	}
   3742 
   3743 ret:
   3744 	if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
   3745 		Fatalf("got %v for %v", n.Type, n)
   3746 	}
   3747 	last := len(typecheckdefstack) - 1
   3748 	if typecheckdefstack[last] != n {
   3749 		Fatalf("typecheckdefstack mismatch")
   3750 	}
   3751 	typecheckdefstack[last] = nil
   3752 	typecheckdefstack = typecheckdefstack[:last]
   3753 
   3754 	lineno = lno
   3755 	n.SetWalkdef(1)
   3756 }
   3757 
   3758 func checkmake(t *types.Type, arg string, n *Node) bool {
   3759 	if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
   3760 		yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
   3761 		return false
   3762 	}
   3763 
   3764 	// Do range checks for constants before defaultlit
   3765 	// to avoid redundant "constant NNN overflows int" errors.
   3766 	switch consttype(n) {
   3767 	case CTINT, CTRUNE, CTFLT, CTCPLX:
   3768 		n.SetVal(toint(n.Val()))
   3769 		if n.Val().U.(*Mpint).CmpInt64(0) < 0 {
   3770 			yyerror("negative %s argument in make(%v)", arg, t)
   3771 			return false
   3772 		}
   3773 		if n.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
   3774 			yyerror("%s argument too large in make(%v)", arg, t)
   3775 			return false
   3776 		}
   3777 	}
   3778 
   3779 	// defaultlit is necessary for non-constants too: n might be 1.1<<k.
   3780 	// TODO(gri) The length argument requirements for (array/slice) make
   3781 	// are the same as for index expressions. Factor the code better;
   3782 	// for instance, indexlit might be called here and incorporate some
   3783 	// of the bounds checks done for make.
   3784 	n = defaultlit(n, types.Types[TINT])
   3785 
   3786 	return true
   3787 }
   3788 
   3789 func markbreak(n *Node, implicit *Node) {
   3790 	if n == nil {
   3791 		return
   3792 	}
   3793 
   3794 	switch n.Op {
   3795 	case OBREAK:
   3796 		if n.Left == nil {
   3797 			if implicit != nil {
   3798 				implicit.SetHasBreak(true)
   3799 			}
   3800 		} else {
   3801 			lab := asNode(n.Left.Sym.Label)
   3802 			if lab != nil {
   3803 				lab.SetHasBreak(true)
   3804 			}
   3805 		}
   3806 	case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
   3807 		implicit = n
   3808 		fallthrough
   3809 	default:
   3810 		markbreak(n.Left, implicit)
   3811 		markbreak(n.Right, implicit)
   3812 		markbreaklist(n.Ninit, implicit)
   3813 		markbreaklist(n.Nbody, implicit)
   3814 		markbreaklist(n.List, implicit)
   3815 		markbreaklist(n.Rlist, implicit)
   3816 	}
   3817 }
   3818 
   3819 func markbreaklist(l Nodes, implicit *Node) {
   3820 	s := l.Slice()
   3821 	for i := 0; i < len(s); i++ {
   3822 		n := s[i]
   3823 		if n == nil {
   3824 			continue
   3825 		}
   3826 		if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
   3827 			switch n.Name.Defn.Op {
   3828 			case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
   3829 				n.Left.Sym.Label = asTypesNode(n.Name.Defn)
   3830 				markbreak(n.Name.Defn, n.Name.Defn)
   3831 				n.Left.Sym.Label = nil
   3832 				i++
   3833 				continue
   3834 			}
   3835 		}
   3836 
   3837 		markbreak(n, implicit)
   3838 	}
   3839 }
   3840 
   3841 // isterminating reports whether the Nodes list ends with a terminating statement.
   3842 func (l Nodes) isterminating() bool {
   3843 	s := l.Slice()
   3844 	c := len(s)
   3845 	if c == 0 {
   3846 		return false
   3847 	}
   3848 	return s[c-1].isterminating()
   3849 }
   3850 
   3851 // Isterminating reports whether the node n, the last one in a
   3852 // statement list, is a terminating statement.
   3853 func (n *Node) isterminating() bool {
   3854 	switch n.Op {
   3855 	// NOTE: OLABEL is treated as a separate statement,
   3856 	// not a separate prefix, so skipping to the last statement
   3857 	// in the block handles the labeled statement case by
   3858 	// skipping over the label. No case OLABEL here.
   3859 
   3860 	case OBLOCK:
   3861 		return n.List.isterminating()
   3862 
   3863 	case OGOTO, ORETURN, ORETJMP, OPANIC, OFALL:
   3864 		return true
   3865 
   3866 	case OFOR, OFORUNTIL:
   3867 		if n.Left != nil {
   3868 			return false
   3869 		}
   3870 		if n.HasBreak() {
   3871 			return false
   3872 		}
   3873 		return true
   3874 
   3875 	case OIF:
   3876 		return n.Nbody.isterminating() && n.Rlist.isterminating()
   3877 
   3878 	case OSWITCH, OTYPESW, OSELECT:
   3879 		if n.HasBreak() {
   3880 			return false
   3881 		}
   3882 		def := false
   3883 		for _, n1 := range n.List.Slice() {
   3884 			if !n1.Nbody.isterminating() {
   3885 				return false
   3886 			}
   3887 			if n1.List.Len() == 0 { // default
   3888 				def = true
   3889 			}
   3890 		}
   3891 
   3892 		if n.Op != OSELECT && !def {
   3893 			return false
   3894 		}
   3895 		return true
   3896 	}
   3897 
   3898 	return false
   3899 }
   3900 
   3901 // checkreturn makes sure that fn terminates appropriately.
   3902 func checkreturn(fn *Node) {
   3903 	if fn.Type.NumResults() != 0 && fn.Nbody.Len() != 0 {
   3904 		markbreaklist(fn.Nbody, nil)
   3905 		if !fn.Nbody.isterminating() {
   3906 			yyerrorl(fn.Func.Endlineno, "missing return at end of function")
   3907 		}
   3908 	}
   3909 }
   3910 
   3911 func deadcode(fn *Node) {
   3912 	deadcodeslice(fn.Nbody)
   3913 }
   3914 
   3915 func deadcodeslice(nn Nodes) {
   3916 	for _, n := range nn.Slice() {
   3917 		if n == nil {
   3918 			continue
   3919 		}
   3920 		if n.Op == OIF && Isconst(n.Left, CTBOOL) {
   3921 			if n.Left.Bool() {
   3922 				n.Rlist = Nodes{}
   3923 			} else {
   3924 				n.Nbody = Nodes{}
   3925 			}
   3926 		}
   3927 		deadcodeslice(n.Ninit)
   3928 		deadcodeslice(n.Nbody)
   3929 		deadcodeslice(n.List)
   3930 		deadcodeslice(n.Rlist)
   3931 	}
   3932 }
   3933