code: func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) {
  	// Side effects of all LHSs and RHSs must occur in left-to-right order.
  	lvals := make([]lvalue, len(lhss))
  	isZero := make([]bool, len(lhss))
  	for i, lhs := range lhss {
  		var lval lvalue = blank{}
  		if !isBlankIdent(lhs) {
  			if isDef {
  				if obj := fn.Pkg.info.Defs[lhs.(*ast.Ident)]; obj != nil {
  					fn.addNamedLocal(obj)
  					isZero[i] = true
  				}
  			}
  			lval = b.addr(fn, lhs, false) // non-escaping
  		}
  		lvals[i] = lval
  	}
  	if len(lhss) == len(rhss) {
  		// Simple assignment:   x     = f()        (!isDef)
  		// Parallel assignment: x, y  = f(), g()   (!isDef)
  		// or short var decl:   x, y := f(), g()   (isDef)
  		//
  		// In all cases, the RHSs may refer to the LHSs,
  		// so we need a storebuf.
  		var sb storebuf
  		for i := range rhss {
  			b.assign(fn, lvals[i], rhss[i], isZero[i], &sb)
  		}
  		sb.emit(fn)
  	} else {
  		// e.g. x, y = pos()
  		tuple := b.exprN(fn, rhss[0])
  		emitDebugRef(fn, rhss[0], tuple, false)
  		for i, lval := range lvals {
  			lval.store(fn, emitExtract(fn, tuple, i))
  		}
  	}
  }
docs: // assignStmt emits code to fn for a parallel assignment of rhss to lhss.
  // isDef is true if this is a short variable declaration (:=).
  //
  // Note the similarity with localValueSpec.
  //