Commit 8d0bbe2b authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: implement fmt.Formatter for *Type formats %s, %v

Change-Id: I878ac549430abc7859c30d176d52d52ce02c5827
Reviewed-on: https://go-review.googlesource.com/28333Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 97ba3c82
......@@ -231,7 +231,7 @@ func gmove(f *gc.Node, t *gc.Node) {
default:
gc.Dump("f", f)
gc.Dump("t", t)
gc.Fatalf("gmove %v -> %v", gc.Tconv(f.Type, gc.FmtLong), gc.Tconv(t.Type, gc.FmtLong))
gc.Fatalf("gmove %2v -> %2v", f.Type, t.Type)
/*
* integer copy and truncate
......
......@@ -210,7 +210,7 @@ func gmove(f *gc.Node, t *gc.Node) {
switch uint32(ft)<<16 | uint32(tt) {
default:
gc.Fatalf("gmove %v -> %v", gc.Tconv(f.Type, gc.FmtLong), gc.Tconv(t.Type, gc.FmtLong))
gc.Fatalf("gmove %2v -> %2v", f.Type, t.Type)
/*
* integer copy and truncate
......
......@@ -75,7 +75,7 @@ func widstruct(errtype *Type, t *Type, o int64, flag int) int64 {
}
o += w
if o >= Thearch.MAXWIDTH {
Yyerror("type %v too large", Tconv(errtype, FmtLong))
Yyerror("type %2v too large", errtype)
o = 8 // small but nonzero
}
}
......@@ -253,7 +253,7 @@ func dowidth(t *Type) {
if t.Elem().Width != 0 {
cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
if uint64(t.NumElem()) > cap {
Yyerror("type %v larger than address space", Tconv(t, FmtLong))
Yyerror("type %2v larger than address space", t)
}
}
w = t.NumElem() * t.Elem().Width
......
......@@ -807,7 +807,7 @@ func (p *exporter) typ(t *Type) {
p.typ(t.Elem())
default:
Fatalf("exporter: unexpected type: %s (Etype = %d)", Tconv(t, 0), t.Etype)
Fatalf("exporter: unexpected type: %s (Etype = %d)", t, t.Etype)
}
}
......
......@@ -235,7 +235,7 @@ func (p *importer) verifyTypes() {
pt := pair.pt
t := pair.t
if !Eqtype(pt.Orig, t) {
formatErrorf("inconsistent definition for type %v during import\n\t%v (in %q)\n\t%v (in %q)", pt.Sym, Tconv(pt, FmtLong), pt.Sym.Importdef.Path, Tconv(t, FmtLong), importpkg.Path)
formatErrorf("inconsistent definition for type %v during import\n\t%2v (in %q)\n\t%2v (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
}
}
}
......@@ -416,7 +416,7 @@ func (p *importer) importtype(pt, t *Type) {
}
if Debug['E'] != 0 {
fmt.Printf("import type %v %v\n", pt, Tconv(t, FmtLong))
fmt.Printf("import type %v %2v\n", pt, t)
}
}
......
......@@ -599,7 +599,7 @@ func cgen_wb(n, res *Node, wb bool) {
break
}
Fatalf("cgen: OLEN: unknown type %v", Tconv(nl.Type, FmtLong))
Fatalf("cgen: OLEN: unknown type %2v", nl.Type)
case OCAP:
if nl.Type.IsChan() {
......@@ -637,7 +637,7 @@ func cgen_wb(n, res *Node, wb bool) {
break
}
Fatalf("cgen: OCAP: unknown type %v", Tconv(nl.Type, FmtLong))
Fatalf("cgen: OCAP: unknown type %2v", nl.Type)
case OADDR:
if n.Bounded { // let race detector avoid nil checks
......
......@@ -540,9 +540,9 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
rcvrtype := fn.Left.Type
if exportname(meth.Name) {
p = fmt.Sprintf("(%v).%s-fm", Tconv(rcvrtype, FmtLeft|FmtShort), meth.Name)
p = fmt.Sprintf("(%-1v).%s-fm", rcvrtype, meth.Name)
} else {
p = fmt.Sprintf("(%v).(%v)-fm", Tconv(rcvrtype, FmtLeft|FmtShort), sconv(meth, FmtLeft))
p = fmt.Sprintf("(%-1v).(%v)-fm", rcvrtype, sconv(meth, FmtLeft))
}
basetype := rcvrtype
if rcvrtype.IsPtr() {
......
......@@ -1595,7 +1595,7 @@ func (n *Node) Convconst(con *Node, t *Type) {
var i int64
switch n.Val().Ctype() {
default:
Fatalf("convconst ctype=%d %v", n.Val().Ctype(), Tconv(t, FmtLong))
Fatalf("convconst ctype=%d %2v", n.Val().Ctype(), t)
case CTINT, CTRUNE:
i = n.Int64()
......@@ -1632,7 +1632,7 @@ func (n *Node) Convconst(con *Node, t *Type) {
return
}
Fatalf("convconst %v constant", Tconv(t, FmtLong))
Fatalf("convconst %2v constant", t)
}
// complex multiply v *= rv
......
......@@ -1095,15 +1095,15 @@ func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
if t0.Sym == nil && t0.IsPtr() {
p = fmt.Sprintf("(%v).%s.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
p = fmt.Sprintf("(%-1v).%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix)
} else {
p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
p = fmt.Sprintf("%-1v.%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix)
}
} else {
if t0.Sym == nil && t0.IsPtr() {
p = fmt.Sprintf("(%v).%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Name, suffix)
p = fmt.Sprintf("(%-1v).%s%s", t0, nsym.Name, suffix)
} else {
p = fmt.Sprintf("%v.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Name, suffix)
p = fmt.Sprintf("%-1v.%s%s", t0, nsym.Name, suffix)
}
}
......@@ -1190,7 +1190,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
default:
// Should have picked off all the reasons above,
// but just in case, fall back to generic error.
Yyerror("invalid receiver type %v (%v / %v)", pa, Tconv(pa, FmtLong), Tconv(t, FmtLong))
Yyerror("invalid receiver type %v (%2v / %2v)", pa, pa, t)
}
return
}
......
......@@ -340,7 +340,7 @@ func importvar(s *Sym, t *Type) {
declare(n, PEXTERN)
if Debug['E'] != 0 {
fmt.Printf("import var %v %v\n", s, Tconv(t, FmtLong))
fmt.Printf("import var %v %2v\n", s, t)
}
}
......@@ -362,11 +362,11 @@ func importtype(pt *Type, t *Type) {
declare(n, PEXTERN)
checkwidth(pt)
} else if !Eqtype(pt.Orig, t) {
Yyerror("inconsistent definition for type %v during import\n\t%v (in %q)\n\t%v (in %q)", pt.Sym, Tconv(pt, FmtLong), pt.Sym.Importdef.Path, Tconv(t, FmtLong), importpkg.Path)
Yyerror("inconsistent definition for type %v during import\n\t%2v (in %q)\n\t%2v (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
}
if Debug['E'] != 0 {
fmt.Printf("import type %v %v\n", pt, Tconv(t, FmtLong))
fmt.Printf("import type %v %2v\n", pt, t)
}
}
......
......@@ -585,21 +585,24 @@ var basicnames = []string{
TBLANK: "blank",
}
func (p *printer) typefmt(t *Type, flag FmtFlag) *printer {
func (t *Type) typefmt(s fmt.State, flag FmtFlag) {
if t == nil {
return p.s("<T>")
fmt.Fprint(s, "<T>")
return
}
if t == bytetype || t == runetype {
// in %-T mode collapse rune and byte with their originals.
if fmtmode != FTypeId {
return p.sconv(t.Sym, FmtShort)
fmt.Fprintf(s, "%1v", t.Sym)
return
}
t = Types[t.Etype]
}
if t == errortype {
return p.s("error")
fmt.Fprint(s, "error")
return
}
// Unless the 'l' flag was specified, if the type has a name, just print that name.
......@@ -608,120 +611,134 @@ func (p *printer) typefmt(t *Type, flag FmtFlag) *printer {
case FTypeId:
if flag&FmtShort != 0 {
if t.Vargen != 0 {
return p.f("%v·%d", sconv(t.Sym, FmtShort), t.Vargen)
fmt.Fprintf(s, "%v·%d", sconv(t.Sym, FmtShort), t.Vargen)
return
}
return p.sconv(t.Sym, FmtShort)
fmt.Fprint(s, sconv(t.Sym, FmtShort))
return
}
if flag&FmtUnsigned != 0 {
return p.sconv(t.Sym, FmtUnsigned)
fmt.Fprint(s, sconv(t.Sym, FmtUnsigned))
return
}
if t.Sym.Pkg == localpkg && t.Vargen != 0 {
return p.f("%v·%d", t.Sym, t.Vargen)
fmt.Fprintf(s, "%v·%d", t.Sym, t.Vargen)
return
}
}
return p.sconv(t.Sym, 0)
fmt.Fprint(s, sconv(t.Sym, 0))
return
}
if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" {
if fmtmode == FErr && (t == idealbool || t == idealstring) {
p.s("untyped ")
fmt.Fprint(s, "untyped ")
}
return p.s(basicnames[t.Etype])
fmt.Fprint(s, basicnames[t.Etype])
return
}
if fmtmode == FDbg {
fmtmode = 0
p.s(t.Etype.String()).s("-").typefmt(t, flag)
fmt.Fprintf(s, "%v-", t.Etype)
t.typefmt(s, flag)
fmtmode = FDbg
return p
return
}
switch t.Etype {
case TPTR32, TPTR64:
if fmtmode == FTypeId && (flag&FmtShort != 0) {
return p.s("*" + Tconv(t.Elem(), FmtShort))
fmt.Fprintf(s, "*%1v", t.Elem())
return
}
return p.s("*" + t.Elem().String())
fmt.Fprint(s, "*"+t.Elem().String())
return
case TARRAY:
if t.isDDDArray() {
return p.s("[...]" + t.Elem().String())
fmt.Fprint(s, "[...]"+t.Elem().String())
return
}
return p.f("[%d]%v", t.NumElem(), t.Elem())
fmt.Fprintf(s, "[%d]%v", t.NumElem(), t.Elem())
return
case TSLICE:
return p.s("[]" + t.Elem().String())
fmt.Fprint(s, "[]"+t.Elem().String())
return
case TCHAN:
switch t.ChanDir() {
case Crecv:
return p.s("<-chan " + t.Elem().String())
fmt.Fprint(s, "<-chan "+t.Elem().String())
return
case Csend:
return p.s("chan<- " + t.Elem().String())
fmt.Fprint(s, "chan<- "+t.Elem().String())
return
}
if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == Crecv {
return p.s("chan (" + t.Elem().String() + ")")
fmt.Fprint(s, "chan ("+t.Elem().String()+")")
return
}
return p.s("chan " + t.Elem().String())
fmt.Fprint(s, "chan "+t.Elem().String())
return
case TMAP:
return p.s("map[" + t.Key().String() + "]" + t.Val().String())
fmt.Fprint(s, "map["+t.Key().String()+"]"+t.Val().String())
return
case TINTER:
p.s("interface {")
fmt.Fprint(s, "interface {")
for i, f := range t.Fields().Slice() {
if i != 0 {
p.s(";")
fmt.Fprint(s, ";")
}
p.s(" ")
fmt.Fprint(s, " ")
switch {
case f.Sym == nil:
// Check first that a symbol is defined for this type.
// Wrong interface definitions may have types lacking a symbol.
break
case exportname(f.Sym.Name):
p.sconv(f.Sym, FmtShort)
fmt.Fprint(s, sconv(f.Sym, FmtShort))
default:
p.sconv(f.Sym, FmtUnsigned)
fmt.Fprint(s, sconv(f.Sym, FmtUnsigned))
}
p.Tconv(f.Type, FmtShort)
fmt.Fprintf(s, "%1v", f.Type)
}
if t.NumFields() != 0 {
p.s(" ")
fmt.Fprint(s, " ")
}
return p.s("}")
fmt.Fprint(s, "}")
return
case TFUNC:
if flag&FmtShort != 0 {
// no leading func
} else {
if t.Recv() != nil {
p.s("method")
p.Tconv(t.Recvs(), 0)
p.s(" ")
fmt.Fprintf(s, "method %v ", t.Recvs())
}
p.s("func")
fmt.Fprint(s, "func")
}
p.Tconv(t.Params(), 0)
fmt.Fprintf(s, "%v", t.Params())
switch t.Results().NumFields() {
case 0:
// nothing to do
case 1:
p.s(" ")
p.Tconv(t.Results().Field(0).Type, 0) // struct->field->field's type
fmt.Fprintf(s, " %v", t.Results().Field(0).Type) // struct->field->field's type
default:
p.s(" ")
p.Tconv(t.Results(), 0)
fmt.Fprintf(s, " %v", t.Results())
}
return p
return
case TSTRUCT:
if m := t.StructType().Map; m != nil {
......@@ -729,67 +746,75 @@ func (p *printer) typefmt(t *Type, flag FmtFlag) *printer {
// Format the bucket struct for map[x]y as map.bucket[x]y.
// This avoids a recursive print that generates very long names.
if mt.Bucket == t {
return p.s("map.bucket[" + m.Key().String() + "]" + m.Val().String())
fmt.Fprint(s, "map.bucket["+m.Key().String()+"]"+m.Val().String())
return
}
if mt.Hmap == t {
return p.s("map.hdr[" + m.Key().String() + "]" + m.Val().String())
fmt.Fprint(s, "map.hdr["+m.Key().String()+"]"+m.Val().String())
return
}
if mt.Hiter == t {
return p.s("map.iter[" + m.Key().String() + "]" + m.Val().String())
fmt.Fprint(s, "map.iter["+m.Key().String()+"]"+m.Val().String())
return
}
Yyerror("unknown internal map type")
}
if t.IsFuncArgStruct() {
p.s("(")
fmt.Fprint(s, "(")
var flag1 FmtFlag
if fmtmode == FTypeId || fmtmode == FErr { // no argument names on function signature, and no "noescape"/"nosplit" tags
flag1 = FmtShort
}
for i, f := range t.Fields().Slice() {
if i != 0 {
p.s(", ")
fmt.Fprint(s, ", ")
}
p.s(Fldconv(f, flag1))
fmt.Fprint(s, Fldconv(f, flag1))
}
p.s(")")
fmt.Fprint(s, ")")
} else {
p.s("struct {")
fmt.Fprint(s, "struct {")
for i, f := range t.Fields().Slice() {
if i != 0 {
p.s(";")
fmt.Fprint(s, ";")
}
p.s(" ")
p.s(Fldconv(f, FmtLong))
fmt.Fprint(s, " ")
fmt.Fprint(s, Fldconv(f, FmtLong))
}
if t.NumFields() != 0 {
p.s(" ")
fmt.Fprint(s, " ")
}
p.s("}")
fmt.Fprint(s, "}")
}
return p
return
case TFORW:
if t.Sym != nil {
return p.s("undefined " + t.Sym.String())
fmt.Fprint(s, "undefined "+t.Sym.String())
return
}
return p.s("undefined")
fmt.Fprint(s, "undefined")
return
case TUNSAFEPTR:
return p.s("unsafe.Pointer")
fmt.Fprint(s, "unsafe.Pointer")
return
case TDDDFIELD:
return p.f("%v <%v> %v", t.Etype, t.Sym, t.DDDField())
fmt.Fprintf(s, "%v <%v> %v", t.Etype, t.Sym, t.DDDField())
return
case Txxx:
return p.s("Txxx")
fmt.Fprint(s, "Txxx")
return
}
// Don't know how to handle - fall back to detailed prints.
return p.f("%v <%v> %v", t.Etype, t.Sym, t.Elem())
fmt.Fprintf(s, "%v <%v> %v", t.Etype, t.Sym, t.Elem())
}
// Statements which may be rendered with a simplestmt as init.
......@@ -1175,7 +1200,7 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
if n.Type == nil && n.Sym != nil {
return p.sconv(n.Sym, 0)
}
return p.Tconv(n.Type, 0)
return p.f("%v", n.Type)
case OTARRAY:
if n.Left != nil {
......@@ -1572,14 +1597,8 @@ func (p *printer) sconv(s *Sym, flag FmtFlag) *printer {
return p
}
func (t *Type) Print(p *printer) {
p.Tconv(t, 0)
}
var _ Printable = new(Type) // verify Type implements Printable
func (t *Type) String() string {
return Tconv(t, 0)
return fmt.Sprint(t)
}
func Fldconv(f *Field, flag FmtFlag) string {
......@@ -1634,9 +1653,9 @@ func Fldconv(f *Field, flag FmtFlag) string {
var typ string
if f.Isddd {
typ = "..." + Tconv(f.Type.Elem(), 0)
typ = fmt.Sprintf("...%v", f.Type.Elem())
} else {
typ = Tconv(f.Type, 0)
typ = fmt.Sprintf("%v", f.Type)
}
str := typ
......@@ -1657,21 +1676,31 @@ func Fldconv(f *Field, flag FmtFlag) string {
return str
}
func (t *Type) Format(s fmt.State, format rune) {
switch format {
case 's', 'v':
t.tconv(s)
default:
fmt.Fprintf(s, "%%!%c(*Type=%p)", format, t)
}
}
// Fmt "%T": types.
// Flags: 'l' print definition, not name
// 'h' omit 'func' and receiver from function types, short type names
// 'u' package name, not prefix (FTypeId mode, sticky)
func Tconv(t *Type, flag FmtFlag) string {
return new(printer).Tconv(t, flag).String()
}
func (t *Type) tconv(s fmt.State) {
flag := fmtFlag(s)
func (p *printer) Tconv(t *Type, flag FmtFlag) *printer {
if t == nil {
return p.s("<T>")
fmt.Fprint(s, "<T>")
return
}
if t.Trecur > 4 {
return p.s("<...>")
fmt.Fprint(s, "<...>")
return
}
t.Trecur++
......@@ -1685,7 +1714,7 @@ func (p *printer) Tconv(t *Type, flag FmtFlag) *printer {
flag |= FmtUnsigned
}
p.typefmt(t, flag)
t.typefmt(s, flag)
if fmtmode == FTypeId && (sf&FmtUnsigned != 0) {
fmtpkgpfx--
......@@ -1694,8 +1723,6 @@ func (p *printer) Tconv(t *Type, flag FmtFlag) *printer {
flag = sf
fmtmode = sm
t.Trecur--
return p
}
func (n *Node) Print(p *printer) {
......
......@@ -1208,7 +1208,7 @@ func componentgen_wb(nr, nl *Node, wb bool) bool {
visitComponents(nl.Type, 0, func(t *Type, offset int64) bool {
if wb && Simtype[t.Etype] == Tptr && t != itable {
if ptrType != nil {
Fatalf("componentgen_wb %v", Tconv(nl.Type, 0))
Fatalf("componentgen_wb %v", nl.Type)
}
ptrType = t
ptrOffset = offset
......
......@@ -420,7 +420,7 @@ func Naddr(a *obj.Addr, n *Node) {
}
switch u := n.Val().U.(type) {
default:
Fatalf("naddr: const %v", Tconv(n.Type, FmtLong))
Fatalf("naddr: const %2v", n.Type)
case *Mpflt:
a.Type = obj.TYPE_FCONST
......
......@@ -165,7 +165,7 @@ func caninl(fn *Node) {
fn.Type.SetNname(n)
if Debug['m'] > 1 {
fmt.Printf("%v: can inline %v as: %v { %v }\n", fn.Line(), Nconv(n, FmtSharp), Tconv(fn.Type, FmtSharp), hconv(n.Func.Inl, FmtSharp))
fmt.Printf("%v: can inline %v as: %#v { %v }\n", fn.Line(), Nconv(n, FmtSharp), fn.Type, hconv(n.Func.Inl, FmtSharp))
} else if Debug['m'] != 0 {
fmt.Printf("%v: can inline %v\n", fn.Line(), n)
}
......@@ -214,7 +214,7 @@ func ishairy(n *Node, budget *int32, reason *string) bool {
Fatalf("no function type for [%p] %v\n", n.Left, Nconv(n.Left, FmtSign))
}
if t.Nname() == nil {
Fatalf("no function definition for [%p] %v\n", t, Tconv(t, FmtSign))
Fatalf("no function definition for [%p] %+v\n", t, t)
}
if inlfn := t.Nname().Func; inlfn.Inl.Len() != 0 {
*budget -= inlfn.InlCost
......@@ -494,7 +494,7 @@ func inlnode(n *Node) *Node {
}
if n.Left.Type.Nname() == nil {
Fatalf("no function definition for [%p] %v\n", n.Left.Type, Tconv(n.Left.Type, FmtSign))
Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type)
}
n = mkinlcall(n, n.Left.Type.Nname(), n.Isddd)
......@@ -556,7 +556,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
// Bingo, we have a function node, and it has an inlineable body
if Debug['m'] > 1 {
fmt.Printf("%v: inlining call to %v %v { %v }\n", n.Line(), fn.Sym, Tconv(fn.Type, FmtSharp), hconv(fn.Func.Inl, FmtSharp))
fmt.Printf("%v: inlining call to %v %#v { %v }\n", n.Line(), fn.Sym, fn.Type, hconv(fn.Func.Inl, FmtSharp))
} else if Debug['m'] != 0 {
fmt.Printf("%v: inlining call to %v\n", n.Line(), fn)
}
......@@ -752,7 +752,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
}
if li < n.List.Len() || t != nil {
Fatalf("arg count mismatch: %v vs %v\n", Tconv(fn.Type.Params(), FmtSharp), hconv(n.List, FmtComma))
Fatalf("arg count mismatch: %#v vs %v\n", fn.Type.Params(), hconv(n.List, FmtComma))
}
}
......
......@@ -864,7 +864,7 @@ func dcommontype(s *Sym, ot int, t *Type) int {
}
exported := false
p := Tconv(t, FmtLeft|FmtUnsigned)
p := fmt.Sprintf("%- v", t)
// If we're writing out type T,
// we are very likely to write out type *T as well.
// Use the string "*T"[1:] for "T", so that the two
......@@ -926,22 +926,22 @@ func dcommontype(s *Sym, ot int, t *Type) int {
}
func typesym(t *Type) *Sym {
return Pkglookup(Tconv(t, FmtLeft), typepkg)
return Pkglookup(fmt.Sprintf("%-v", t), typepkg)
}
// tracksym returns the symbol for tracking use of field/method f, assumed
// to be a member of struct/interface type t.
func tracksym(t *Type, f *Field) *Sym {
return Pkglookup(Tconv(t, FmtLeft)+"."+f.Sym.Name, trackpkg)
return Pkglookup(fmt.Sprintf("%-v.%s", t, f.Sym.Name), trackpkg)
}
func typelinkLSym(t *Type) *obj.LSym {
name := "go.typelink." + Tconv(t, FmtLeft) // complete, unambiguous type name
name := fmt.Sprintf("go.typelink.%-v", t) // complete, unambiguous type name
return obj.Linklookup(Ctxt, name, 0)
}
func typesymprefix(prefix string, t *Type) *Sym {
p := prefix + "." + Tconv(t, FmtLeft)
p := fmt.Sprintf("%s.%-v", prefix, t)
s := Pkglookup(p, typepkg)
//print("algsym: %s -> %+S\n", p, s);
......@@ -981,7 +981,7 @@ func itabname(t, itype *Type) *Node {
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
Fatalf("itabname %v", t)
}
s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itabpkg)
s := Pkglookup(fmt.Sprintf("%-v,%-v", t, itype), itabpkg)
if s.Def == nil {
n := newname(s)
n.Type = Types[TUINT8]
......@@ -1406,7 +1406,7 @@ func dumptypestructs() {
// method functions. None are allocated on heap, so we can use obj.NOPTR.
ggloblsym(i.sym, int32(o), int16(obj.DUPOK|obj.NOPTR))
ilink := Pkglookup(Tconv(i.t, FmtLeft)+","+Tconv(i.itype, FmtLeft), itablinkpkg)
ilink := Pkglookup(fmt.Sprintf("%-v,%-v", i.t, i.itype), itablinkpkg)
dsymptr(ilink, 0, i.sym, 0)
ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
}
......
......@@ -810,11 +810,11 @@ func assignop(src *Type, dst *Type, why *string) Op {
} else if have != nil && have.Sym == missing.Sym && have.Nointerface {
*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
} else if have != nil && have.Sym == missing.Sym {
*why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", src, dst, missing.Sym, have.Sym, Tconv(have.Type, FmtShort|FmtByte), missing.Sym, Tconv(missing.Type, FmtShort|FmtByte))
*why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%01v\n\t\twant %v%01v", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if ptr != 0 {
*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
} else if have != nil {
*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", src, dst, missing.Sym, have.Sym, Tconv(have.Type, FmtShort|FmtByte), missing.Sym, Tconv(missing.Type, FmtShort|FmtByte))
*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%01v\n\t\twant %v%01v", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else {
*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
}
......@@ -1139,10 +1139,10 @@ func syslook(name string) *Node {
// typehash computes a hash value for type t to use in type switch
// statements.
func typehash(t *Type) uint32 {
// Tconv already contains all the necessary logic to generate
// fmt.Sprintf("%- v", t) already contains all the necessary logic to generate
// a representation that completely describes the type, so using
// it here avoids duplicating that code.
p := Tconv(t, FmtLeft|FmtUnsigned)
p := fmt.Sprintf("%- v", t)
// Using MD5 is overkill, but reduces accidental collisions.
h := md5.Sum([]byte(p))
......
......@@ -4,7 +4,10 @@
package gc
import "sort"
import (
"fmt"
"sort"
)
const (
// expression switch
......@@ -162,7 +165,7 @@ func typecheckswitch(n *Node) {
ls[i1] = n1
case !n1.Type.IsInterface() && t.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr):
if have != nil && !missing.Broke && !have.Broke {
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.Left.Right, FmtLong), n1.Type, missing.Sym, have.Sym, Tconv(have.Type, FmtShort), missing.Sym, Tconv(missing.Type, FmtShort))
Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%1v\n\twant %v%1v", Nconv(n.Left.Right, FmtLong), n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if !missing.Broke {
Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, FmtLong), n1.Type, missing.Sym)
}
......@@ -642,9 +645,9 @@ func (s *exprSwitch) checkDupCases(cc []caseClause) {
}
n := c.node.Left
tv := typeVal{
// Tconv here serves to completely describe the type.
// fmt.Sprintf("% -v", n.Type) here serves to completely describe the type.
// See the comments in func typehash.
typ: Tconv(n.Type, FmtLeft|FmtUnsigned),
typ: fmt.Sprintf("% -v", n.Type),
val: n.Val().Interface(),
}
prev, dup := seen[tv]
......
......@@ -964,11 +964,11 @@ OpSwitch:
var ptr int
if !implements(n.Type, t, &missing, &have, &ptr) {
if have != nil && have.Sym == missing.Sym {
Yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", n.Type, t, missing.Sym, have.Sym, Tconv(have.Type, FmtShort|FmtByte), missing.Sym, Tconv(missing.Type, FmtShort|FmtByte))
Yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%01v\n\t\twant %v%01v", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if ptr != 0 {
Yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
} else if have != nil {
Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", n.Type, t, missing.Sym, have.Sym, Tconv(have.Type, FmtShort|FmtByte), missing.Sym, Tconv(missing.Type, FmtShort|FmtByte))
Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%01v\n\t\twant %v%01v", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else {
Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
}
......@@ -1515,7 +1515,7 @@ OpSwitch:
l := args.First()
r := args.Second()
if l.Type != nil && !l.Type.IsMap() {
Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, FmtLong))
Yyerror("first argument to delete must be map; have %2v", l.Type)
n.Type = nil
return n
}
......@@ -1559,7 +1559,7 @@ OpSwitch:
return n
}
Yyerror("first argument to append must be slice; have %v", Tconv(t, FmtLong))
Yyerror("first argument to append must be slice; have %2v", t)
n.Type = nil
return n
}
......@@ -1642,25 +1642,25 @@ OpSwitch:
if Eqtype(n.Left.Type.Elem(), bytetype) {
break OpSwitch
}
Yyerror("arguments to copy have different element types: %v and string", Tconv(n.Left.Type, FmtLong))
Yyerror("arguments to copy have different element types: %2v and string", n.Left.Type)
n.Type = nil
return n
}
if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, FmtLong), Tconv(n.Right.Type, FmtLong))
Yyerror("arguments to copy must be slices; have %2v, %2v", n.Left.Type, n.Right.Type)
} else if !n.Left.Type.IsSlice() {
Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, FmtLong))
Yyerror("first argument to copy should be slice; have %2v", n.Left.Type)
} else {
Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, FmtLong))
Yyerror("second argument to copy should be slice or string; have %2v", n.Right.Type)
}
n.Type = nil
return n
}
if !Eqtype(n.Left.Type.Elem(), n.Right.Type.Elem()) {
Yyerror("arguments to copy have different element types: %v and %v", Tconv(n.Left.Type, FmtLong), Tconv(n.Right.Type, FmtLong))
Yyerror("arguments to copy have different element types: %2v and %2v", n.Left.Type, n.Right.Type)
n.Type = nil
return n
}
......
......@@ -1875,7 +1875,7 @@ func dumpnodetypes(l []*Node, what string) string {
if s != "" {
s += ", "
}
s += Tconv(r.Type, 0)
s += r.Type.String()
}
if s == "" {
s = fmt.Sprintf("[no arguments %s]", what)
......@@ -3951,7 +3951,7 @@ func usemethod(n *Node) {
return
}
}
if Tconv(res0.Type, 0) != "reflect.Method" {
if res0.Type.String() != "reflect.Method" {
return
}
......
......@@ -293,7 +293,7 @@ func gmove(f *gc.Node, t *gc.Node) {
switch uint32(ft)<<16 | uint32(tt) {
default:
gc.Fatalf("gmove %v -> %v", gc.Tconv(f.Type, gc.FmtLong), gc.Tconv(t.Type, gc.FmtLong))
gc.Fatalf("gmove %2v -> %2v", f.Type, t.Type)
/*
* integer copy and truncate
......
......@@ -256,7 +256,7 @@ func gmove(f *gc.Node, t *gc.Node) {
switch uint32(ft)<<16 | uint32(tt) {
default:
gc.Fatalf("gmove %v -> %v", gc.Tconv(f.Type, gc.FmtLong), gc.Tconv(t.Type, gc.FmtLong))
gc.Fatalf("gmove %2v -> %2v", f.Type, t.Type)
/*
* integer copy and truncate
......
......@@ -253,7 +253,7 @@ func gmove(f *gc.Node, t *gc.Node) {
// otherwise handle and return.
switch uint32(ft)<<16 | uint32(tt) {
default:
gc.Fatalf("gmove %v -> %v", gc.Tconv(f.Type, gc.FmtLong), gc.Tconv(t.Type, gc.FmtLong))
gc.Fatalf("gmove %2v -> %2v", f.Type, t.Type)
// integer copy and truncate
case gc.TINT8<<16 | gc.TINT8,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment