Skip to content

Commit 165ebd8

Browse files
committed
cmd/compile/internal/types2: clean up panics in instantiation
Clean up a few issues related to panicking during invalid instantiation. - Panic early in instantiateLazy when check == nil and verify == true. Otherwise, we would panic at check.later. - Always panic when check == nil and verify == true, even if targs is of incorrect length. This is more consistent behavior. - Lift the check for len(posList) <= len(targs) out of Checker.instantiate. This is the only reason why posList is passed to that function, and doing this allows us to eliminate posList from instance. At this point instance is close to being unnecessary, so update a TODO to this effect. Change-Id: Id5f44cbb1a5897aef10ce2a573aa78acd7ae4026 Reviewed-on: https://go-review.googlesource.com/c/go/+/341862 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 4a0fd73 commit 165ebd8

File tree

2 files changed

+27
-22
lines changed

2 files changed

+27
-22
lines changed

src/cmd/compile/internal/types2/instantiate.go

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,18 @@ func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posLis
5454
// only types and functions can be generic
5555
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
5656
}
57+
inst := check.instantiate(pos, typ, tparams, targs, nil)
5758

58-
inst := check.instantiate(pos, typ, tparams, targs, posList, nil)
59-
if verify && len(tparams) == len(targs) {
60-
check.verify(pos, tparams, targs, posList)
59+
if verify {
60+
assert(len(posList) <= len(targs))
61+
if len(tparams) == len(targs) {
62+
check.verify(pos, tparams, targs, posList)
63+
}
6164
}
6265
return inst
6366
}
6467

65-
func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName, targs []Type, posList []syntax.Pos, typMap map[string]*Named) (res Type) {
68+
func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName, targs []Type, typMap map[string]*Named) (res Type) {
6669
// the number of supplied types must match the number of type parameters
6770
if len(targs) != len(tparams) {
6871
// TODO(gri) provide better error message
@@ -89,8 +92,6 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName,
8992
}()
9093
}
9194

92-
assert(len(posList) <= len(targs))
93-
9495
if len(tparams) == 0 {
9596
return typ // nothing to do (minor optimization)
9697
}
@@ -100,15 +101,21 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName,
100101

101102
// instantiateLazy avoids actually instantiating the type until needed. typ
102103
// must be a *Named type.
103-
func (check *Checker) instantiateLazy(pos syntax.Pos, base *Named, targs []Type, posList []syntax.Pos, verify bool) Type {
104-
if verify && base.TParams().Len() == len(targs) {
105-
// TODO: lift the nil check in verify to here.
106-
check.later(func() {
107-
check.verify(pos, base.tparams.list(), targs, posList)
108-
})
104+
func (check *Checker) instantiateLazy(pos syntax.Pos, orig *Named, targs []Type, posList []syntax.Pos, verify bool) Type {
105+
if verify {
106+
if check == nil {
107+
// Provide a more useful panic instead of panicking at check.later below.
108+
panic("cannot have nil Checker if verifying constraints")
109+
}
110+
assert(len(posList) <= len(targs))
111+
if orig.TParams().Len() == len(targs) {
112+
check.later(func() {
113+
check.verify(pos, orig.tparams.list(), targs, posList)
114+
})
115+
}
109116
}
110117

111-
h := instantiatedHash(base, targs)
118+
h := instantiatedHash(orig, targs)
112119
if check != nil {
113120
// typ may already have been instantiated with identical type arguments. In
114121
// that case, re-use the existing instance.
@@ -117,10 +124,10 @@ func (check *Checker) instantiateLazy(pos syntax.Pos, base *Named, targs []Type,
117124
}
118125
}
119126

120-
tname := NewTypeName(pos, base.obj.pkg, base.obj.name, nil)
121-
named := check.newNamed(tname, base, nil, nil, nil) // methods and tparams are set when named is loaded
127+
tname := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
128+
named := check.newNamed(tname, orig, nil, nil, nil) // methods and tparams are set when named is loaded
122129
named.targs = targs
123-
named.instance = &instance{pos, posList}
130+
named.instance = &instance{pos}
124131
if check != nil {
125132
check.typMap[h] = named
126133
}
@@ -132,7 +139,6 @@ func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type,
132139
if check == nil {
133140
panic("cannot have nil Checker if verifying constraints")
134141
}
135-
136142
smap := makeSubstMap(tparams, targs)
137143
for i, tname := range tparams {
138144
// best position for error reporting

src/cmd/compile/internal/types2/named.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,10 @@ func (n *Named) setUnderlying(typ Type) {
244244

245245
// instance holds position information for use in lazy instantiation.
246246
//
247-
// TODO(rfindley): come up with a better name for this type, now that its usage
248-
// has changed.
247+
// TODO(rfindley): instance is probably unnecessary now. See if it can be
248+
// eliminated.
249249
type instance struct {
250-
pos syntax.Pos // position of type instantiation; for error reporting only
251-
posList []syntax.Pos // position of each targ; for error reporting only
250+
pos syntax.Pos // position of type instantiation; for error reporting only
252251
}
253252

254253
// expand ensures that the underlying type of n is instantiated.
@@ -272,7 +271,7 @@ func (n *Named) expand(typMap map[string]*Named) *Named {
272271
}
273272
}
274273

275-
inst := n.check.instantiate(n.instance.pos, n.orig.underlying, n.TParams().list(), n.targs, n.instance.posList, typMap)
274+
inst := n.check.instantiate(n.instance.pos, n.orig.underlying, n.TParams().list(), n.targs, typMap)
276275
n.underlying = inst
277276
n.fromRHS = inst
278277
n.instance = nil

0 commit comments

Comments
 (0)