// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
 * type check the whole tree of an expression.
 * calculates expression types.
 * evaluates compile time constants.
 * marks variables that escape the local frame.
 * rewrites n->op to be more specific in some cases.
 */

#include <u.h>
#include <libc.h>
#include "go.h"

static void	implicitstar(Node**);
static int	onearg(Node*, char*, ...);
static int	twoarg(Node*);
static int	lookdot(Node*, Type*, int);
static int	looktypedot(Node*, Type*, int);
static void	typecheckaste(int, Node*, int, Type*, NodeList*, char*);
static Type*	lookdot1(Node*, Sym *s, Type *t, Type *f, int);
static int	nokeys(NodeList*);
static void	typecheckcomplit(Node**);
static void	typecheckas2(Node*);
static void	typecheckas(Node*);
static void	typecheckfunc(Node*);
static void	checklvalue(Node*, char*);
static void	checkassign(Node*);
static void	checkassignlist(NodeList*);
static void	stringtoarraylit(Node**);
static Node*	resolve(Node*);
static void	checkdefergo(Node*);
static int	checkmake(Type*, char*, Node*);
static int	checksliceindex(Node*, Type*);
static int	checksliceconst(Node*, Node*);

static	NodeList*	typecheckdefstack;

/*
 * resolve ONONAME to definition, if any.
 */
static Node*
resolve(Node *n)
{
	Node *r;

	if(n != N && n->op == ONONAME && n->sym != S && (r = n->sym->def) != N) {
		if(r->op != OIOTA)
			n = r;
		else if(n->iota >= 0)
			n = nodintconst(n->iota);
	}
	return n;
}

void
typechecklist(NodeList *l, int top)
{
	for(; l; l=l->next)
		typecheck(&l->n, top);
}

static char* _typekind[] = {
	[TINT]		= "int",
	[TUINT]		= "uint",
	[TINT8]		= "int8",
	[TUINT8]	= "uint8",
	[TINT16]	= "int16",
	[TUINT16]	= "uint16",
	[TINT32]	= "int32",
	[TUINT32]	= "uint32",
	[TINT64]	= "int64",
	[TUINT64]	= "uint64",
	[TUINTPTR]	= "uintptr",
	[TCOMPLEX64]	= "complex64",
	[TCOMPLEX128]	= "complex128",
	[TFLOAT32]	= "float32",
	[TFLOAT64]	= "float64",
	[TBOOL]		= "bool",
	[TSTRING]	= "string",
	[TPTR32]	= "pointer",
	[TPTR64]	= "pointer",
	[TUNSAFEPTR]	= "unsafe.Pointer",
	[TSTRUCT]	= "struct",
	[TINTER]	= "interface",
	[TCHAN]		= "chan",
	[TMAP]		= "map",
	[TARRAY]	= "array",
	[TFUNC]		= "func",
	[TNIL]		= "nil",
	[TIDEAL]	= "untyped number",
};

static char*
typekind(Type *t)
{
	int et;
	static char buf[50];
	char *s;
	
	if(isslice(t))
		return "slice";
	et = t->etype;
	if(0 <= et && et < nelem(_typekind) && (s=_typekind[et]) != nil)
		return s;
	snprint(buf, sizeof buf, "etype=%d", et);
	return buf;
}

/*
 * sprint_depchain prints a dependency chain
 * of nodes into fmt.
 * It is used by typecheck in the case of OLITERAL nodes
 * to print constant definition loops.
 */
static void
sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first)
{
	NodeList *l;

	for(l = stack; l; l=l->next) {
		if(l->n->op == cur->op) {
			if(l->n != first)
				sprint_depchain(fmt, l->next, l->n, first);
			fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur);
			return;
		}
	}
}

/*
 * type check node *np.
 * replaces *np with a new pointer in some cases.
 * returns the final value of *np as a convenience.
 */
static void typecheck1(Node **, int);
Node*
typecheck(Node **np, int top)
{
	Node *n;
	int lno;
	Fmt fmt;
	NodeList *l;
	static NodeList *tcstack, *tcfree;

	// cannot type check until all the source has been parsed
	if(!typecheckok)
		fatal("early typecheck");

	n = *np;
	if(n == N)
		return N;
	
	lno = setlineno(n);

	// Skip over parens.
	while(n->op == OPAREN)
		n = n->left;

	// Resolve definition of name and value of iota lazily.
	n = resolve(n);

	*np = n;

	// Skip typecheck if already done.
	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
	if(n->typecheck == 1) {
		switch(n->op) {
		case ONAME:
		case OTYPE:
		case OLITERAL:
		case OPACK:
			break;
		default:
			lineno = lno;
			return n;
		}
	}

	if(n->typecheck == 2) {
		// Typechecking loop. Trying printing a meaningful message,
		// otherwise a stack trace of typechecking.
		switch(n->op) {
		case ONAME:
			// We can already diagnose variables used as types.
			if((top & (Erv|Etype)) == Etype)
				yyerror("%N is not a type", n);
			break;
		case OLITERAL:
			if((top & (Erv|Etype)) == Etype) {
				yyerror("%N is not a type", n);
				break;
			}
			fmtstrinit(&fmt);
			sprint_depchain(&fmt, tcstack, n, n);
			yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt));
			break;
		}
		if(nsavederrors+nerrors == 0) {
			fmtstrinit(&fmt);
			for(l=tcstack; l; l=l->next)
				fmtprint(&fmt, "\n\t%L %N", l->n->lineno, l->n);
			yyerror("typechecking loop involving %N%s", n, fmtstrflush(&fmt));
		}
		lineno = lno;
		return n;
	}
	n->typecheck = 2;

	if(tcfree != nil) {
		l = tcfree;
		tcfree = l->next;
	} else
		l = mal(sizeof *l);
	l->next = tcstack;
	l->n = n;
	tcstack = l;

	typecheck1(&n, top);
	*np = n;
	n->typecheck = 1;

	if(tcstack != l)
		fatal("typecheck stack out of sync");
	tcstack = l->next;
	l->next = tcfree;
	tcfree = l;

	lineno = lno;
	return n;
}

/*
 * does n contain a call or receive operation?
 */
static int callrecvlist(NodeList*);

static int
callrecv(Node *n)
{
	if(n == nil)
		return 0;
	
	switch(n->op) {
	case OCALL:
	case OCALLMETH:
	case OCALLINTER:
	case OCALLFUNC:
	case ORECV:
	case OCAP:
	case OLEN:
	case OCOPY:
	case ONEW:
	case OAPPEND:
	case ODELETE:
		return 1;
	}

	return callrecv(n->left) ||
		callrecv(n->right) ||
		callrecv(n->ntest) ||
		callrecv(n->nincr) ||
		callrecvlist(n->ninit) ||
		callrecvlist(n->nbody) ||
		callrecvlist(n->nelse) ||
		callrecvlist(n->list) ||
		callrecvlist(n->rlist);
}

static int
callrecvlist(NodeList *l)
{
	for(; l; l=l->next)
		if(callrecv(l->n))
			return 1;
	return 0;
}

// indexlit implements typechecking of untyped values as
// array/slice indexes. It is equivalent to defaultlit
// except for constants of numerical kind, which are acceptable
// whenever they can be represented by a value of type int.
static void
indexlit(Node **np)
{
	Node *n;

	n = *np;
	if(n == N || !isideal(n->type))
		return;
	switch(consttype(n)) {
	case CTINT:
	case CTRUNE:
	case CTFLT:
	case CTCPLX:
		defaultlit(np, types[TINT]);
		break;
	}
	defaultlit(np, T);
}

static void
typecheck1(Node **np, int top)
{
	int et, aop, op, ptr;
	Node *n, *l, *r, *lo, *mid, *hi;
	NodeList *args;
	int ok, ntop;
	Type *t, *tp, *missing, *have, *badtype;
	Val v;
	char *why, *desc, descbuf[64];
	
	n = *np;

	if(n->sym) {
		if(n->op == ONAME && n->etype != 0 && !(top & Ecall)) {
			yyerror("use of builtin %S not in function call", n->sym);
			goto error;
		}

		typecheckdef(n);
		if(n->op == ONONAME)
			goto error;
	}
	*np = n;

reswitch:
	ok = 0;
	switch(n->op) {
	default:
		// until typecheck is complete, do nothing.
		dump("typecheck", n);
		fatal("typecheck %O", n->op);

	/*
	 * names
	 */
	case OLITERAL:
		ok |= Erv;
		if(n->type == T && n->val.ctype == CTSTR)
			n->type = idealstring;
		goto ret;

	case ONONAME:
		ok |= Erv;
		goto ret;

	case ONAME:
		if(n->etype != 0) {
			ok |= Ecall;
			goto ret;
		}
		if(!(top & Easgn)) {
			// not a write to the variable
			if(isblank(n)) {
				yyerror("cannot use _ as value");
				goto error;
			}
			n->used = 1;
		}
		if(!(top &Ecall) && isunsafebuiltin(n)) {
			yyerror("%N is not an expression, must be called", n);
			goto error;
		}
		ok |= Erv;
		goto ret;

	case OPACK:
		yyerror("use of package %S without selector", n->sym);
		goto error;

	case ODDD:
		break;

	/*
	 * types (OIND is with exprs)
	 */
	case OTYPE:
		ok |= Etype;
		if(n->type == T)
			goto error;
		break;

	case OTPAREN:
		ok |= Etype;
		l = typecheck(&n->left, Etype);
		if(l->type == T)
			goto error;
		n->op = OTYPE;
		n->type = l->type;
		n->left = N;
		break;
	
	case OTARRAY:
		ok |= Etype;
		t = typ(TARRAY);
		l = n->left;
		r = n->right;
		if(l == nil) {
			t->bound = -1;	// slice
		} else if(l->op == ODDD) {
			t->bound = -100;	// to be filled in
			if(!(top&Ecomplit) && !n->diag) {
				t->broke = 1;
				n->diag = 1;
				yyerror("use of [...] array outside of array literal");
			}
		} else {
			l = typecheck(&n->left, Erv);
			switch(consttype(l)) {
			case CTINT:
			case CTRUNE:
				v = l->val;
				break;
			case CTFLT:
				v = toint(l->val);
				break;
			default:
				yyerror("invalid array bound %N", l);
				goto error;
			}
			t->bound = mpgetfix(v.u.xval);
			if(doesoverflow(v, types[TINT])) {
				yyerror("array bound is too large"); 
				goto error;
			} else if(t->bound < 0) {
				yyerror("array bound must be non-negative");
				goto error;
			}
		}
		typecheck(&r, Etype);
		if(r->type == T)
			goto error;
		t->type = r->type;
		n->op = OTYPE;
		n->type = t;
		n->left = N;
		n->right = N;
		if(t->bound != -100)
			checkwidth(t);
		break;

	case OTMAP:
		ok |= Etype;
		l = typecheck(&n->left, Etype);
		r = typecheck(&n->right, Etype);
		if(l->type == T || r->type == T)
			goto error;
		n->op = OTYPE;
		n->type = maptype(l->type, r->type);
		n->left = N;
		n->right = N;
		break;

	case OTCHAN:
		ok |= Etype;
		l = typecheck(&n->left, Etype);
		if(l->type == T)
			goto error;
		t = typ(TCHAN);
		t->type = l->type;
		t->chan = n->etype;
		n->op = OTYPE;
		n->type = t;
		n->left = N;
		n->etype = 0;
		break;

	case OTSTRUCT:
		ok |= Etype;
		n->op = OTYPE;
		n->type = tostruct(n->list);
		if(n->type == T || n->type->broke)
			goto error;
		n->list = nil;
		break;

	case OTINTER:
		ok |= Etype;
		n->op = OTYPE;
		n->type = tointerface(n->list);
		if(n->type == T)
			goto error;
		break;

	case OTFUNC:
		ok |= Etype;
		n->op = OTYPE;
		n->type = functype(n->left, n->list, n->rlist);
		if(n->type == T)
			goto error;
		break;

	/*
	 * type or expr
	 */
	case OIND:
		ntop = Erv | Etype;
		if(!(top & Eaddr))  		// The *x in &*x is not an indirect.
			ntop |= Eindir;
		ntop |= top & Ecomplit;
		l = typecheck(&n->left, ntop);
		if((t = l->type) == T)
			goto error;
		if(l->op == OTYPE) {
			ok |= Etype;
			n->op = OTYPE;
			n->type = ptrto(l->type);
			n->left = N;
			goto ret;
		}
		if(!isptr[t->etype]) {
			if(top & (Erv | Etop)) {
				yyerror("invalid indirect of %lN", n->left);
				goto error;
			}
			goto ret;
		}
		ok |= Erv;
		n->type = t->type;
		goto ret;

	/*
	 * arithmetic exprs
	 */
	case OASOP:
		ok |= Etop;
		l = typecheck(&n->left, Erv);
		checkassign(n->left);
		r = typecheck(&n->right, Erv);
		if(l->type == T || r->type == T)
			goto error;
		op = n->etype;
		goto arith;

	case OADDPTR:
		ok |= Erv;
		l = typecheck(&n->left, Erv);
		r = typecheck(&n->right, Erv);
		if(l->type == T || r->type == T)
			goto error;
		if(l->type->etype != tptr)
			fatal("bad OADDPTR left type %E for %N", l->type->etype, n->left);
		if(r->type->etype != TUINTPTR)
			fatal("bad OADDPTR right type %E for %N", r->type->etype, n->right);
		n->type = types[tptr];
		goto ret;

	case OADD:
	case OAND:
	case OANDAND:
	case OANDNOT:
	case ODIV:
	case OEQ:
	case OGE:
	case OGT:
	case OLE:
	case OLT:
	case OLSH:
	case ORSH:
	case OMOD:
	case OMUL:
	case ONE:
	case OOR:
	case OOROR:
	case OSUB:
	case OXOR:
		ok |= Erv;
		l = typecheck(&n->left, Erv | (top & Eiota));
		r = typecheck(&n->right, Erv | (top & Eiota));
		if(l->type == T || r->type == T)
			goto error;
		op = n->op;
	arith:
		if(op == OLSH || op == ORSH)
			goto shift;
		// ideal mixed with non-ideal
		defaultlit2(&l, &r, 0);
		n->left = l;
		n->right = r;
		if(l->type == T || r->type == T)
			goto error;
		t = l->type;
		if(t->etype == TIDEAL)
			t = r->type;
		et = t->etype;
		if(et == TIDEAL)
			et = TINT;
		if(iscmp[n->op] && t->etype != TIDEAL && !eqtype(l->type, r->type)) {
			// comparison is okay as long as one side is
			// assignable to the other.  convert so they have
			// the same type.
			//
			// the only conversion that isn't a no-op is concrete == interface.
			// in that case, check comparability of the concrete type.
			if(r->type->etype != TBLANK && (aop = assignop(l->type, r->type, nil)) != 0) {
				if(isinter(r->type) && !isinter(l->type) && algtype1(l->type, nil) == ANOEQ) {
					yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(l->type));
					goto error;
				}
				l = nod(aop, l, N);
				l->type = r->type;
				l->typecheck = 1;
				n->left = l;
				t = l->type;
			} else if(l->type->etype != TBLANK && (aop = assignop(r->type, l->type, nil)) != 0) {
				if(isinter(l->type) && !isinter(r->type) && algtype1(r->type, nil) == ANOEQ) {
					yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(r->type));
					goto error;
				}
				r = nod(aop, r, N);
				r->type = l->type;
				r->typecheck = 1;
				n->right = r;
				t = r->type;
			}
			et = t->etype;
		}
		if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
			defaultlit2(&l, &r, 1);
			yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
			goto error;
		}
		if(!okfor[op][et]) {
			yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(t));
			goto error;
		}
		// okfor allows any array == array, map == map, func == func.
		// restrict to slice/map/func == nil and nil == slice/map/func.
		if(isfixedarray(l->type) && algtype1(l->type, nil) == ANOEQ) {
			yyerror("invalid operation: %N (%T cannot be compared)", n, l->type);
			goto error;
		}
		if(isslice(l->type) && !isnil(l) && !isnil(r)) {
			yyerror("invalid operation: %N (slice can only be compared to nil)", n);
			goto error;
		}
		if(l->type->etype == TMAP && !isnil(l) && !isnil(r)) {
			yyerror("invalid operation: %N (map can only be compared to nil)", n);
			goto error;
		}
		if(l->type->etype == TFUNC && !isnil(l) && !isnil(r)) {
			yyerror("invalid operation: %N (func can only be compared to nil)", n);
			goto error;
		}
		if(l->type->etype == TSTRUCT && algtype1(l->type, &badtype) == ANOEQ) {
			yyerror("invalid operation: %N (struct containing %T cannot be compared)", n, badtype);
			goto error;
		}
		
		t = l->type;
		if(iscmp[n->op]) {
			evconst(n);
			t = idealbool;
			if(n->op != OLITERAL) {
				defaultlit2(&l, &r, 1);
				n->left = l;
				n->right = r;
			}
		// non-comparison operators on ideal bools should make them lose their ideal-ness
		} else if(t == idealbool)
			t = types[TBOOL];

		if(et == TSTRING) {
			if(iscmp[n->op]) {
				n->etype = n->op;
				n->op = OCMPSTR;
			} else if(n->op == OADD) {
				// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
				n->op = OADDSTR;
				if(l->op == OADDSTR)
					n->list = l->list;
				else
					n->list = list1(l);
				if(r->op == OADDSTR)
					n->list = concat(n->list, r->list);
				else
					n->list = list(n->list, r);
				n->left = N;
				n->right = N;
			}
		}
		if(et == TINTER) {
			if(l->op == OLITERAL && l->val.ctype == CTNIL) {
				// swap for back end
				n->left = r;
				n->right = l;
			} else if(r->op == OLITERAL && r->val.ctype == CTNIL) {
				// leave alone for back end
			} else {
				n->etype = n->op;
				n->op = OCMPIFACE;
			}
		}

		if((op == ODIV || op == OMOD) && isconst(r, CTINT))
		if(mpcmpfixc(r->val.u.xval, 0) == 0) {
			yyerror("division by zero");
			goto error;
		} 

		n->type = t;
		goto ret;

	shift:
		defaultlit(&r, types[TUINT]);
		n->right = r;
		t = r->type;
		if(!isint[t->etype] || issigned[t->etype]) {
			yyerror("invalid operation: %N (shift count type %T, must be unsigned integer)", n, r->type);
			goto error;
		}
		t = l->type;
		if(t != T && t->etype != TIDEAL && !isint[t->etype]) {
			yyerror("invalid operation: %N (shift of type %T)", n, t);
			goto error;
		}
		// no defaultlit for left
		// the outer context gives the type
		n->type = l->type;
		goto ret;

	case OCOM:
	case OMINUS:
	case ONOT:
	case OPLUS:
		ok |= Erv;
		l = typecheck(&n->left, Erv | (top & Eiota));
		if((t = l->type) == T)
			goto error;
		if(!okfor[n->op][t->etype]) {
			yyerror("invalid operation: %O %T", n->op, t);
			goto error;
		}
		n->type = t;
		goto ret;

	/*
	 * exprs
	 */
	case OADDR:
		ok |= Erv;
		typecheck(&n->left, Erv | Eaddr);
		if(n->left->type == T)
			goto error;
		checklvalue(n->left, "take the address of");
		r = outervalue(n->left);
		for(l = n->left; l != r; l = l->left)
			l->addrtaken = 1;
		if(l->orig != l && l->op == ONAME)
			fatal("found non-orig name node %N", l);
		l->addrtaken = 1;
		defaultlit(&n->left, T);
		l = n->left;
		if((t = l->type) == T)
			goto error;
		// top&Eindir means this is &x in *&x.  (or the arg to built-in print)
		// n->etype means code generator flagged it as non-escaping.
		if(debug['N'] && !(top & Eindir) && !n->etype)
			addrescapes(n->left);
		n->type = ptrto(t);
		goto ret;

	case OCOMPLIT:
		ok |= Erv;
		typecheckcomplit(&n);
		if(n->type == T)
			goto error;
		goto ret;

	case OXDOT:
		n = adddot(n);
		n->op = ODOT;
		if(n->left == N)
			goto error;
		// fall through
	case ODOT:
		typecheck(&n->left, Erv|Etype);
		defaultlit(&n->left, T);
		if((t = n->left->type) == T)
			goto error;
		if(n->right->op != ONAME) {
			yyerror("rhs of . must be a name");	// impossible
			goto error;
		}
		r = n->right;

		if(n->left->op == OTYPE) {
			if(!looktypedot(n, t, 0)) {
				if(looktypedot(n, t, 1))
					yyerror("%N undefined (cannot refer to unexported method %S)", n, n->right->sym);
				else
					yyerror("%N undefined (type %T has no method %S)", n, t, n->right->sym);
				goto error;
			}
			if(n->type->etype != TFUNC || n->type->thistuple != 1) {
				yyerror("type %T has no method %hS", n->left->type, n->right->sym);
				n->type = T;
				goto error;
			}
			n->op = ONAME;
			n->sym = n->right->sym;
			n->type = methodfunc(n->type, n->left->type);
			n->xoffset = 0;
			n->class = PFUNC;
			ok = Erv;
			goto ret;
		}
		if(isptr[t->etype] && t->type->etype != TINTER) {
			t = t->type;
			if(t == T)
				goto error;
			n->op = ODOTPTR;
			checkwidth(t);
		}
		if(isblank(n->right)) {
			yyerror("cannot refer to blank field or method");
			goto error;
		}
		if(!lookdot(n, t, 0)) {
			if(lookdot(n, t, 1))
				yyerror("%N undefined (cannot refer to unexported field or method %S)", n, n->right->sym);
			else
				yyerror("%N undefined (type %T has no field or method %S)", n, n->left->type, n->right->sym);
			goto error;
		}
		switch(n->op) {
		case ODOTINTER:
		case ODOTMETH:
			if(top&Ecall)
				ok |= Ecall;
			else {
				typecheckpartialcall(n, r);
				ok |= Erv;
			}
			break;
		default:
			ok |= Erv;
			break;
		}
		goto ret;

	case ODOTTYPE:
		ok |= Erv;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, T);
		l = n->left;
		if((t = l->type) == T)
			goto error;
		if(!isinter(t)) {
			yyerror("invalid type assertion: %N (non-interface type %T on left)", n, t);
			goto error;
		}
		if(n->right != N) {
			typecheck(&n->right, Etype);
			n->type = n->right->type;
			n->right = N;
			if(n->type == T)
				goto error;
		}
		if(n->type != T && n->type->etype != TINTER)
		if(!implements(n->type, t, &missing, &have, &ptr)) {
			if(have && have->sym == missing->sym)
				yyerror("impossible type assertion:\n\t%T does not implement %T (wrong type for %S method)\n"
					"\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
					have->sym, have->type, missing->sym, missing->type);
			else if(ptr)
				yyerror("impossible type assertion:\n\t%T does not implement %T (%S method has pointer receiver)",
					n->type, t, missing->sym);
			else if(have)
				yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)\n"
					"\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
					have->sym, have->type, missing->sym, missing->type);
			else
				yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)",
					n->type, t, missing->sym);
			goto error;
		}
		goto ret;

	case OINDEX:
		ok |= Erv;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, T);
		implicitstar(&n->left);
		l = n->left;
		typecheck(&n->right, Erv);
		r = n->right;
		if((t = l->type) == T || r->type == T)
			goto error;
		switch(t->etype) {
		default:
			yyerror("invalid operation: %N (type %T does not support indexing)", n, t);
			goto error;


		case TSTRING:
		case TARRAY:
			indexlit(&n->right);
			if(t->etype == TSTRING)
				n->type = types[TUINT8];
			else
				n->type = t->type;
			why = "string";
			if(t->etype == TARRAY) {
				if(isfixedarray(t))
					why = "array";
				else
					why = "slice";
			}
			if(n->right->type != T && !isint[n->right->type->etype]) {
				yyerror("non-integer %s index %N", why, n->right);
				break;
			}
			if(isconst(n->right, CTINT)) {
				if(mpgetfix(n->right->val.u.xval) < 0)
					yyerror("invalid %s index %N (index must be non-negative)", why, n->right);
				else if(isfixedarray(t) && t->bound > 0 && mpgetfix(n->right->val.u.xval) >= t->bound)
					yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound);
				else if(isconst(n->left, CTSTR) && mpgetfix(n->right->val.u.xval) >= n->left->val.u.sval->len)
					yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len);
				else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
					yyerror("invalid %s index %N (index too large)", why, n->right);
			}
			break;

		case TMAP:
			n->etype = 0;
			defaultlit(&n->right, t->down);
			if(n->right->type != T)
				n->right = assignconv(n->right, t->down, "map index");
			n->type = t->type;
			n->op = OINDEXMAP;
			break;
		}
		goto ret;

	case ORECV:
		ok |= Etop | Erv;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, T);
		l = n->left;
		if((t = l->type) == T)
			goto error;
		if(t->etype != TCHAN) {
			yyerror("invalid operation: %N (receive from non-chan type %T)", n, t);
			goto error;
		}
		if(!(t->chan & Crecv)) {
			yyerror("invalid operation: %N (receive from send-only type %T)", n, t);
			goto error;
		}
		n->type = t->type;
		goto ret;

	case OSEND:
		ok |= Etop;
		l = typecheck(&n->left, Erv);
		typecheck(&n->right, Erv);
		defaultlit(&n->left, T);
		l = n->left;
		if((t = l->type) == T)
			goto error;
		if(t->etype != TCHAN) {
			yyerror("invalid operation: %N (send to non-chan type %T)", n, t);
			goto error;
		}
		if(!(t->chan & Csend)) {
			yyerror("invalid operation: %N (send to receive-only type %T)", n, t);
			goto error;
		}
		defaultlit(&n->right, t->type);
		r = n->right;
		if(r->type == T)
			goto error;
		n->right = assignconv(r, l->type->type, "send");
		// TODO: more aggressive
		n->etype = 0;
		n->type = T;
		goto ret;

	case OSLICE:
		ok |= Erv;
		typecheck(&n->left, top);
		typecheck(&n->right->left, Erv);
		typecheck(&n->right->right, Erv);
		defaultlit(&n->left, T);
		indexlit(&n->right->left);
		indexlit(&n->right->right);
		l = n->left;
		if(isfixedarray(l->type)) {
			if(!islvalue(n->left)) {
				yyerror("invalid operation %N (slice of unaddressable value)", n);
				goto error;
			}
			n->left = nod(OADDR, n->left, N);
			n->left->implicit = 1;
			typecheck(&n->left, Erv);
			l = n->left;
		}
		if((t = l->type) == T)
			goto error;
		tp = nil;
		if(istype(t, TSTRING)) {
			n->type = t;
			n->op = OSLICESTR;
		} else if(isptr[t->etype] && isfixedarray(t->type)) {
			tp = t->type;
			n->type = typ(TARRAY);
			n->type->type = tp->type;
			n->type->bound = -1;
			dowidth(n->type);
			n->op = OSLICEARR;
		} else if(isslice(t)) {
			n->type = t;
		} else {
			yyerror("cannot slice %N (type %T)", l, t);
			goto error;
		}
		if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0)
			goto error;
		if((hi = n->right->right) != N && checksliceindex(hi, tp) < 0)
			goto error;
		if(checksliceconst(lo, hi) < 0)
			goto error;
		goto ret;

	case OSLICE3:
		ok |= Erv;
		typecheck(&n->left, top);
		typecheck(&n->right->left, Erv);
		typecheck(&n->right->right->left, Erv);
		typecheck(&n->right->right->right, Erv);
		defaultlit(&n->left, T);
		indexlit(&n->right->left);
		indexlit(&n->right->right->left);
		indexlit(&n->right->right->right);
		l = n->left;
		if(isfixedarray(l->type)) {
			if(!islvalue(n->left)) {
				yyerror("invalid operation %N (slice of unaddressable value)", n);
				goto error;
			}
			n->left = nod(OADDR, n->left, N);
			n->left->implicit = 1;
			typecheck(&n->left, Erv);
			l = n->left;
		}
		if((t = l->type) == T)
			goto error;
		tp = nil;
		if(istype(t, TSTRING)) {
			yyerror("invalid operation %N (3-index slice of string)", n);
			goto error;
		}
		if(isptr[t->etype] && isfixedarray(t->type)) {
			tp = t->type;
			n->type = typ(TARRAY);
			n->type->type = tp->type;
			n->type->bound = -1;
			dowidth(n->type);
			n->op = OSLICE3ARR;
		} else if(isslice(t)) {
			n->type = t;
		} else {
			yyerror("cannot slice %N (type %T)", l, t);
			goto error;
		}
		if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0)
			goto error;
		if((mid = n->right->right->left) != N && checksliceindex(mid, tp) < 0)
			goto error;
		if((hi = n->right->right->right) != N && checksliceindex(hi, tp) < 0)
			goto error;
		if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0)
			goto error;
		goto ret;

	/*
	 * call and call like
	 */
	case OCALL:
		l = n->left;
		if(l->op == ONAME && (r = unsafenmagic(n)) != N) {
			if(n->isddd)
				yyerror("invalid use of ... with builtin %N", l);
			n = r;
			goto reswitch;
		}
		typecheck(&n->left, Erv | Etype | Ecall |(top&Eproc));
		n->diag |= n->left->diag;
		l = n->left;
		if(l->op == ONAME && l->etype != 0) {
			if(n->isddd && l->etype != OAPPEND)
				yyerror("invalid use of ... with builtin %N", l);
			// builtin: OLEN, OCAP, etc.
			n->op = l->etype;
			n->left = n->right;
			n->right = N;
			goto reswitch;
		}
		defaultlit(&n->left, T);
		l = n->left;
		if(l->op == OTYPE) {
			if(n->isddd || l->type->bound == -100) {
				if(!l->type->broke)
					yyerror("invalid use of ... in type conversion", l);
				n->diag = 1;
			}
			// pick off before type-checking arguments
			ok |= Erv;
			// turn CALL(type, arg) into CONV(arg) w/ type
			n->left = N;
			n->op = OCONV;
			n->type = l->type;
			if(onearg(n, "conversion to %T", l->type) < 0)
				goto error;
			goto doconv;
		}

		if(count(n->list) == 1 && !n->isddd)
			typecheck(&n->list->n, Erv | Efnstruct);
		else
			typechecklist(n->list, Erv);
		if((t = l->type) == T)
			goto error;
		checkwidth(t);

		switch(l->op) {
		case ODOTINTER:
			n->op = OCALLINTER;
			break;

		case ODOTMETH:
			n->op = OCALLMETH;
			// typecheckaste was used here but there wasn't enough
			// information further down the call chain to know if we
			// were testing a method receiver for unexported fields.
			// It isn't necessary, so just do a sanity check.
			tp = getthisx(t)->type->type;
			if(l->left == N || !eqtype(l->left->type, tp))
				fatal("method receiver");
			break;

		default:
			n->op = OCALLFUNC;
			if(t->etype != TFUNC) {
				yyerror("cannot call non-function %N (type %T)", l, t);
				goto error;
			}
			break;
		}
		if(snprint(descbuf, sizeof descbuf, "argument to %N", n->left) < sizeof descbuf)
			desc = descbuf;
		else
			desc = "function argument";
		typecheckaste(OCALL, n->left, n->isddd, getinargx(t), n->list, desc);
		ok |= Etop;
		if(t->outtuple == 0)
			goto ret;
		ok |= Erv;
		if(t->outtuple == 1) {
			t = getoutargx(l->type)->type;
			if(t == T)
				goto error;
			if(t->etype == TFIELD)
				t = t->type;
			n->type = t;
			goto ret;
		}
		// multiple return
		if(!(top & (Efnstruct | Etop))) {
			yyerror("multiple-value %N() in single-value context", l);
			goto ret;
		}
		n->type = getoutargx(l->type);
		goto ret;

	case OCAP:
	case OLEN:
	case OREAL:
	case OIMAG:
		ok |= Erv;
		if(onearg(n, "%O", n->op) < 0)
			goto error;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, T);
		implicitstar(&n->left);
		l = n->left;
		t = l->type;
		if(t == T)
			goto error;
		switch(n->op) {
		case OCAP:
			if(!okforcap[t->etype])
				goto badcall1;
			break;
		case OLEN:
			if(!okforlen[t->etype])
				goto badcall1;
			break;
		case OREAL:
		case OIMAG:
			if(!iscomplex[t->etype])
				goto badcall1;
			if(isconst(l, CTCPLX)){
				r = n;
				if(n->op == OREAL)
					n = nodfltconst(&l->val.u.cval->real);
				else
					n = nodfltconst(&l->val.u.cval->imag);
				n->orig = r;
			}
			n->type = types[cplxsubtype(t->etype)];
			goto ret;
		}
		// might be constant
		switch(t->etype) {
		case TSTRING:
			if(isconst(l, CTSTR)) {
				r = nod(OXXX, N, N);
				nodconst(r, types[TINT], l->val.u.sval->len);
				r->orig = n;
				n = r;
			}
			break;
		case TARRAY:
			if(t->bound < 0) // slice
				break;
			if(callrecv(l)) // has call or receive
				break;
			r = nod(OXXX, N, N);
			nodconst(r, types[TINT], t->bound);
			r->orig = n;
			n = r;
			break;
		}
		n->type = types[TINT];
		goto ret;

	case OCOMPLEX:
		ok |= Erv;
		if(count(n->list) == 1) {
			typechecklist(n->list, Efnstruct);
			t = n->list->n->left->type;
			if(t->outtuple != 2) {
				yyerror("invalid operation: complex expects two arguments, %N returns %d results", n->list->n, t->outtuple);
				goto error;
			}
			t = n->list->n->type->type;
			l = t->nname;
			r = t->down->nname;
		} else {
			if(twoarg(n) < 0)
				goto error;
			l = typecheck(&n->left, Erv | (top & Eiota));
			r = typecheck(&n->right, Erv | (top & Eiota));
			if(l->type == T || r->type == T)
				goto error;
			defaultlit2(&l, &r, 0);
			if(l->type == T || r->type == T)
				goto error;
			n->left = l;
			n->right = r;
		}
		if(!eqtype(l->type, r->type)) {
			yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
			goto error;
		}
		switch(l->type->etype) {
		default:
			yyerror("invalid operation: %N (arguments have type %T, expected floating-point)", n, l->type, r->type);
			goto error;
		case TIDEAL:
			t = types[TIDEAL];
			break;
		case TFLOAT32:
			t = types[TCOMPLEX64];
			break;
		case TFLOAT64:
			t = types[TCOMPLEX128];
			break;
		}
		if(l->op == OLITERAL && r->op == OLITERAL) {
			// make it a complex literal
			r = nodcplxlit(l->val, r->val);
			r->orig = n;
			n = r;
		}
		n->type = t;
		goto ret;

	case OCLOSE:
		if(onearg(n, "%O", n->op) < 0)
			goto error;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, T);
		l = n->left;
		if((t = l->type) == T)
			goto error;
		if(t->etype != TCHAN) {
			yyerror("invalid operation: %N (non-chan type %T)", n, t);
			goto error;
		}
		if(!(t->chan & Csend)) {
			yyerror("invalid operation: %N (cannot close receive-only channel)", n);
			goto error;
		}
		ok |= Etop;
		goto ret;

	case ODELETE:
		args = n->list;
		if(args == nil) {
			yyerror("missing arguments to delete");
			goto error;
		}
		if(args->next == nil) {
			yyerror("missing second (key) argument to delete");
			goto error;
		}
		if(args->next->next != nil) {
			yyerror("too many arguments to delete");
			goto error;
		}
		ok |= Etop;
		typechecklist(args, Erv);
		l = args->n;
		r = args->next->n;
		if(l->type != T && l->type->etype != TMAP) {
			yyerror("first argument to delete must be map; have %lT", l->type);
			goto error;
		}
		args->next->n = assignconv(r, l->type->down, "delete");
		goto ret;

	case OAPPEND:
		ok |= Erv;
		args = n->list;
		if(args == nil) {
			yyerror("missing arguments to append");
			goto error;
		}

		if(count(args) == 1 && !n->isddd)
			typecheck(&args->n, Erv | Efnstruct);
		else
			typechecklist(args, Erv);

		if((t = args->n->type) == T)
			goto error;

		// Unpack multiple-return result before type-checking.
		if(istype(t, TSTRUCT)) {
			t = t->type;
			if(istype(t, TFIELD))
				t = t->type;
		}

		n->type = t;
		if(!isslice(t)) {
			if(isconst(args->n, CTNIL)) {
				yyerror("first argument to append must be typed slice; have untyped nil", t);
				goto error;
			}
			yyerror("first argument to append must be slice; have %lT", t);
			goto error;
		}

		if(n->isddd) {
			if(args->next == nil) {
				yyerror("cannot use ... on first argument to append");
				goto error;
			}
			if(args->next->next != nil) {
				yyerror("too many arguments to append");
				goto error;
			}
			if(istype(t->type, TUINT8) && istype(args->next->n->type, TSTRING)) {
				defaultlit(&args->next->n, types[TSTRING]);
				goto ret;
			}
			args->next->n = assignconv(args->next->n, t->orig, "append");
			goto ret;
		}
		for(args=args->next; args != nil; args=args->next) {
			if(args->n->type == T)
				continue;
			args->n = assignconv(args->n, t->type, "append");
		}
		goto ret;

	case OCOPY:
		ok |= Etop|Erv;
		args = n->list;
		if(args == nil || args->next == nil) {
			yyerror("missing arguments to copy");
			goto error;
		}
		if(args->next->next != nil) {
			yyerror("too many arguments to copy");
			goto error;
		}
		n->left = args->n;
		n->right = args->next->n;
		n->list = nil;
		n->type = types[TINT];
		typecheck(&n->left, Erv);
		typecheck(&n->right, Erv);
		if(n->left->type == T || n->right->type == T)
			goto error;
		defaultlit(&n->left, T);
		defaultlit(&n->right, T);
		if(n->left->type == T || n->right->type == T)
			goto error;

		// copy([]byte, string)
		if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
			if(eqtype(n->left->type->type, bytetype))
				goto ret;
			yyerror("arguments to copy have different element types: %lT and string", n->left->type);
			goto error;
		}

		if(!isslice(n->left->type) || !isslice(n->right->type)) {
			if(!isslice(n->left->type) && !isslice(n->right->type))
				yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
			else if(!isslice(n->left->type))
				yyerror("first argument to copy should be slice; have %lT", n->left->type);
			else
				yyerror("second argument to copy should be slice or string; have %lT", n->right->type);
			goto error;
		}
		if(!eqtype(n->left->type->type, n->right->type->type)) {
			yyerror("arguments to copy have different element types: %lT and %lT", n->left->type, n->right->type);
			goto error;
		}
		goto ret;

	case OCONV:
	doconv:
		ok |= Erv;
		saveorignode(n);
		typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
		convlit1(&n->left, n->type, 1);
		if((t = n->left->type) == T || n->type == T)
			goto error;
		if((n->op = convertop(t, n->type, &why)) == 0) {
			if(!n->diag && !n->type->broke) {
				yyerror("cannot convert %lN to type %T%s", n->left, n->type, why);
				n->diag = 1;
			}
			n->op = OCONV;
		}
		switch(n->op) {
		case OCONVNOP:
			if(n->left->op == OLITERAL) {
				r = nod(OXXX, N, N);
				n->op = OCONV;
				n->orig = r;
				*r = *n;
				n->op = OLITERAL;
				n->val = n->left->val;
			}
			break;
		case OSTRARRAYBYTE:
			// do not use stringtoarraylit.
			// generated code and compiler memory footprint is better without it.
			break;
		case OSTRARRAYRUNE:
			if(n->left->op == OLITERAL)
				stringtoarraylit(&n);
			break;
		}
		goto ret;

	case OMAKE:
		ok |= Erv;
		args = n->list;
		if(args == nil) {
			yyerror("missing argument to make");
			goto error;
		}
		n->list = nil;
		l = args->n;
		args = args->next;
		typecheck(&l, Etype);
		if((t = l->type) == T)
			goto error;

		switch(t->etype) {
		default:
		badmake:
			yyerror("cannot make type %T", t);
			goto error;

		case TARRAY:
			if(!isslice(t))
				goto badmake;
			if(args == nil) {
				yyerror("missing len argument to make(%T)", t);
				goto error;
			}
			l = args->n;
			args = args->next;
			typecheck(&l, Erv);
			r = N;
			if(args != nil) {
				r = args->n;
				args = args->next;
				typecheck(&r, Erv);
			}
			if(l->type == T || (r && r->type == T))
				goto error;
			et = checkmake(t, "len", l) < 0;
			et |= r && checkmake(t, "cap", r) < 0;
			if(et)
				goto error;
			if(isconst(l, CTINT) && r && isconst(r, CTINT) && mpcmpfixfix(l->val.u.xval, r->val.u.xval) > 0) {
				yyerror("len larger than cap in make(%T)", t);
				goto error;
			}
			n->left = l;
			n->right = r;
			n->op = OMAKESLICE;
			break;

		case TMAP:
			if(args != nil) {
				l = args->n;
				args = args->next;
				typecheck(&l, Erv);
				defaultlit(&l, types[TINT]);
				if(l->type == T)
					goto error;
				if(checkmake(t, "size", l) < 0)
					goto error;
				n->left = l;
			} else
				n->left = nodintconst(0);
			n->op = OMAKEMAP;
			break;

		case TCHAN:
			l = N;
			if(args != nil) {
				l = args->n;
				args = args->next;
				typecheck(&l, Erv);
				defaultlit(&l, types[TINT]);
				if(l->type == T)
					goto error;
				if(checkmake(t, "buffer", l) < 0)
					goto error;
				n->left = l;
			} else
				n->left = nodintconst(0);
			n->op = OMAKECHAN;
			break;
		}
		if(args != nil) {
			yyerror("too many arguments to make(%T)", t);
			n->op = OMAKE;
			goto error;
		}
		n->type = t;
		goto ret;

	case ONEW:
		ok |= Erv;
		args = n->list;
		if(args == nil) {
			yyerror("missing argument to new");
			goto error;
		}
		l = args->n;
		typecheck(&l, Etype);
		if((t = l->type) == T)
			goto error;
		if(args->next != nil) {
			yyerror("too many arguments to new(%T)", t);
			goto error;
		}
		n->left = l;
		n->type = ptrto(t);
		goto ret;

	case OPRINT:
	case OPRINTN:
		ok |= Etop;
		typechecklist(n->list, Erv | Eindir);  // Eindir: address does not escape
		for(args=n->list; args; args=args->next) {
			// Special case for print: int constant is int64, not int.
			if(isconst(args->n, CTINT))
				defaultlit(&args->n, types[TINT64]);
			else
				defaultlit(&args->n, T);
		}
		goto ret;

	case OPANIC:
		ok |= Etop;
		if(onearg(n, "panic") < 0)
			goto error;
		typecheck(&n->left, Erv);
		defaultlit(&n->left, types[TINTER]);
		if(n->left->type == T)
			goto error;
		goto ret;
	
	case ORECOVER:
		ok |= Erv|Etop;
		if(n->list != nil) {
			yyerror("too many arguments to recover");
			goto error;
		}
		n->type = types[TINTER];
		goto ret;

	case OCLOSURE:
		ok |= Erv;
		typecheckclosure(n, top);
		if(n->type == T)
			goto error;
		goto ret;
	
	case OITAB:
		ok |= Erv;
		typecheck(&n->left, Erv);
		if((t = n->left->type) == T)
			goto error;
		if(t->etype != TINTER)
			fatal("OITAB of %T", t);
		n->type = ptrto(types[TUINTPTR]);
		goto ret;

	case OSPTR:
		ok |= Erv;
		typecheck(&n->left, Erv);
		if((t = n->left->type) == T)
			goto error;
		if(!isslice(t) && t->etype != TSTRING)
			fatal("OSPTR of %T", t);
		if(t->etype == TSTRING)
			n->type = ptrto(types[TUINT8]);
		else
			n->type = ptrto(t->type);
		goto ret;

	case OCLOSUREVAR:
		ok |= Erv;
		goto ret;
	
	case OCFUNC:
		ok |= Erv;
		typecheck(&n->left, Erv);
		n->type = types[TUINTPTR];
		goto ret;

	case OCONVNOP:
		ok |= Erv;
		typecheck(&n->left, Erv);
		goto ret;

	/*
	 * statements
	 */
	case OAS:
		ok |= Etop;
		typecheckas(n);
		goto ret;

	case OAS2:
		ok |= Etop;
		typecheckas2(n);
		goto ret;

	case OBREAK:
	case OCONTINUE:
	case ODCL:
	case OEMPTY:
	case OGOTO:
	case OLABEL:
	case OXFALL:
	case OVARKILL:
		ok |= Etop;
		goto ret;

	case ODEFER:
		ok |= Etop;
		typecheck(&n->left, Etop|Erv);
		if(!n->left->diag)
			checkdefergo(n);
		goto ret;

	case OPROC:
		ok |= Etop;
		typecheck(&n->left, Etop|Eproc|Erv);
		checkdefergo(n);
		goto ret;

	case OFOR:
		ok |= Etop;
		typechecklist(n->ninit, Etop);
		typecheck(&n->ntest, Erv);
		if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
			yyerror("non-bool %lN used as for condition", n->ntest);
		typecheck(&n->nincr, Etop);
		typechecklist(n->nbody, Etop);
		goto ret;

	case OIF:
		ok |= Etop;
		typechecklist(n->ninit, Etop);
		typecheck(&n->ntest, Erv);
		if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
			yyerror("non-bool %lN used as if condition", n->ntest);
		typechecklist(n->nbody, Etop);
		typechecklist(n->nelse, Etop);
		goto ret;

	case ORETURN:
		ok |= Etop;
		if(count(n->list) == 1)
			typechecklist(n->list, Erv | Efnstruct);
		else
			typechecklist(n->list, Erv);
		if(curfn == N) {
			yyerror("return outside function");
			goto error;
		}
		if(curfn->type->outnamed && n->list == nil)
			goto ret;
		typecheckaste(ORETURN, nil, 0, getoutargx(curfn->type), n->list, "return argument");
		goto ret;
	
	case ORETJMP:
		ok |= Etop;
		goto ret;

	case OSELECT:
		ok |= Etop;
		typecheckselect(n);
		goto ret;

	case OSWITCH:
		ok |= Etop;
		typecheckswitch(n);
		goto ret;

	case ORANGE:
		ok |= Etop;
		typecheckrange(n);
		goto ret;

	case OTYPESW:
		yyerror("use of .(type) outside type switch");
		goto error;

	case OXCASE:
		ok |= Etop;
		typechecklist(n->list, Erv);
		typechecklist(n->nbody, Etop);
		goto ret;

	case ODCLFUNC:
		ok |= Etop;
		typecheckfunc(n);
		goto ret;

	case ODCLCONST:
		ok |= Etop;
		typecheck(&n->left, Erv);
		goto ret;

	case ODCLTYPE:
		ok |= Etop;
		typecheck(&n->left, Etype);
		if(!incannedimport)
			checkwidth(n->left->type);
		goto ret;
	}

ret:
	t = n->type;
	if(t && !t->funarg && n->op != OTYPE) {
		switch(t->etype) {
		case TFUNC:	// might have TANY; wait until its called
		case TANY:
		case TFORW:
		case TIDEAL:
		case TNIL:
		case TBLANK:
			break;
		default:
			checkwidth(t);
		}
	}

	if(safemode && !incannedimport && !importpkg && !compiling_wrappers && t && t->etype == TUNSAFEPTR)
		yyerror("cannot use unsafe.Pointer");

	evconst(n);
	if(n->op == OTYPE && !(top & Etype)) {
		yyerror("type %T is not an expression", n->type);
		goto error;
	}
	if((top & (Erv|Etype)) == Etype && n->op != OTYPE) {
		yyerror("%N is not a type", n);
		goto error;
	}
	// TODO(rsc): simplify
	if((top & (Ecall|Erv|Etype)) && !(top & Etop) && !(ok & (Erv|Etype|Ecall))) {
		yyerror("%N used as value", n);
		goto error;
	}
	if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) {
		if(n->diag == 0) {
			yyerror("%N evaluated but not used", n);
			n->diag = 1;
		}
		goto error;
	}

	/* TODO
	if(n->type == T)
		fatal("typecheck nil type");
	*/
	goto out;

badcall1:
	yyerror("invalid argument %lN for %O", n->left, n->op);
	goto error;

error:
	n->type = T;

out:
	*np = n;
}

static int
checksliceindex(Node *r, Type *tp)
{
	Type *t;

	if((t = r->type) == T)
		return -1;
	if(!isint[t->etype]) {
		yyerror("invalid slice index %N (type %T)", r, t);
		return -1;
	}
	if(r->op == OLITERAL) {
		if(mpgetfix(r->val.u.xval) < 0) {
			yyerror("invalid slice index %N (index must be non-negative)", r);
			return -1;
		} else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) {
			yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound);
			return -1;
		} else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) {
			yyerror("invalid slice index %N (index too large)", r);
			return -1;
		}
	}
	return 0;
}

static int
checksliceconst(Node *lo, Node *hi)
{
	if(lo != N && hi != N && lo->op == OLITERAL && hi->op == OLITERAL
	   && mpcmpfixfix(lo->val.u.xval, hi->val.u.xval) > 0) {
		yyerror("invalid slice index: %N > %N", lo, hi);
		return -1;
	}
	return 0;
}

static void
checkdefergo(Node *n)
{
	char *what;
	
	what = "defer";
	if(n->op == OPROC)
		what = "go";

	switch(n->left->op) {
	case OCALLINTER:
	case OCALLMETH:
	case OCALLFUNC:
	case OCLOSE:
	case OCOPY:
	case ODELETE:
	case OPANIC:
	case OPRINT:
	case OPRINTN:
	case ORECOVER:
		// ok
		break;
	case OAPPEND:
	case OCAP:
	case OCOMPLEX:
	case OIMAG:
	case OLEN:
	case OMAKE:
	case OMAKESLICE:
	case OMAKECHAN:
	case OMAKEMAP:
	case ONEW:
	case OREAL:
	case OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
		if(n->left->orig != N && n->left->orig->op == OCONV)
			goto conv;
		yyerror("%s discards result of %N", what, n->left);
		break;
	default:
	conv:
		// type is broken or missing, most likely a method call on a broken type
		// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
		if(n->left->type == T || n->left->type->broke)
			break;

		if(!n->diag) {
			// The syntax made sure it was a call, so this must be
			// a conversion.
			n->diag = 1;
			yyerror("%s requires function call, not conversion", what);
		}
		break;
	}
}

static void
implicitstar(Node **nn)
{
	Type *t;
	Node *n;

	// insert implicit * if needed for fixed array
	n = *nn;
	t = n->type;
	if(t == T || !isptr[t->etype])
		return;
	t = t->type;
	if(t == T)
		return;
	if(!isfixedarray(t))
		return;
	n = nod(OIND, n, N);
	n->implicit = 1;
	typecheck(&n, Erv);
	*nn = n;
}

static int
onearg(Node *n, char *f, ...)
{
	va_list arg;
	char *p;

	if(n->left != N)
		return 0;
	if(n->list == nil) {
		va_start(arg, f);
		p = vsmprint(f, arg);
		va_end(arg);
		yyerror("missing argument to %s: %N", p, n);
		return -1;
	}
	if(n->list->next != nil) {
		va_start(arg, f);
		p = vsmprint(f, arg);
		va_end(arg);
		yyerror("too many arguments to %s: %N", p, n);
		n->left = n->list->n;
		n->list = nil;
		return -1;
	}
	n->left = n->list->n;
	n->list = nil;
	return 0;
}

static int
twoarg(Node *n)
{
	if(n->left != N)
		return 0;
	if(n->list == nil) {
		yyerror("missing argument to %O - %N", n->op, n);
		return -1;
	}
	n->left = n->list->n;
	if(n->list->next == nil) {
		yyerror("missing argument to %O - %N", n->op, n);
		n->list = nil;
		return -1;
	}
	if(n->list->next->next != nil) {
		yyerror("too many arguments to %O - %N", n->op, n);
		n->list = nil;
		return -1;
	}
	n->right = n->list->next->n;
	n->list = nil;
	return 0;
}

static Type*
lookdot1(Node *errnode, Sym *s, Type *t, Type *f, int dostrcmp)
{
	Type *r;

	r = T;
	for(; f!=T; f=f->down) {
		if(dostrcmp && strcmp(f->sym->name, s->name) == 0)
			return f;
		if(f->sym != s)
			continue;
		if(r != T) {
			if(errnode)
				yyerror("ambiguous selector %N", errnode);
			else if(isptr[t->etype])
				yyerror("ambiguous selector (%T).%S", t, s);
			else
				yyerror("ambiguous selector %T.%S", t, s);
			break;
		}
		r = f;
	}
	return r;
}

static int
looktypedot(Node *n, Type *t, int dostrcmp)
{
	Type *f1, *f2;
	Sym *s;
	
	s = n->right->sym;

	if(t->etype == TINTER) {
		f1 = lookdot1(n, s, t, t->type, dostrcmp);
		if(f1 == T)
			return 0;

		n->right = methodname(n->right, t);
		n->xoffset = f1->width;
		n->type = f1->type;
		n->op = ODOTINTER;
		return 1;
	}

	// Find the base type: methtype will fail if t
	// is not of the form T or *T.
	f2 = methtype(t, 0);
	if(f2 == T)
		return 0;

	expandmeth(f2);
	f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp);
	if(f2 == T)
		return 0;

	// disallow T.m if m requires *T receiver
	if(isptr[getthisx(f2->type)->type->type->etype]
	&& !isptr[t->etype]
	&& f2->embedded != 2
	&& !isifacemethod(f2->type)) {
		yyerror("invalid method expression %N (needs pointer receiver: (*%T).%hS)", n, t, f2->sym);
		return 0;
	}

	n->right = methodname(n->right, t);
	n->xoffset = f2->width;
	n->type = f2->type;
	n->op = ODOTMETH;
	return 1;
}

static Type*
derefall(Type* t)
{
	while(t && t->etype == tptr)
		t = t->type;
	return t;
}

static int
lookdot(Node *n, Type *t, int dostrcmp)
{
	Type *f1, *f2, *tt, *rcvr;
	Sym *s;

	s = n->right->sym;

	dowidth(t);
	f1 = T;
	if(t->etype == TSTRUCT || t->etype == TINTER)
		f1 = lookdot1(n, s, t, t->type, dostrcmp);

	f2 = T;
	if(n->left->type == t || n->left->type->sym == S) {
		f2 = methtype(t, 0);
		if(f2 != T) {
			// Use f2->method, not f2->xmethod: adddot has
			// already inserted all the necessary embedded dots.
			f2 = lookdot1(n, s, f2, f2->method, dostrcmp);
		}
	}

	if(f1 != T) {
		if(f2 != T)
			yyerror("%S is both field and method",
				n->right->sym);
		if(f1->width == BADWIDTH)
			fatal("lookdot badwidth %T %p", f1, f1);
		n->xoffset = f1->width;
		n->type = f1->type;
		n->paramfld = f1;
		if(t->etype == TINTER) {
			if(isptr[n->left->type->etype]) {
				n->left = nod(OIND, n->left, N);	// implicitstar
				n->left->implicit = 1;
				typecheck(&n->left, Erv);
			}
			n->op = ODOTINTER;
		}
		return 1;
	}

	if(f2 != T) {
		tt = n->left->type;
		dowidth(tt);
		rcvr = getthisx(f2->type)->type->type;
		if(!eqtype(rcvr, tt)) {
			if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) {
				checklvalue(n->left, "call pointer method on");
				if(debug['N'])
					addrescapes(n->left);
				n->left = nod(OADDR, n->left, N);
				n->left->implicit = 1;
				typecheck(&n->left, Etype|Erv);
			} else if(tt->etype == tptr && eqtype(tt->type, rcvr)) {
				n->left = nod(OIND, n->left, N);
				n->left->implicit = 1;
				typecheck(&n->left, Etype|Erv);
			} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), rcvr)) {
				yyerror("calling method %N with receiver %lN requires explicit dereference", n->right, n->left);
				while(tt->etype == tptr) {
					n->left = nod(OIND, n->left, N);
					n->left->implicit = 1;
					typecheck(&n->left, Etype|Erv);
					tt = tt->type;
				}
			} else {
				fatal("method mismatch: %T for %T", rcvr, tt);
			}
		}
		n->right = methodname(n->right, n->left->type);
		n->xoffset = f2->width;
		n->type = f2->type;
//		print("lookdot found [%p] %T\n", f2->type, f2->type);
		n->op = ODOTMETH;
		return 1;
	}

	return 0;
}

static int
nokeys(NodeList *l)
{
	for(; l; l=l->next)
		if(l->n->op == OKEY)
			return 0;
	return 1;
}

static int
hasddd(Type *t)
{
	Type *tl;

	for(tl=t->type; tl; tl=tl->down) {
		if(tl->isddd)
			return 1;
	}
	return 0;
}

static int
downcount(Type *t)
{
	Type *tl;
	int n;

	n = 0;
	for(tl=t->type; tl; tl=tl->down) {
		n++;
	}
	return n;
}

/*
 * typecheck assignment: type list = expression list
 */
static void
typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *desc)
{
	Type *t, *tl, *tn;
	Node *n;
	int lno;
	char *why;
	int n1, n2;

	lno = lineno;

	if(tstruct->broke)
		goto out;

	n = N;
	if(nl != nil && nl->next == nil && (n = nl->n)->type != T)
	if(n->type->etype == TSTRUCT && n->type->funarg) {
		if(!hasddd(tstruct)) {
			n1 = downcount(tstruct);
			n2 = downcount(n->type);
			if(n2 > n1)
				goto toomany;
			if(n2 < n1)
				goto notenough;
		}
		
		tn = n->type->type;
		for(tl=tstruct->type; tl; tl=tl->down) {
			if(tl->isddd) {
				for(; tn; tn=tn->down) {
					if(assignop(tn->type, tl->type->type, &why) == 0) {
						if(call != N)
							yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type->type, call, why);
						else
							yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type->type, desc, why);
					}
				}
				goto out;
			}
			if(tn == T)
				goto notenough;
			if(assignop(tn->type, tl->type, &why) == 0) {
				if(call != N)
					yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type, call, why);
				else
					yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type, desc, why);
			}
			tn = tn->down;
		}
		if(tn != T)
			goto toomany;
		goto out;
	}

	n1 = downcount(tstruct);
	n2 = count(nl);
	if(!hasddd(tstruct)) {
		if(n2 > n1)
			goto toomany;
		if(n2 < n1)
			goto notenough;
	}
	else {
		if(!isddd) {
			if(n2 < n1-1)
				goto notenough;
		} else {
			if(n2 > n1)
				goto toomany;
			if(n2 < n1)
				goto notenough;
		}
	}

	for(tl=tstruct->type; tl; tl=tl->down) {
		t = tl->type;
		if(tl->isddd) {
			if(isddd) {
				if(nl == nil)
					goto notenough;
				if(nl->next != nil)
					goto toomany;
				n = nl->n;
				setlineno(n);
				if(n->type != T)
					nl->n = assignconv(n, t, desc);
				goto out;
			}
			for(; nl; nl=nl->next) {
				n = nl->n;
				setlineno(nl->n);
				if(n->type != T)
					nl->n = assignconv(n, t->type, desc);
			}
			goto out;
		}
		if(nl == nil)
			goto notenough;
		n = nl->n;
		setlineno(n);
		if(n->type != T)
			nl->n = assignconv(n, t, desc);
		nl = nl->next;
	}
	if(nl != nil)
		goto toomany;
	if(isddd) {
		if(call != N)
			yyerror("invalid use of ... in call to %N", call);
		else
			yyerror("invalid use of ... in %O", op);
	}

out:
	lineno = lno;
	return;

notenough:
	if(n == N || !n->diag) {
		if(call != N)
			yyerror("not enough arguments in call to %N", call);
		else
			yyerror("not enough arguments to %O", op);
		if(n != N)
			n->diag = 1;
	}
	goto out;

toomany:
	if(call != N)
		yyerror("too many arguments in call to %N", call);
	else
		yyerror("too many arguments to %O", op);
	goto out;
}

/*
 * type check composite
 */

static void
fielddup(Node *n, Node *hash[], ulong nhash)
{
	uint h;
	char *s;
	Node *a;

	if(n->op != ONAME)
		fatal("fielddup: not ONAME");
	s = n->sym->name;
	h = stringhash(s)%nhash;
	for(a=hash[h]; a!=N; a=a->ntest) {
		if(strcmp(a->sym->name, s) == 0) {
			yyerror("duplicate field name in struct literal: %s", s);
			return;
		}
	}
	n->ntest = hash[h];
	hash[h] = n;
}

static void
keydup(Node *n, Node *hash[], ulong nhash)
{
	uint h;
	ulong b;
	double d;
	int i;
	Node *a, *orign;
	Node cmp;
	char *s;

	orign = n;
	if(n->op == OCONVIFACE)
		n = n->left;
	evconst(n);
	if(n->op != OLITERAL)
		return;	// we dont check variables

	switch(n->val.ctype) {
	default:	// unknown, bool, nil
		b = 23;
		break;
	case CTINT:
	case CTRUNE:
		b = mpgetfix(n->val.u.xval);
		break;
	case CTFLT:
		d = mpgetflt(n->val.u.fval);
		s = (char*)&d;
		b = 0;
		for(i=sizeof(d); i>0; i--)
			b = b*PRIME1 + *s++;
		break;
	case CTSTR:
		b = 0;
		s = n->val.u.sval->s;
		for(i=n->val.u.sval->len; i>0; i--)
			b = b*PRIME1 + *s++;
		break;
	}

	h = b%nhash;
	memset(&cmp, 0, sizeof(cmp));
	for(a=hash[h]; a!=N; a=a->ntest) {
		cmp.op = OEQ;
		cmp.left = n;
		b = 0;
		if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
			if(eqtype(a->left->type, n->type)) {
				cmp.right = a->left;
				evconst(&cmp);
				b = cmp.val.u.bval;
			}
		} else if(eqtype(a->type, n->type)) {
			cmp.right = a;
			evconst(&cmp);
			b = cmp.val.u.bval;
		}
		if(b) {
			yyerror("duplicate key %N in map literal", n);
			return;
		}
	}
	orign->ntest = hash[h];
	hash[h] = orign;
}

static void
indexdup(Node *n, Node *hash[], ulong nhash)
{
	uint h;
	Node *a;
	ulong b, c;

	if(n->op != OLITERAL)
		fatal("indexdup: not OLITERAL");

	b = mpgetfix(n->val.u.xval);
	h = b%nhash;
	for(a=hash[h]; a!=N; a=a->ntest) {
		c = mpgetfix(a->val.u.xval);
		if(b == c) {
			yyerror("duplicate index in array literal: %ld", b);
			return;
		}
	}
	n->ntest = hash[h];
	hash[h] = n;
}

static int
prime(ulong h, ulong sr)
{
	ulong n;

	for(n=3; n<=sr; n+=2)
		if(h%n == 0)
			return 0;
	return 1;
}

static ulong
inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash)
{
	ulong h, sr;
	NodeList *ll;
	int i;

	// count the number of entries
	h = 0;
	for(ll=n->list; ll; ll=ll->next)
		h++;

	// if the auto hash table is
	// large enough use it.
	if(h <= nautohash) {
		*hash = autohash;
		memset(*hash, 0, nautohash * sizeof(**hash));
		return nautohash;
	}

	// make hash size odd and 12% larger than entries
	h += h/8;
	h |= 1;

	// calculate sqrt of h
	sr = h/2;
	for(i=0; i<5; i++)
		sr = (sr + h/sr)/2;

	// check for primeality
	while(!prime(h, sr))
		h += 2;

	// build and return a throw-away hash table
	*hash = mal(h * sizeof(**hash));
	memset(*hash, 0, h * sizeof(**hash));
	return h;
}

static int
iscomptype(Type *t)
{
	switch(t->etype) {
	case TARRAY:
	case TSTRUCT:
	case TMAP:
		return 1;
	case TPTR32:
	case TPTR64:
		switch(t->type->etype) {
		case TARRAY:
		case TSTRUCT:
		case TMAP:
			return 1;
		}
		break;
	}
	return 0;
}

static void
pushtype(Node *n, Type *t)
{
	if(n == N || n->op != OCOMPLIT || !iscomptype(t))
		return;
	
	if(n->right == N) {
		n->right = typenod(t);
		n->implicit = 1;  // don't print
		n->right->implicit = 1;  // * is okay
	}
	else if(debug['s']) {
		typecheck(&n->right, Etype);
		if(n->right->type != T && eqtype(n->right->type, t))
			print("%lL: redundant type: %T\n", n->lineno, t);
	}
}

static void
typecheckcomplit(Node **np)
{
	int bad, i, nerr;
	int64 len;
	Node *l, *n, *norig, *r, **hash;
	NodeList *ll;
	Type *t, *f;
	Sym *s, *s1;
	int32 lno;
	ulong nhash;
	Node *autohash[101];

	n = *np;
	lno = lineno;

	if(n->right == N) {
		if(n->list != nil)
			setlineno(n->list->n);
		yyerror("missing type in composite literal");
		goto error;
	}

	// Save original node (including n->right)
	norig = nod(n->op, N, N);
	*norig = *n;

	setlineno(n->right);
	l = typecheck(&n->right /* sic */, Etype|Ecomplit);
	if((t = l->type) == T)
		goto error;
	nerr = nerrors;
	n->type = t;

	if(isptr[t->etype]) {
		// For better or worse, we don't allow pointers as the composite literal type,
		// except when using the &T syntax, which sets implicit on the OIND.
		if(!n->right->implicit) {
			yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
			goto error;
		}
		// Also, the underlying type must be a struct, map, slice, or array.
		if(!iscomptype(t)) {
			yyerror("invalid pointer type %T for composite literal", t);
			goto error;
		}
		t = t->type;
	}

	switch(t->etype) {
	default:
		yyerror("invalid type for composite literal: %T", t);
		n->type = T;
		break;

	case TARRAY:
		nhash = inithash(n, &hash, autohash, nelem(autohash));

		len = 0;
		i = 0;
		for(ll=n->list; ll; ll=ll->next) {
			l = ll->n;
			setlineno(l);
			if(l->op != OKEY) {
				l = nod(OKEY, nodintconst(i), l);
				l->left->type = types[TINT];
				l->left->typecheck = 1;
				ll->n = l;
			}

			typecheck(&l->left, Erv);
			evconst(l->left);
			i = nonnegconst(l->left);
			if(i < 0 && !l->left->diag) {
				yyerror("array index must be non-negative integer constant");
				l->left->diag = 1;
				i = -(1<<30);	// stay negative for a while
			}
			if(i >= 0)
				indexdup(l->left, hash, nhash);
			i++;
			if(i > len) {
				len = i;
				if(t->bound >= 0 && len > t->bound) {
					setlineno(l);
					yyerror("array index %lld out of bounds [0:%lld]", len-1, t->bound);
					t->bound = -1;	// no more errors
				}
			}

			r = l->right;
			pushtype(r, t->type);
			typecheck(&r, Erv);
			defaultlit(&r, t->type);
			l->right = assignconv(r, t->type, "array element");
		}
		if(t->bound == -100)
			t->bound = len;
		if(t->bound < 0)
			n->right = nodintconst(len);
		n->op = OARRAYLIT;
		break;

	case TMAP:
		nhash = inithash(n, &hash, autohash, nelem(autohash));

		for(ll=n->list; ll; ll=ll->next) {
			l = ll->n;
			setlineno(l);
			if(l->op != OKEY) {
				typecheck(&ll->n, Erv);
				yyerror("missing key in map literal");
				continue;
			}

			typecheck(&l->left, Erv);
			defaultlit(&l->left, t->down);
			l->left = assignconv(l->left, t->down, "map key");
			if (l->left->op != OCONV)
				keydup(l->left, hash, nhash);

			r = l->right;
			pushtype(r, t->type);
			typecheck(&r, Erv);
			defaultlit(&r, t->type);
			l->right = assignconv(r, t->type, "map value");
		}
		n->op = OMAPLIT;
		break;

	case TSTRUCT:
		bad = 0;
		if(n->list != nil && nokeys(n->list)) {
			// simple list of variables
			f = t->type;
			for(ll=n->list; ll; ll=ll->next) {
				setlineno(ll->n);
				typecheck(&ll->n, Erv);
				if(f == nil) {
					if(!bad++)
						yyerror("too many values in struct initializer");
					continue;
				}
				s = f->sym;
				if(s != nil && !exportname(s->name) && s->pkg != localpkg)
					yyerror("implicit assignment of unexported field '%s' in %T literal", s->name, t);
				// No pushtype allowed here.  Must name fields for that.
				ll->n = assignconv(ll->n, f->type, "field value");
				ll->n = nod(OKEY, newname(f->sym), ll->n);
				ll->n->left->type = f;
				ll->n->left->typecheck = 1;
				f = f->down;
			}
			if(f != nil)
				yyerror("too few values in struct initializer");
		} else {
			nhash = inithash(n, &hash, autohash, nelem(autohash));

			// keyed list
			for(ll=n->list; ll; ll=ll->next) {
				l = ll->n;
				setlineno(l);
				if(l->op != OKEY) {
					if(!bad++)
						yyerror("mixture of field:value and value initializers");
					typecheck(&ll->n, Erv);
					continue;
				}
				s = l->left->sym;
				if(s == S) {
					yyerror("invalid field name %N in struct initializer", l->left);
					typecheck(&l->right, Erv);
					continue;
				}

				// Sym might have resolved to name in other top-level
				// package, because of import dot.  Redirect to correct sym
				// before we do the lookup.
				if(s->pkg != localpkg && exportname(s->name)) {
					s1 = lookup(s->name);
					if(s1->origpkg == s->pkg)
						s = s1;
				}
				f = lookdot1(nil, s, t, t->type, 0);
				if(f == nil) {
					yyerror("unknown %T field '%S' in struct literal", t, s);
					continue;
				}
				l->left = newname(s);
				l->left->typecheck = 1;
				l->left->type = f;
				s = f->sym;
				fielddup(newname(s), hash, nhash);
				r = l->right;
				// No pushtype allowed here.  Tried and rejected.
				typecheck(&r, Erv);
				l->right = assignconv(r, f->type, "field value");
			}
		}
		n->op = OSTRUCTLIT;
		break;
	}
	if(nerr != nerrors)
		goto error;
	
	n->orig = norig;
	if(isptr[n->type->etype]) {
		n = nod(OPTRLIT, n, N);
		n->typecheck = 1;
		n->type = n->left->type;
		n->left->type = t;
		n->left->typecheck = 1;
	}

	n->orig = norig;
	*np = n;
	lineno = lno;
	return;

error:
	n->type = T;
	*np = n;
	lineno = lno;
}

/*
 * lvalue etc
 */
int
islvalue(Node *n)
{
	switch(n->op) {
	case OINDEX:
		if(isfixedarray(n->left->type))
			return islvalue(n->left);
		if(n->left->type != T && n->left->type->etype == TSTRING)
			return 0;
		// fall through
	case OIND:
	case ODOTPTR:
	case OCLOSUREVAR:
		return 1;
	case ODOT:
		return islvalue(n->left);
	case ONAME:
		if(n->class == PFUNC)
			return 0;
		return 1;
	}
	return 0;
}

static void
checklvalue(Node *n, char *verb)
{
	if(!islvalue(n))
		yyerror("cannot %s %N", verb, n);
}

static void
checkassign(Node *n)
{
	if(islvalue(n))
		return;
	if(n->op == OINDEXMAP) {
		n->etype = 1;
		return;
	}

	// have already complained about n being undefined
	if(n->op == ONONAME)
		return;

	yyerror("cannot assign to %N", n);
}

static void
checkassignlist(NodeList *l)
{
	for(; l; l=l->next)
		checkassign(l->n);
}

/*
 * type check assignment.
 * if this assignment is the definition of a var on the left side,
 * fill in the var's type.
 */

static void
typecheckas(Node *n)
{
	// delicate little dance.
	// the definition of n may refer to this assignment
	// as its definition, in which case it will call typecheckas.
	// in that case, do not call typecheck back, or it will cycle.
	// if the variable has a type (ntype) then typechecking
	// will not look at defn, so it is okay (and desirable,
	// so that the conversion below happens).
	n->left = resolve(n->left);
	if(n->left->defn != n || n->left->ntype)
		typecheck(&n->left, Erv | Easgn);

	checkassign(n->left);
	typecheck(&n->right, Erv);
	if(n->right && n->right->type != T) {
		if(n->left->type != T)
			n->right = assignconv(n->right, n->left->type, "assignment");
	}
	if(n->left->defn == n && n->left->ntype == N) {
		defaultlit(&n->right, T);
		n->left->type = n->right->type;
	}

	// second half of dance.
	// now that right is done, typecheck the left
	// just to get it over with.  see dance above.
	n->typecheck = 1;
	if(n->left->typecheck == 0)
		typecheck(&n->left, Erv | Easgn);
}

static void
checkassignto(Type *src, Node *dst)
{
	char *why;

	if(assignop(src, dst->type, &why) == 0) {
		yyerror("cannot assign %T to %lN in multiple assignment%s", src, dst, why);
		return;
	}
}

static void
typecheckas2(Node *n)
{
	int cl, cr;
	NodeList *ll, *lr;
	Node *l, *r;
	Iter s;
	Type *t;

	for(ll=n->list; ll; ll=ll->next) {
		// delicate little dance.
		ll->n = resolve(ll->n);
		if(ll->n->defn != n || ll->n->ntype)
			typecheck(&ll->n, Erv | Easgn);
	}
	cl = count(n->list);
	cr = count(n->rlist);
	checkassignlist(n->list);
	if(cl > 1 && cr == 1)
		typecheck(&n->rlist->n, Erv | Efnstruct);
	else
		typechecklist(n->rlist, Erv);

	if(cl == cr) {
		// easy
		for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next) {
			if(ll->n->type != T && lr->n->type != T)
				lr->n = assignconv(lr->n, ll->n->type, "assignment");
			if(ll->n->defn == n && ll->n->ntype == N) {
				defaultlit(&lr->n, T);
				ll->n->type = lr->n->type;
			}
		}
		goto out;
	}


	l = n->list->n;
	r = n->rlist->n;

	// m[i] = x, ok
	if(cl == 1 && cr == 2 && l->op == OINDEXMAP) {
		if(l->type == T)
			goto out;
		yyerror("assignment count mismatch: %d = %d (use delete)", cl, cr);
		goto out;
	}

	// x,y,z = f()
	if(cr == 1) {
		if(r->type == T)
			goto out;
		switch(r->op) {
		case OCALLMETH:
		case OCALLINTER:
		case OCALLFUNC:
			if(r->type->etype != TSTRUCT || r->type->funarg == 0)
				break;
			cr = structcount(r->type);
			if(cr != cl)
				goto mismatch;
			n->op = OAS2FUNC;
			t = structfirst(&s, &r->type);
			for(ll=n->list; ll; ll=ll->next) {
				if(t->type != T && ll->n->type != T)
					checkassignto(t->type, ll->n);
				if(ll->n->defn == n && ll->n->ntype == N)
					ll->n->type = t->type;
				t = structnext(&s);
			}
			goto out;
		}
	}

	// x, ok = y
	if(cl == 2 && cr == 1) {
		if(r->type == T)
			goto out;
		switch(r->op) {
		case OINDEXMAP:
			n->op = OAS2MAPR;
			goto common;
		case ORECV:
			n->op = OAS2RECV;
			goto common;
		case ODOTTYPE:
			n->op = OAS2DOTTYPE;
			r->op = ODOTTYPE2;
		common:
			if(l->type != T)
				checkassignto(r->type, l);
			if(l->defn == n)
				l->type = r->type;
			l = n->list->next->n;
			if(l->type != T)
				checkassignto(types[TBOOL], l);
			if(l->defn == n && l->ntype == N)
				l->type = types[TBOOL];
			goto out;
		}
	}

mismatch:
	yyerror("assignment count mismatch: %d = %d", cl, cr);

out:
	// second half of dance
	n->typecheck = 1;
	for(ll=n->list; ll; ll=ll->next)
		if(ll->n->typecheck == 0)
			typecheck(&ll->n, Erv | Easgn);
}

/*
 * type check function definition
 */
static void
typecheckfunc(Node *n)
{
	Type *t, *rcvr;

	typecheck(&n->nname, Erv | Easgn);
	if((t = n->nname->type) == T)
		return;
	n->type = t;
	t->nname = n->nname;
	rcvr = getthisx(t)->type;
	if(rcvr != nil && n->shortname != N && !isblank(n->shortname))
		addmethod(n->shortname->sym, t, 1, n->nname->nointerface);
}

static void
stringtoarraylit(Node **np)
{
	int32 i;
	NodeList *l;
	Strlit *s;
	char *p, *ep;
	Rune r;
	Node *nn, *n;

	n = *np;
	if(n->left->op != OLITERAL || n->left->val.ctype != CTSTR)
		fatal("stringtoarraylit %N", n);

	s = n->left->val.u.sval;
	l = nil;
	p = s->s;
	ep = s->s + s->len;
	i = 0;
	if(n->type->type->etype == TUINT8) {
		// raw []byte
		while(p < ep)
			l = list(l, nod(OKEY, nodintconst(i++), nodintconst((uchar)*p++)));
	} else {
		// utf-8 []rune
		while(p < ep) {
			p += chartorune(&r, p);
			l = list(l, nod(OKEY, nodintconst(i++), nodintconst(r)));
		}
	}
	nn = nod(OCOMPLIT, N, typenod(n->type));
	nn->list = l;
	typecheck(&nn, Erv);
	*np = nn;
}


static int ntypecheckdeftype;
static NodeList *methodqueue;

static void
domethod(Node *n)
{
	Node *nt;
	Type *t;

	nt = n->type->nname;
	typecheck(&nt, Etype);
	if(nt->type == T) {
		// type check failed; leave empty func
		n->type->etype = TFUNC;
		n->type->nod = N;
		return;
	}
	
	// If we have
	//	type I interface {
	//		M(_ int)
	//	}
	// then even though I.M looks like it doesn't care about the
	// value of its argument, a specific implementation of I may
	// care.  The _ would suppress the assignment to that argument
	// while generating a call, so remove it.
	for(t=getinargx(nt->type)->type; t; t=t->down) {
		if(t->sym != nil && strcmp(t->sym->name, "_") == 0)
			t->sym = nil;
	}

	*n->type = *nt->type;
	n->type->nod = N;
	checkwidth(n->type);
}

static NodeList *mapqueue;

void
copytype(Node *n, Type *t)
{
	int maplineno, embedlineno, lno;
	NodeList *l;

	if(t->etype == TFORW) {
		// This type isn't computed yet; when it is, update n.
		t->copyto = list(t->copyto, n);
		return;
	}

	maplineno = n->type->maplineno;
	embedlineno = n->type->embedlineno;

	l = n->type->copyto;
	*n->type = *t;

	t = n->type;
	t->sym = n->sym;
	t->local = n->local;
	t->vargen = n->vargen;
	t->siggen = 0;
	t->method = nil;
	t->xmethod = nil;
	t->nod = N;
	t->printed = 0;
	t->deferwidth = 0;
	t->copyto = nil;
	
	// Update nodes waiting on this type.
	for(; l; l=l->next)
		copytype(l->n, t);

	// Double-check use of type as embedded type.
	lno = lineno;
	if(embedlineno) {
		lineno = embedlineno;
		if(isptr[t->etype])
			yyerror("embedded type cannot be a pointer");
	}
	lineno = lno;
	
	// Queue check for map until all the types are done settling.
	if(maplineno) {
		t->maplineno = maplineno;
		mapqueue = list(mapqueue, n);
	}
}

static void
typecheckdeftype(Node *n)
{
	int lno;
	Type *t;
	NodeList *l;

	ntypecheckdeftype++;
	lno = lineno;
	setlineno(n);
	n->type->sym = n->sym;
	n->typecheck = 1;
	typecheck(&n->ntype, Etype);
	if((t = n->ntype->type) == T) {
		n->diag = 1;
		n->type = T;
		goto ret;
	}
	if(n->type == T) {
		n->diag = 1;
		goto ret;
	}

	// copy new type and clear fields
	// that don't come along.
	// anything zeroed here must be zeroed in
	// typedcl2 too.
	copytype(n, t);

ret:
	lineno = lno;

	// if there are no type definitions going on, it's safe to
	// try to resolve the method types for the interfaces
	// we just read.
	if(ntypecheckdeftype == 1) {
		while((l = methodqueue) != nil) {
			methodqueue = nil;
			for(; l; l=l->next)
				domethod(l->n);
		}
		for(l=mapqueue; l; l=l->next) {
			lineno = l->n->type->maplineno;
			maptype(l->n->type, types[TBOOL]);
		}
		lineno = lno;
	}
	ntypecheckdeftype--;
}

void
queuemethod(Node *n)
{
	if(ntypecheckdeftype == 0) {
		domethod(n);
		return;
	}
	methodqueue = list(methodqueue, n);
}

Node*
typecheckdef(Node *n)
{
	int lno, nerrors0;
	Node *e;
	Type *t;
	NodeList *l;

	lno = lineno;
	setlineno(n);

	if(n->op == ONONAME) {
		if(!n->diag) {
			n->diag = 1;
			if(n->lineno != 0)
				lineno = n->lineno;
			yyerror("undefined: %S", n->sym);
		}
		return n;
	}

	if(n->walkdef == 1)
		return n;

	l = mal(sizeof *l);
	l->n = n;
	l->next = typecheckdefstack;
	typecheckdefstack = l;

	if(n->walkdef == 2) {
		flusherrors();
		print("typecheckdef loop:");
		for(l=typecheckdefstack; l; l=l->next)
			print(" %S", l->n->sym);
		print("\n");
		fatal("typecheckdef loop");
	}
	n->walkdef = 2;

	if(n->type != T || n->sym == S)	// builtin or no name
		goto ret;

	switch(n->op) {
	default:
		fatal("typecheckdef %O", n->op);

	case OGOTO:
	case OLABEL:
		// not really syms
		break;

	case OLITERAL:
		if(n->ntype != N) {
			typecheck(&n->ntype, Etype);
			n->type = n->ntype->type;
			n->ntype = N;
			if(n->type == T) {
				n->diag = 1;
				goto ret;
			}
		}
		e = n->defn;
		n->defn = N;
		if(e == N) {
			lineno = n->lineno;
			dump("typecheckdef nil defn", n);
			yyerror("xxx");
		}
		typecheck(&e, Erv | Eiota);
		if(isconst(e, CTNIL)) {
			yyerror("const initializer cannot be nil");
			goto ret;
		}
		if(e->type != T && e->op != OLITERAL || !isgoconst(e)) {
			if(!e->diag) {
				yyerror("const initializer %N is not a constant", e);
				e->diag = 1;
			}
			goto ret;
		}
		t = n->type;
		if(t != T) {
			if(!okforconst[t->etype]) {
				yyerror("invalid constant type %T", t);
				goto ret;
			}
			if(!isideal(e->type) && !eqtype(t, e->type)) {
				yyerror("cannot use %lN as type %T in const initializer", e, t);
				goto ret;
			}
			convlit(&e, t);
		}
		n->val = e->val;
		n->type = e->type;
		break;

	case ONAME:
		if(n->ntype != N) {
			typecheck(&n->ntype, Etype);
			n->type = n->ntype->type;

			if(n->type == T) {
				n->diag = 1;
				goto ret;
			}
		}
		if(n->type != T)
			break;
		if(n->defn == N) {
			if(n->etype != 0)	// like OPRINTN
				break;
			if(nsavederrors+nerrors > 0) {
				// Can have undefined variables in x := foo
				// that make x have an n->ndefn == nil.
				// If there are other errors anyway, don't
				// bother adding to the noise.
				break;
			}
			fatal("var without type, init: %S", n->sym);
		}
		if(n->defn->op == ONAME) {
			typecheck(&n->defn, Erv);
			n->type = n->defn->type;
			break;
		}
		typecheck(&n->defn, Etop);	// fills in n->type
		break;

	case OTYPE:
		if(curfn)
			defercheckwidth();
		n->walkdef = 1;
		n->type = typ(TFORW);
		n->type->sym = n->sym;
		nerrors0 = nerrors;
		typecheckdeftype(n);
		if(n->type->etype == TFORW && nerrors > nerrors0) {
			// Something went wrong during type-checking,
			// but it was reported. Silence future errors.
			n->type->broke = 1;
		}
		if(curfn)
			resumecheckwidth();
		break;

	case OPACK:
		// nothing to see here
		break;
	}

ret:
	if(n->op != OLITERAL && n->type != T && isideal(n->type))
		fatal("got %T for %N", n->type, n);
	if(typecheckdefstack->n != n)
		fatal("typecheckdefstack mismatch");
	l = typecheckdefstack;
	typecheckdefstack = l->next;

	lineno = lno;
	n->walkdef = 1;
	return n;
}

static int
checkmake(Type *t, char *arg, Node *n)
{
	if(n->op == OLITERAL) {
		switch(n->val.ctype) {
		case CTINT:
		case CTRUNE:
		case CTFLT:
		case CTCPLX:
			n->val = toint(n->val);
			if(mpcmpfixc(n->val.u.xval, 0) < 0) {
				yyerror("negative %s argument in make(%T)", arg, t);
				return -1;
			}
			if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
				yyerror("%s argument too large in make(%T)", arg, t);
				return -1;
			}
			
			// Delay defaultlit until after we've checked range, to avoid
			// a redundant "constant NNN overflows int" error.
			defaultlit(&n, types[TINT]);
			return 0;
		default:
		       	break;
		}
	}

	if(!isint[n->type->etype] && n->type->etype != TIDEAL) {
		yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type);
		return -1;
	}

	// Defaultlit still necessary for non-constant: n might be 1<<k.
	defaultlit(&n, types[TINT]);

	return 0;
}

static void	markbreaklist(NodeList*, Node*);

static void
markbreak(Node *n, Node *implicit)
{
	Label *lab;

	if(n == N)
		return;

	switch(n->op) {
	case OBREAK:
		if(n->left == N) {
			if(implicit)
				implicit->hasbreak = 1;
		} else {
			lab = n->left->sym->label;
			if(lab != L)
				lab->def->hasbreak = 1;
		}
		break;
	
	case OFOR:
	case OSWITCH:
	case OTYPESW:
	case OSELECT:
	case ORANGE:
		implicit = n;
		// fall through
	
	default:
		markbreak(n->left, implicit);
		markbreak(n->right, implicit);
		markbreak(n->ntest, implicit);
		markbreak(n->nincr, implicit);
		markbreaklist(n->ninit, implicit);
		markbreaklist(n->nbody, implicit);
		markbreaklist(n->nelse, implicit);
		markbreaklist(n->list, implicit);
		markbreaklist(n->rlist, implicit);
		break;
	}
}

static void
markbreaklist(NodeList *l, Node *implicit)
{
	Node *n;
	Label *lab;

	for(; l; l=l->next) {
		n = l->n;
		if(n->op == OLABEL && l->next && n->defn == l->next->n) {
			switch(n->defn->op) {
			case OFOR:
			case OSWITCH:
			case OTYPESW:
			case OSELECT:
			case ORANGE:
				lab = mal(sizeof *lab);
				lab->def = n->defn;
				n->left->sym->label = lab;
				markbreak(n->defn, n->defn);
				n->left->sym->label = L;
				l = l->next;
				continue;
			}
		}
		markbreak(n, implicit);
	}
}

static int
isterminating(NodeList *l, int top)
{
	int def;
	Node *n;

	if(l == nil)
		return 0;
	if(top) {
		while(l->next && l->n->op != OLABEL)
			l = l->next;
		markbreaklist(l, nil);
	}
	while(l->next)
		l = l->next;
	n = l->n;

	if(n == N)
		return 0;

	switch(n->op) {
	// NOTE: OLABEL is treated as a separate statement,
	// not a separate prefix, so skipping to the last statement
	// in the block handles the labeled statement case by
	// skipping over the label. No case OLABEL here.

	case OBLOCK:
		return isterminating(n->list, 0);

	case OGOTO:
	case ORETURN:
	case ORETJMP:
	case OPANIC:
	case OXFALL:
		return 1;

	case OFOR:
		if(n->ntest != N)
			return 0;
		if(n->hasbreak)
			return 0;
		return 1;

	case OIF:
		return isterminating(n->nbody, 0) && isterminating(n->nelse, 0);

	case OSWITCH:
	case OTYPESW:
	case OSELECT:
		if(n->hasbreak)
			return 0;
		def = 0;
		for(l=n->list; l; l=l->next) {
			if(!isterminating(l->n->nbody, 0))
				return 0;
			if(l->n->list == nil) // default
				def = 1;
		}
		if(n->op != OSELECT && !def)
			return 0;
		return 1;
	}
	
	return 0;
}

void
checkreturn(Node *fn)
{
	if(fn->type->outtuple && fn->nbody != nil)
		if(!isterminating(fn->nbody, 1))
			yyerrorl(fn->endlineno, "missing return at end of function");
}
