When following a RHS chain, the (TypeName) Object path is only needed
when there is a cycle (i.e., an error), in which case we can be slow.
Rather than always compute the path, only compute it in the error case.
In the same vain, allocate the seen map lazily, only when needed.
This code could use a test (it doesn't seem to be encountered by our
test suite), but I haven't found a case to provoke the error yet.
Change-Id: Iff6313394442a251adc56580f746928ec13450fd
Reviewed-on: https://go-review.googlesource.com/c/go/+/712321
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
return
}
- seen := make(map[*Named]int)
- var path []Object
-
+ var seen map[*Named]int // allocated lazily
var u Type
for rhs := Type(n); u == nil; {
switch t := rhs.(type) {
case *Named:
if i, ok := seen[t]; ok {
+ // compute cycle path
+ path := make([]Object, len(seen))
+ for t, j := range seen {
+ path[j] = t.obj
+ }
+ path = path[i:]
// Note: This code may only be called during type checking,
// hence n.check != nil.
- n.check.cycleError(path[i:], firstInSrc(path[i:]))
+ n.check.cycleError(path, firstInSrc(path))
u = Typ[Invalid]
break
}
break
}
+ if seen == nil {
+ seen = make(map[*Named]int)
+ }
seen[t] = len(seen)
- path = append(path, t.obj)
assert(t.fromRHS != nil || t.allowNilRHS)
rhs = t.fromRHS
return
}
- seen := make(map[*Named]int)
- var path []Object
-
+ var seen map[*Named]int // allocated lazily
var u Type
for rhs := Type(n); u == nil; {
switch t := rhs.(type) {
case *Named:
if i, ok := seen[t]; ok {
+ // compute cycle path
+ path := make([]Object, len(seen))
+ for t, j := range seen {
+ path[j] = t.obj
+ }
+ path = path[i:]
// Note: This code may only be called during type checking,
// hence n.check != nil.
- n.check.cycleError(path[i:], firstInSrc(path[i:]))
+ n.check.cycleError(path, firstInSrc(path))
u = Typ[Invalid]
break
}
break
}
+ if seen == nil {
+ seen = make(map[*Named]int)
+ }
seen[t] = len(seen)
- path = append(path, t.obj)
assert(t.fromRHS != nil || t.allowNilRHS)
rhs = t.fromRHS