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