]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: avoid closure allocations in mono check
authorMatthew Dempsky <mdempsky@google.com>
Tue, 2 Nov 2021 18:23:34 +0000 (11:23 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 2 Nov 2021 19:56:02 +0000 (19:56 +0000)
This CL replaces monoEdge's "report" field with fields "pos" and
"typ", and pushes the logic for formatting them into the report
loop. This avoids needing to allocate a function closure for each
edge.

Also tweak a test case so the two type parameters involved in the
cycle aren't both "T" so they're easier to understand.

Change-Id: I9d392ad1d99a4c5e89da4613084e885149ebad07
Reviewed-on: https://go-review.googlesource.com/c/go/+/360815
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/mono.go
src/go/types/mono_test.go

index fb1127e959fa89598747202df3c4db2a482811d7..d4d884393b9ce01287ef13b2a3e1d2a381e497cc 100644 (file)
@@ -71,14 +71,11 @@ type monoVertex struct {
 }
 
 type monoEdge struct {
-       dst    int
-       src    int
-       weight int
+       dst, src int
+       weight   int
 
-       // report emits an error describing why this edge exists.
-       //
-       // TODO(mdempsky): Avoid requiring a function closure for each edge.
-       report func(check *Checker)
+       pos token.Pos
+       typ Type
 }
 
 func (check *Checker) monomorph() {
@@ -139,12 +136,22 @@ func (check *Checker) reportInstanceLoop(v int) {
 
        // TODO(mdempsky): Pivot stack so we report the cycle from the top?
 
-       obj := check.mono.vertices[v].obj
-       check.errorf(obj, _InvalidInstanceCycle, "instantiation cycle:")
+       obj0 := check.mono.vertices[v].obj
+       check.errorf(obj0, _InvalidInstanceCycle, "instantiation cycle:")
 
+       qf := RelativeTo(check.pkg)
        for _, v := range stack {
                edge := check.mono.edges[check.mono.vertices[v].pre]
-               edge.report(check)
+               obj := check.mono.vertices[edge.dst].obj
+
+               switch obj.Type().(type) {
+               default:
+                       panic("unexpected type")
+               case *Named:
+                       check.errorf(atPos(edge.pos), _InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+               case *TypeParam:
+                       check.errorf(atPos(edge.pos), _InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+               }
        }
 }
 
@@ -190,10 +197,7 @@ func (w *monoGraph) assign(pkg *Package, pos token.Pos, tpar *TypeParam, targ Ty
                        weight = 0
                }
 
-               w.addEdge(w.typeParamVertex(tpar), src, weight, func(check *Checker) {
-                       qf := RelativeTo(check.pkg)
-                       check.errorf(atPos(pos), _InvalidInstanceCycle, "\t%s instantiated as %s", tpar.Obj().Name(), TypeString(targ, qf)) // secondary error, \t indented
-               })
+               w.addEdge(w.typeParamVertex(tpar), src, weight, pos, targ)
        }
 
        // Recursively walk the type argument to find any defined types or
@@ -283,9 +287,7 @@ func (w *monoGraph) localNamedVertex(pkg *Package, named *Named) int {
                                                w.vertices = append(w.vertices, monoVertex{obj: obj})
                                        }
 
-                                       w.addEdge(idx, w.typeParamVertex(tpar), 1, func(check *Checker) {
-                                               check.errorf(obj, _InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), elem.Name())
-                                       })
+                                       w.addEdge(idx, w.typeParamVertex(tpar), 1, obj.Pos(), tpar)
                                }
                        }
                }
@@ -320,12 +322,14 @@ func (w *monoGraph) typeParamVertex(tpar *TypeParam) int {
        return idx
 }
 
-func (w *monoGraph) addEdge(dst, src, weight int, report func(check *Checker)) {
+func (w *monoGraph) addEdge(dst, src, weight int, pos token.Pos, typ Type) {
        // TODO(mdempsky): Deduplicate redundant edges?
        w.edges = append(w.edges, monoEdge{
                dst:    dst,
                src:    src,
                weight: weight,
-               report: report,
+
+               pos: pos,
+               typ: typ,
        })
 }
index c4c5282427691382d5c2812714ad169ce5c24040..5df3d493f8a4fcb31c09bfd2b5ef73949bded9ae 100644 (file)
@@ -84,7 +84,7 @@ var bads = []string{
        "func F[T any]() { type U int; F[*U]() }",
        "type U[T any] int; func (U[T]) m() { var _ U[*T] }",
        "type U[T any] int; func (*U[T]) m() { var _ U[*T] }",
-       "type U[T any] [unsafe.Sizeof(F[*T])]byte; func F[T any]() { var _ U[T] }",
+       "type U[T1 any] [unsafe.Sizeof(F[*T1])]byte; func F[T2 any]() { var _ U[T2] }",
        "func F[A, B, C, D, E any]() { F[B, C, D, E, *A]() }",
        "type U[_ any] int; const X = unsafe.Sizeof(func() { type A[T any] U[A[*T]] })",
        "func F[T any]() { type A = *T; F[A]() }",