func (r errorReporter) nope(n ast.Node, msg string, args ...interface{}) {
	r.prefixed("impossible(go)", n, msg, args...)
}
nope reports a situation that I thought was impossible from reading the
documentation.
package goose
import (
	"bytes"
	"fmt"
	"go/ast"
	"go/printer"
	"go/token"
	"runtime"
	"strings"
)
type errorReporter struct {
	fset *token.FileSet
}
func newErrorReporter(fset *token.FileSet) errorReporter {
	return errorReporter{fset}
}
func (r errorReporter) printField(f *ast.Field) string {
	var what bytes.Buffer
	var names []string
	for _, n := range f.Names {
		names = append(names, n.Name)
	}
	err := printer.Fprint(&what, r.fset, f.Type)
	if err != nil {
		panic(err.Error())
	}
	return fmt.Sprintf("%s %s",
		strings.Join(names, ", "),
		what.String())
}
func (r errorReporter) printGo(n ast.Node) string {
	if f, ok := n.(*ast.Field); ok {
		return r.printField(f)
	}
	if fl, ok := n.(*ast.FieldList); ok {
		var fields []string
		for _, f := range fl.List {
			fields = append(fields, r.printField(f))
		}
		return strings.Join(fields, "; ")
	}
	var what bytes.Buffer
	err := printer.Fprint(&what, r.fset, n)
	if err != nil {
		panic(err.Error())
	}
	return what.String()
}
func getCaller(skip int) string {
	_, file, line, ok := runtime.Caller(1 + skip)
	if !ok {
		return "<no caller>"
	}
	return fmt.Sprintf("%s:%d", file, line)
}
type gooseError struct{ err *ConversionError }
type ConversionError struct {
	Category string
	Message string
	GoCode string
	GooseCaller string
	GoSrcFile string
	Pos, End token.Pos
}
func (e *ConversionError) Error() string {
	lines := []string{
		fmt.Sprintf("[%s]: %s", e.Category, e.Message),
		fmt.Sprintf("%s", e.GoCode),
		fmt.Sprintf("  %s", e.GooseCaller),
		fmt.Sprintf("  src: %s", e.GoSrcFile),
	}
	return strings.Join(lines, "\n")
}
func (r errorReporter) prefixed(prefix string, n ast.Node, msg string, args ...interface{}) {
	where := r.fset.Position(n.Pos())
	what := r.printGo(n)
	formatted := fmt.Sprintf(msg, args...)
	err := &ConversionError{
		Category:    prefix,
		Message:     formatted,
		GoCode:      what,
		GooseCaller: getCaller(2),
		GoSrcFile:   where.String(),
		Pos:         n.Pos(),
		End:         n.End(),
	}
	panic(gooseError{err: err})
}