// 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.

package gc

import (
	"cmd/internal/obj"
	"fmt"
)

const (
	Snorm = 0 + iota
	Strue
	Sfalse
	Stype
	Tdefault
	Texprconst
	Texprvar
	Ttypenil
	Ttypeconst
	Ttypevar
	Ncase = 4
)

type Case struct {
	node    *Node
	hash    uint32
	type_   uint8
	diag    uint8
	ordinal uint16
	link    *Case
}

var C *Case

func dumpcase(c0 *Case) {
	var c *Case

	for c = c0; c != nil; c = c.link {
		switch c.type_ {
		case Tdefault:
			fmt.Printf("case-default\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case Texprconst:
			fmt.Printf("case-exprconst\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case Texprvar:
			fmt.Printf("case-exprvar\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\top=%v\n", Oconv(int(c.node.Left.Op), 0))

		case Ttypenil:
			fmt.Printf("case-typenil\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case Ttypeconst:
			fmt.Printf("case-typeconst\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\thash=%x\n", c.hash)

		case Ttypevar:
			fmt.Printf("case-typevar\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		default:
			fmt.Printf("case-???\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\top=%v\n", Oconv(int(c.node.Left.Op), 0))
			fmt.Printf("\thash=%x\n", c.hash)
		}
	}

	fmt.Printf("\n")
}

func ordlcmp(c1 *Case, c2 *Case) int {
	// sort default first
	if c1.type_ == Tdefault {
		return -1
	}
	if c2.type_ == Tdefault {
		return +1
	}

	// sort nil second
	if c1.type_ == Ttypenil {
		return -1
	}
	if c2.type_ == Ttypenil {
		return +1
	}

	// sort by ordinal
	if c1.ordinal > c2.ordinal {
		return +1
	}
	if c1.ordinal < c2.ordinal {
		return -1
	}
	return 0
}

func exprcmp(c1 *Case, c2 *Case) int {
	var ct int
	var n int
	var n1 *Node
	var n2 *Node

	// sort non-constants last
	if c1.type_ != Texprconst {
		return +1
	}
	if c2.type_ != Texprconst {
		return -1
	}

	n1 = c1.node.Left
	n2 = c2.node.Left

	// sort by type (for switches on interface)
	ct = int(n1.Val.Ctype)

	if ct != int(n2.Val.Ctype) {
		return ct - int(n2.Val.Ctype)
	}
	if !Eqtype(n1.Type, n2.Type) {
		if n1.Type.Vargen > n2.Type.Vargen {
			return +1
		} else {
			return -1
		}
	}

	// sort by constant value
	n = 0

	switch ct {
	case CTFLT:
		n = mpcmpfltflt(n1.Val.U.Fval, n2.Val.U.Fval)

	case CTINT,
		CTRUNE:
		n = Mpcmpfixfix(n1.Val.U.Xval, n2.Val.U.Xval)

	case CTSTR:
		n = cmpslit(n1, n2)
	}

	return n
}

func typecmp(c1 *Case, c2 *Case) int {
	// sort non-constants last
	if c1.type_ != Ttypeconst {
		return +1
	}
	if c2.type_ != Ttypeconst {
		return -1
	}

	// sort by hash code
	if c1.hash > c2.hash {
		return +1
	}
	if c1.hash < c2.hash {
		return -1
	}

	// sort by ordinal so duplicate error
	// happens on later case.
	if c1.ordinal > c2.ordinal {
		return +1
	}
	if c1.ordinal < c2.ordinal {
		return -1
	}
	return 0
}

func csort(l *Case, f func(*Case, *Case) int) *Case {
	var l1 *Case
	var l2 *Case
	var le *Case

	if l == nil || l.link == nil {
		return l
	}

	l1 = l
	l2 = l
	for {
		l2 = l2.link
		if l2 == nil {
			break
		}
		l2 = l2.link
		if l2 == nil {
			break
		}
		l1 = l1.link
	}

	l2 = l1.link
	l1.link = nil
	l1 = csort(l, f)
	l2 = csort(l2, f)

	/* set up lead element */
	if f(l1, l2) < 0 {
		l = l1
		l1 = l1.link
	} else {
		l = l2
		l2 = l2.link
	}

	le = l

	for {
		if l1 == nil {
			for l2 != nil {
				le.link = l2
				le = l2
				l2 = l2.link
			}

			le.link = nil
			break
		}

		if l2 == nil {
			for l1 != nil {
				le.link = l1
				le = l1
				l1 = l1.link
			}

			break
		}

		if f(l1, l2) < 0 {
			le.link = l1
			le = l1
			l1 = l1.link
		} else {
			le.link = l2
			le = l2
			l2 = l2.link
		}
	}

	le.link = nil
	return l
}

var newlabel_swt_label int

func newlabel_swt() *Node {
	newlabel_swt_label++
	namebuf = fmt.Sprintf("%.6d", newlabel_swt_label)
	return newname(Lookup(namebuf))
}

/*
 * build separate list of statements and cases
 * make labels between cases and statements
 * deal with fallthrough, break, unreachable statements
 */
func casebody(sw *Node, typeswvar *Node) {
	var n *Node
	var c *Node
	var last *Node
	var def *Node
	var cas *NodeList
	var stat *NodeList
	var l *NodeList
	var lc *NodeList
	var go_ *Node
	var br *Node
	var lno int32
	var needvar bool

	if sw.List == nil {
		return
	}

	lno = setlineno(sw)

	cas = nil  // cases
	stat = nil // statements
	def = nil  // defaults
	br = Nod(OBREAK, nil, nil)

	for l = sw.List; l != nil; l = l.Next {
		n = l.N
		setlineno(n)
		if n.Op != OXCASE {
			Fatal("casebody %v", Oconv(int(n.Op), 0))
		}
		n.Op = OCASE
		needvar = count(n.List) != 1 || n.List.N.Op == OLITERAL

		go_ = Nod(OGOTO, newlabel_swt(), nil)
		if n.List == nil {
			if def != nil {
				Yyerror("more than one default case")
			}

			// reuse original default case
			n.Right = go_

			def = n
		}

		if n.List != nil && n.List.Next == nil {
			// one case - reuse OCASE node.
			c = n.List.N

			n.Left = c
			n.Right = go_
			n.List = nil
			cas = list(cas, n)
		} else {
			// expand multi-valued cases
			for lc = n.List; lc != nil; lc = lc.Next {
				c = lc.N
				cas = list(cas, Nod(OCASE, c, go_))
			}
		}

		stat = list(stat, Nod(OLABEL, go_.Left, nil))
		if typeswvar != nil && needvar && n.Nname != nil {
			var l *NodeList

			l = list1(Nod(ODCL, n.Nname, nil))
			l = list(l, Nod(OAS, n.Nname, typeswvar))
			typechecklist(l, Etop)
			stat = concat(stat, l)
		}

		stat = concat(stat, n.Nbody)

		// botch - shouldn't fall thru declaration
		last = stat.End.N

		if last.Xoffset == n.Xoffset && last.Op == OXFALL {
			if typeswvar != nil {
				setlineno(last)
				Yyerror("cannot fallthrough in type switch")
			}

			if l.Next == nil {
				setlineno(last)
				Yyerror("cannot fallthrough final case in switch")
			}

			last.Op = OFALL
		} else {
			stat = list(stat, br)
		}
	}

	stat = list(stat, br)
	if def != nil {
		cas = list(cas, def)
	}

	sw.List = cas
	sw.Nbody = stat
	lineno = lno
}

func mkcaselist(sw *Node, arg int) *Case {
	var n *Node
	var c *Case
	var c1 *Case
	var c2 *Case
	var l *NodeList
	var ord int

	c = nil
	ord = 0

	for l = sw.List; l != nil; l = l.Next {
		n = l.N
		c1 = new(Case)
		c1.link = c
		c = c1

		ord++
		if int(uint16(ord)) != ord {
			Fatal("too many cases in switch")
		}
		c.ordinal = uint16(ord)
		c.node = n

		if n.Left == nil {
			c.type_ = Tdefault
			continue
		}

		switch arg {
		case Stype:
			c.hash = 0
			if n.Left.Op == OLITERAL {
				c.type_ = Ttypenil
				continue
			}

			if Istype(n.Left.Type, TINTER) {
				c.type_ = Ttypevar
				continue
			}

			c.hash = typehash(n.Left.Type)
			c.type_ = Ttypeconst
			continue

		case Snorm,
			Strue,
			Sfalse:
			c.type_ = Texprvar
			c.hash = typehash(n.Left.Type)
			switch consttype(n.Left) {
			case CTFLT,
				CTINT,
				CTRUNE,
				CTSTR:
				c.type_ = Texprconst
			}

			continue
		}
	}

	if c == nil {
		return nil
	}

	// sort by value and diagnose duplicate cases
	switch arg {
	case Stype:
		c = csort(c, typecmp)
		for c1 = c; c1 != nil; c1 = c1.link {
			for c2 = c1.link; c2 != nil && c2.hash == c1.hash; c2 = c2.link {
				if c1.type_ == Ttypenil || c1.type_ == Tdefault {
					break
				}
				if c2.type_ == Ttypenil || c2.type_ == Tdefault {
					break
				}
				if !Eqtype(c1.node.Left.Type, c2.node.Left.Type) {
					continue
				}
				yyerrorl(int(c2.node.Lineno), "duplicate case %v in type switch\n\tprevious case at %v", Tconv(c2.node.Left.Type, 0), c1.node.Line())
			}
		}

	case Snorm,
		Strue,
		Sfalse:
		c = csort(c, exprcmp)
		for c1 = c; c1.link != nil; c1 = c1.link {
			if exprcmp(c1, c1.link) != 0 {
				continue
			}
			setlineno(c1.link.node)
			Yyerror("duplicate case %v in switch\n\tprevious case at %v", Nconv(c1.node.Left, 0), c1.node.Line())
		}
	}

	// put list back in processing order
	c = csort(c, ordlcmp)

	return c
}

var exprname *Node

func exprbsw(c0 *Case, ncase int, arg int) *Node {
	var cas *NodeList
	var a *Node
	var n *Node
	var c *Case
	var i int
	var half int
	var lno int

	cas = nil
	if ncase < Ncase {
		for i = 0; i < ncase; i++ {
			n = c0.node
			lno = int(setlineno(n))

			if (arg != Strue && arg != Sfalse) || assignop(n.Left.Type, exprname.Type, nil) == OCONVIFACE || assignop(exprname.Type, n.Left.Type, nil) == OCONVIFACE {
				a = Nod(OIF, nil, nil)
				a.Ntest = Nod(OEQ, exprname, n.Left) // if name == val
				typecheck(&a.Ntest, Erv)
				a.Nbody = list1(n.Right) // then goto l
			} else if arg == Strue {
				a = Nod(OIF, nil, nil)
				a.Ntest = n.Left         // if val
				a.Nbody = list1(n.Right) // then goto l // arg == Sfalse
			} else {
				a = Nod(OIF, nil, nil)
				a.Ntest = Nod(ONOT, n.Left, nil) // if !val
				typecheck(&a.Ntest, Erv)
				a.Nbody = list1(n.Right) // then goto l
			}

			cas = list(cas, a)
			c0 = c0.link
			lineno = int32(lno)
		}

		return liststmt(cas)
	}

	// find the middle and recur
	c = c0

	half = ncase >> 1
	for i = 1; i < half; i++ {
		c = c.link
	}
	a = Nod(OIF, nil, nil)
	a.Ntest = Nod(OLE, exprname, c.node.Left)
	typecheck(&a.Ntest, Erv)
	a.Nbody = list1(exprbsw(c0, half, arg))
	a.Nelse = list1(exprbsw(c.link, ncase-half, arg))
	return a
}

/*
 * normal (expression) switch.
 * rebuild case statements into if .. goto
 */
func exprswitch(sw *Node) {
	var def *Node
	var cas *NodeList
	var a *Node
	var c0 *Case
	var c *Case
	var c1 *Case
	var t *Type
	var arg int
	var ncase int

	casebody(sw, nil)

	arg = Snorm
	if Isconst(sw.Ntest, CTBOOL) {
		arg = Strue
		if sw.Ntest.Val.U.Bval == 0 {
			arg = Sfalse
		}
	}

	walkexpr(&sw.Ntest, &sw.Ninit)
	t = sw.Type
	if t == nil {
		return
	}

	/*
	 * convert the switch into OIF statements
	 */
	exprname = nil

	cas = nil
	if arg == Strue || arg == Sfalse {
		exprname = Nodbool(arg == Strue)
	} else if consttype(sw.Ntest) >= 0 {
		// leave constants to enable dead code elimination (issue 9608)
		exprname = sw.Ntest
	} else {
		exprname = temp(sw.Ntest.Type)
		cas = list1(Nod(OAS, exprname, sw.Ntest))
		typechecklist(cas, Etop)
	}

	c0 = mkcaselist(sw, arg)
	if c0 != nil && c0.type_ == Tdefault {
		def = c0.node.Right
		c0 = c0.link
	} else {
		def = Nod(OBREAK, nil, nil)
	}

loop:
	if c0 == nil {
		cas = list(cas, def)
		sw.Nbody = concat(cas, sw.Nbody)
		sw.List = nil
		walkstmtlist(sw.Nbody)
		return
	}

	// deal with the variables one-at-a-time
	if okforcmp[t.Etype] == 0 || c0.type_ != Texprconst {
		a = exprbsw(c0, 1, arg)
		cas = list(cas, a)
		c0 = c0.link
		goto loop
	}

	// do binary search on run of constants
	ncase = 1

	for c = c0; c.link != nil; c = c.link {
		if c.link.type_ != Texprconst {
			break
		}
		ncase++
	}

	// break the chain at the count
	c1 = c.link

	c.link = nil

	// sort and compile constants
	c0 = csort(c0, exprcmp)

	a = exprbsw(c0, ncase, arg)
	cas = list(cas, a)

	c0 = c1
	goto loop
}

var hashname *Node

var facename *Node

var boolname *Node

func typeone(t *Node) *Node {
	var init *NodeList
	var a *Node
	var b *Node
	var var_ *Node

	var_ = t.Nname
	init = nil
	if var_ == nil {
		typecheck(&nblank, Erv|Easgn)
		var_ = nblank
	} else {
		init = list1(Nod(ODCL, var_, nil))
	}

	a = Nod(OAS2, nil, nil)
	a.List = list(list1(var_), boolname) // var,bool =
	b = Nod(ODOTTYPE, facename, nil)
	b.Type = t.Left.Type // interface.(type)
	a.Rlist = list1(b)
	typecheck(&a, Etop)
	init = list(init, a)

	b = Nod(OIF, nil, nil)
	b.Ntest = boolname
	b.Nbody = list1(t.Right) // if bool { goto l }
	a = liststmt(list(init, b))
	return a
}

func typebsw(c0 *Case, ncase int) *Node {
	var cas *NodeList
	var a *Node
	var n *Node
	var c *Case
	var i int
	var half int

	cas = nil

	if ncase < Ncase {
		for i = 0; i < ncase; i++ {
			n = c0.node
			if c0.type_ != Ttypeconst {
				Fatal("typebsw")
			}
			a = Nod(OIF, nil, nil)
			a.Ntest = Nod(OEQ, hashname, Nodintconst(int64(c0.hash)))
			typecheck(&a.Ntest, Erv)
			a.Nbody = list1(n.Right)
			cas = list(cas, a)
			c0 = c0.link
		}

		return liststmt(cas)
	}

	// find the middle and recur
	c = c0

	half = ncase >> 1
	for i = 1; i < half; i++ {
		c = c.link
	}
	a = Nod(OIF, nil, nil)
	a.Ntest = Nod(OLE, hashname, Nodintconst(int64(c.hash)))
	typecheck(&a.Ntest, Erv)
	a.Nbody = list1(typebsw(c0, half))
	a.Nelse = list1(typebsw(c.link, ncase-half))
	return a
}

/*
 * convert switch of the form
 *	switch v := i.(type) { case t1: ..; case t2: ..; }
 * into if statements
 */
func typeswitch(sw *Node) {
	var def *Node
	var cas *NodeList
	var hash *NodeList
	var a *Node
	var n *Node
	var c *Case
	var c0 *Case
	var c1 *Case
	var ncase int
	var t *Type
	var v Val

	if sw.Ntest == nil {
		return
	}
	if sw.Ntest.Right == nil {
		setlineno(sw)
		Yyerror("type switch must have an assignment")
		return
	}

	walkexpr(&sw.Ntest.Right, &sw.Ninit)
	if !Istype(sw.Ntest.Right.Type, TINTER) {
		Yyerror("type switch must be on an interface")
		return
	}

	cas = nil

	/*
	 * predeclare temporary variables
	 * and the boolean var
	 */
	facename = temp(sw.Ntest.Right.Type)

	a = Nod(OAS, facename, sw.Ntest.Right)
	typecheck(&a, Etop)
	cas = list(cas, a)

	casebody(sw, facename)

	boolname = temp(Types[TBOOL])
	typecheck(&boolname, Erv)

	hashname = temp(Types[TUINT32])
	typecheck(&hashname, Erv)

	t = sw.Ntest.Right.Type
	if isnilinter(t) {
		a = syslook("efacethash", 1)
	} else {
		a = syslook("ifacethash", 1)
	}
	argtype(a, t)
	a = Nod(OCALL, a, nil)
	a.List = list1(facename)
	a = Nod(OAS, hashname, a)
	typecheck(&a, Etop)
	cas = list(cas, a)

	c0 = mkcaselist(sw, Stype)
	if c0 != nil && c0.type_ == Tdefault {
		def = c0.node.Right
		c0 = c0.link
	} else {
		def = Nod(OBREAK, nil, nil)
	}

	/*
	 * insert if statement into each case block
	 */
	for c = c0; c != nil; c = c.link {
		n = c.node
		switch c.type_ {
		case Ttypenil:
			v.Ctype = CTNIL
			a = Nod(OIF, nil, nil)
			a.Ntest = Nod(OEQ, facename, nodlit(v))
			typecheck(&a.Ntest, Erv)
			a.Nbody = list1(n.Right) // if i==nil { goto l }
			n.Right = a

		case Ttypevar,
			Ttypeconst:
			n.Right = typeone(n)
		}
	}

	/*
	 * generate list of if statements, binary search for constant sequences
	 */
	for c0 != nil {
		if c0.type_ != Ttypeconst {
			n = c0.node
			cas = list(cas, n.Right)
			c0 = c0.link
			continue
		}

		// identify run of constants
		c = c0
		c1 = c

		for c.link != nil && c.link.type_ == Ttypeconst {
			c = c.link
		}
		c0 = c.link
		c.link = nil

		// sort by hash
		c1 = csort(c1, typecmp)

		// for debugging: linear search
		if false {
			for c = c1; c != nil; c = c.link {
				n = c.node
				cas = list(cas, n.Right)
			}

			continue
		}

		// combine adjacent cases with the same hash
		ncase = 0

		for c = c1; c != nil; c = c.link {
			ncase++
			hash = list1(c.node.Right)
			for c.link != nil && c.link.hash == c.hash {
				hash = list(hash, c.link.node.Right)
				c.link = c.link.link
			}

			c.node.Right = liststmt(hash)
		}

		// binary search among cases to narrow by hash
		cas = list(cas, typebsw(c1, ncase))
	}

	if nerrors == 0 {
		cas = list(cas, def)
		sw.Nbody = concat(cas, sw.Nbody)
		sw.List = nil
		walkstmtlist(sw.Nbody)
	}
}

func walkswitch(sw *Node) {
	/*
	 * reorder the body into (OLIST, cases, statements)
	 * cases have OGOTO into statements.
	 * both have inserted OBREAK statements
	 */
	if sw.Ntest == nil {
		sw.Ntest = Nodbool(true)
		typecheck(&sw.Ntest, Erv)
	}

	if sw.Ntest.Op == OTYPESW {
		typeswitch(sw)

		//dump("sw", sw);
		return
	}

	exprswitch(sw)

	// Discard old AST elements after a walk. They can confuse racewealk.
	sw.Ntest = nil

	sw.List = nil
}

/*
 * type check switch statement
 */
func typecheckswitch(n *Node) {
	var top int
	var lno int
	var ptr int
	var nilonly string
	var t *Type
	var badtype *Type
	var missing *Type
	var have *Type
	var l *NodeList
	var ll *NodeList
	var ncase *Node
	var nvar *Node
	var def *Node

	lno = int(lineno)
	typechecklist(n.Ninit, Etop)
	nilonly = ""

	if n.Ntest != nil && n.Ntest.Op == OTYPESW {
		// type switch
		top = Etype

		typecheck(&n.Ntest.Right, Erv)
		t = n.Ntest.Right.Type
		if t != nil && t.Etype != TINTER {
			Yyerror("cannot type switch on non-interface value %v", Nconv(n.Ntest.Right, obj.FmtLong))
		}
	} else {
		// value switch
		top = Erv

		if n.Ntest != nil {
			typecheck(&n.Ntest, Erv)
			defaultlit(&n.Ntest, nil)
			t = n.Ntest.Type
		} else {
			t = Types[TBOOL]
		}
		if t != nil {
			if okforeq[t.Etype] == 0 {
				Yyerror("cannot switch on %v", Nconv(n.Ntest, obj.FmtLong))
			} else if t.Etype == TARRAY && !Isfixedarray(t) {
				nilonly = "slice"
			} else if t.Etype == TARRAY && Isfixedarray(t) && algtype1(t, nil) == ANOEQ {
				Yyerror("cannot switch on %v", Nconv(n.Ntest, obj.FmtLong))
			} else if t.Etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ {
				Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Ntest, obj.FmtLong), Tconv(badtype, 0))
			} else if t.Etype == TFUNC {
				nilonly = "func"
			} else if t.Etype == TMAP {
				nilonly = "map"
			}
		}
	}

	n.Type = t

	def = nil
	for l = n.List; l != nil; l = l.Next {
		ncase = l.N
		setlineno(n)
		if ncase.List == nil {
			// default
			if def != nil {
				Yyerror("multiple defaults in switch (first at %v)", def.Line())
			} else {
				def = ncase
			}
		} else {
			for ll = ncase.List; ll != nil; ll = ll.Next {
				setlineno(ll.N)
				typecheck(&ll.N, Erv|Etype)
				if ll.N.Type == nil || t == nil {
					continue
				}
				setlineno(ncase)
				switch top {
				case Erv: // expression switch
					defaultlit(&ll.N, t)

					if ll.N.Op == OTYPE {
						Yyerror("type %v is not an expression", Tconv(ll.N.Type, 0))
					} else if ll.N.Type != nil && assignop(ll.N.Type, t, nil) == 0 && assignop(t, ll.N.Type, nil) == 0 {
						if n.Ntest != nil {
							Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", Nconv(ll.N, 0), Nconv(n.Ntest, 0), Tconv(ll.N.Type, 0), Tconv(t, 0))
						} else {
							Yyerror("invalid case %v in switch (mismatched types %v and bool)", Nconv(ll.N, 0), Tconv(ll.N.Type, 0))
						}
					} else if nilonly != "" && !Isconst(ll.N, CTNIL) {
						Yyerror("invalid case %v in switch (can only compare %s %v to nil)", Nconv(ll.N, 0), nilonly, Nconv(n.Ntest, 0))
					}

				case Etype: // type switch
					if ll.N.Op == OLITERAL && Istype(ll.N.Type, TNIL) {
					} else if ll.N.Op != OTYPE && ll.N.Type != nil { // should this be ||?
						Yyerror("%v is not a type", Nconv(ll.N, obj.FmtLong))

						// reset to original type
						ll.N = n.Ntest.Right
					} else if ll.N.Type.Etype != TINTER && t.Etype == TINTER && !implements(ll.N.Type, t, &missing, &have, &ptr) {
						if have != nil && missing.Broke == 0 && have.Broke == 0 {
							Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Ntest.Right, obj.FmtLong), Tconv(ll.N.Type, 0), Sconv(missing.Sym, 0), Sconv(have.Sym, 0), Tconv(have.Type, obj.FmtShort), Sconv(missing.Sym, 0), Tconv(missing.Type, obj.FmtShort))
						} else if missing.Broke == 0 {
							Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Ntest.Right, obj.FmtLong), Tconv(ll.N.Type, 0), Sconv(missing.Sym, 0))
						}
					}
				}
			}
		}

		if top == Etype && n.Type != nil {
			ll = ncase.List
			nvar = ncase.Nname
			if nvar != nil {
				if ll != nil && ll.Next == nil && ll.N.Type != nil && !Istype(ll.N.Type, TNIL) {
					// single entry type switch
					nvar.Ntype = typenod(ll.N.Type)
				} else {
					// multiple entry type switch or default
					nvar.Ntype = typenod(n.Type)
				}

				typecheck(&nvar, Erv|Easgn)
				ncase.Nname = nvar
			}
		}

		typechecklist(ncase.Nbody, Etop)
	}

	lineno = int32(lno)
}
