mirror of
https://github.com/golang/go
synced 2024-11-24 06:20:02 -07:00
go/types: avoid closure allocations in mono check
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>
This commit is contained in:
parent
1011e26b9c
commit
c45c32b1cd
@ -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,
|
||||
})
|
||||
}
|
||||
|
@ -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]() }",
|
||||
|
Loading…
Reference in New Issue
Block a user