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