]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: more systematic error handling in typeWriter
authorRobert Findley <rfindley@google.com>
Tue, 31 Aug 2021 22:20:49 +0000 (18:20 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 1 Sep 2021 00:37:16 +0000 (00:37 +0000)
This is a port of CL 346009 to go/types. An unnecessary break statement
was removed from both the port and types2.

Change-Id: I2cc1328a61100d4b01a2d26ac7bac9044440d579
Reviewed-on: https://go-review.googlesource.com/c/go/+/346558
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/compile/internal/types2/typestring.go
src/go/types/typestring.go

index 204e20c7ffd860beaa433ea442bada98ab77e9b3..da5de08758d93cbe34938703bcf2abd3ed654800 100644 (file)
@@ -212,7 +212,6 @@ func (w *typeWriter) typ(typ Type) {
                        s = "<-chan "
                default:
                        w.error("unknown channel direction")
-                       break
                }
                w.string(s)
                if parens {
index 3a6bb9aafc773589dfa97e35a64f809246ecb42f..3d30ff98f39bd61e0fd00e4ca10fb5eafca4c44e 100644 (file)
@@ -56,6 +56,14 @@ func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
        newTypeWriter(buf, qf).typ(typ)
 }
 
+// WriteSignature writes the representation of the signature sig to buf,
+// without a leading "func" keyword.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
+       newTypeWriter(buf, qf).signature(sig)
+}
+
 // instanceMarker is the prefix for an instantiated type in unexpanded form.
 const instanceMarker = '#'
 
@@ -77,10 +85,16 @@ func newTypeHasher(buf *bytes.Buffer) *typeWriter {
 func (w *typeWriter) byte(b byte)                               { w.buf.WriteByte(b) }
 func (w *typeWriter) string(s string)                           { w.buf.WriteString(s) }
 func (w *typeWriter) writef(format string, args ...interface{}) { fmt.Fprintf(w.buf, format, args...) }
+func (w *typeWriter) error(msg string) {
+       if w.hash {
+               panic(msg)
+       }
+       w.string("<" + msg + ">")
+}
 
 func (w *typeWriter) typ(typ Type) {
        if w.seen[typ] {
-               w.writef("○%T", goTypeName(typ)) // cycle to typ
+               w.error("cycle to " + goTypeName(typ))
                return
        }
        w.seen[typ] = true
@@ -88,7 +102,7 @@ func (w *typeWriter) typ(typ Type) {
 
        switch t := typ.(type) {
        case nil:
-               w.string("<nil>")
+               w.error("nil")
 
        case *Basic:
                // exported basic types go into package unsafe
@@ -144,7 +158,8 @@ func (w *typeWriter) typ(typ Type) {
                // Unions only appear as (syntactic) embedded elements
                // in interfaces and syntactically cannot be empty.
                if t.Len() == 0 {
-                       panic("empty union")
+                       w.error("empty union")
+                       break
                }
                for i, t := range t.terms {
                        if i > 0 {
@@ -197,7 +212,7 @@ func (w *typeWriter) typ(typ Type) {
                case RecvOnly:
                        s = "<-chan "
                default:
-                       unreachable()
+                       w.error("unknown channel direction")
                }
                w.string(s)
                if parens {
@@ -226,21 +241,21 @@ func (w *typeWriter) typ(typ Type) {
                }
 
        case *TypeParam:
-               s := "?"
-               if t.obj != nil {
-                       // Optionally write out package for typeparams (like Named).
-                       // TODO(danscales): this is required for import/export, so
-                       // we maybe need a separate function that won't be changed
-                       // for debugging purposes.
-                       if t.obj.pkg != nil {
-                               writePackage(w.buf, t.obj.pkg, w.qf)
-                       }
-                       s = t.obj.name
+               if t.obj == nil {
+                       w.error("unnamed type parameter")
+                       break
                }
-               w.string(s + subscript(t.id))
+               // Optionally write out package for typeparams (like Named).
+               // TODO(danscales): this is required for import/export, so
+               // we maybe need a separate function that won't be changed
+               // for debugging purposes.
+               if t.obj.pkg != nil {
+                       writePackage(w.buf, t.obj.pkg, w.qf)
+               }
+               w.string(t.obj.name + subscript(t.id))
 
        case *top:
-               w.string("⊤")
+               w.error("⊤")
 
        default:
                // For externally defined implementations of Type.
@@ -267,26 +282,20 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
                // Determine the type parameter and its constraint.
                // list is expected to hold type parameter names,
                // but don't crash if that's not the case.
-               var bound Type
-               if tpar != nil {
-                       bound = tpar.bound // should not be nil but we want to see it if it is
+               if tpar == nil {
+                       w.error("nil type parameter")
+                       continue
                }
-
                if i > 0 {
-                       if bound != prev {
+                       if tpar.bound != prev {
                                // bound changed - write previous one before advancing
                                w.byte(' ')
                                w.typ(prev)
                        }
                        w.string(", ")
                }
-               prev = bound
-
-               if tpar != nil {
-                       w.typ(tpar)
-               } else {
-                       w.string(tpar.obj.name)
-               }
+               prev = tpar.bound
+               w.typ(tpar)
        }
        if prev != nil {
                w.byte(' ')
@@ -296,11 +305,6 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
 }
 
 func (w *typeWriter) typeName(obj *TypeName) {
-       if obj == nil {
-               assert(!w.hash) // we need an object for type hashing
-               w.string("<Named w/o object>")
-               return
-       }
        if obj.pkg != nil {
                writePackage(w.buf, obj.pkg, w.qf)
        }
@@ -353,7 +357,8 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
                                        // special case:
                                        // append(s, "foo"...) leads to signature func([]byte, string...)
                                        if t := asBasic(typ); t == nil || t.kind != String {
-                                               panic("expected string type")
+                                               w.error("expected string type")
+                                               continue
                                        }
                                        w.typ(typ)
                                        w.string("...")
@@ -366,14 +371,6 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
        w.byte(')')
 }
 
-// WriteSignature writes the representation of the signature sig to buf,
-// without a leading "func" keyword.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
-func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
-       newTypeWriter(buf, qf).signature(sig)
-}
-
 func (w *typeWriter) signature(sig *Signature) {
        if sig.TParams().Len() != 0 {
                w.tParamList(sig.TParams().list())