func exprAssignableTo(from Expr, to reflect.Type) (bool, []error) {
	if len(from.KnownType()) != 1 {
		panic("go-eval: assignableTo called with from.KnownType() != 1")
	}
	fromType := from.KnownType()[0]
	if c, ok := fromType.(ConstType); ok && from.IsConst() {
		cv, errs := promoteConstToTyped(c, constValue(from.Const()), to, from)
		return reflect.Value(cv).IsValid(), errs
	}
	return typeAssignableTo(fromType, to), nil
}
Determine if the result of from expr is assignable to type to. to must be a vanilla reflect.Type.
from must have a KnownType() of length 1. Const types that raise overflow and truncation
errors will still return true, but the errors will be reflected in the []error slice.
package eval
import (
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"go/ast"
	"go/token"
)
func hackedNew(t reflect.Type) reflect.Value {
	return reflect.New(unhackType(t))
}
func unhackType(t reflect.Type) reflect.Type {
	switch tt := t.(type) {
	case Rune:
		return tt.Type
	case Byte:
		return tt.Type
	default:
		return t
	}
}
func typeAssignableTo(from, to reflect.Type) bool {
	return from.AssignableTo(unhackType(to))
}
func checkExprAssignableTo(expr ast.Expr, t reflect.Type, env Env) (Expr, bool, []error) {
	var errs []error
	aexpr, moreErrs := CheckExpr(expr, env)
	if moreErrs != nil {
		errs = append(errs, moreErrs...)
	} else if _, err := expectSingleType(aexpr); err != nil {
		errs = append(errs, err)
	}
	if errs != nil {
		return aexpr, true, errs
	}
	ok, convErrs := exprAssignableTo(aexpr, t)
	if convErrs != nil {
		errs = append(errs, convErrs...)
	}
	return aexpr, ok, errs
}