github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/cmd/compile/internal/gc/typecheck.go (about)

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