]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: use InstantiateLazy to create instance types (cleanup)
authorRob Findley <rfindley@google.com>
Fri, 16 Jul 2021 23:58:59 +0000 (19:58 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 19 Jul 2021 17:07:35 +0000 (17:07 +0000)
This is a port of CL 333669 to go/types, adjusted for the position and
IndexExpr APIs, and excluding the noder changes.

Change-Id: I3ac4bbf271947c3cf80ab04c462a91657316f4fe
Reviewed-on: https://go-review.googlesource.com/c/go/+/335073
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/instance.go
src/go/types/instantiate.go
src/go/types/typexpr.go

index 143ba693a6e023eda4eaac7c42b4008531c118f1..25f1442881d509b9d271f7c1eb4ab54772a998f7 100644 (file)
@@ -15,7 +15,7 @@ type instance struct {
        pos     token.Pos   // position of type instantiation; for error reporting only
        base    *Named      // parameterized type to be instantiated
        targs   []Type      // type arguments
-       poslist []token.Pos // position of each targ; for error reporting only
+       posList []token.Pos // position of each targ; for error reporting only
        verify  bool        // if set, constraint satisfaction is verified
        value   Type        // base[targs...] after instantiation or Typ[Invalid]; nil if not yet set
 }
@@ -26,7 +26,7 @@ type instance struct {
 func (t *instance) expand() Type {
        v := t.value
        if v == nil {
-               v = t.check.Instantiate(t.pos, t.base, t.targs, t.poslist, t.verify)
+               v = t.check.Instantiate(t.pos, t.base, t.targs, t.posList, t.verify)
                if v == nil {
                        v = Typ[Invalid]
                }
index 55e34ca0c1c5be47d0729efd7eae8d96a24d727e..99ffb9e6048c4a83191d281224af4ec97e852bfe 100644 (file)
@@ -113,19 +113,21 @@ func (check *Checker) Instantiate(pos token.Pos, typ Type, targs []Type, posList
 }
 
 // InstantiateLazy is like Instantiate, but avoids actually
-// instantiating the type until needed.
-func (check *Checker) InstantiateLazy(pos token.Pos, typ Type, targs []Type, verify bool) (res Type) {
+// instantiating the type until needed. typ must be a *Named
+// type.
+func (check *Checker) InstantiateLazy(pos token.Pos, typ Type, targs []Type, posList []token.Pos, verify bool) Type {
        base := asNamed(typ)
        if base == nil {
                panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
        }
 
        return &instance{
-               check:  check,
-               pos:    pos,
-               base:   base,
-               targs:  targs,
-               verify: verify,
+               check:   check,
+               pos:     pos,
+               base:    base,
+               targs:   targs,
+               posList: posList,
+               verify:  verify,
        }
 }
 
index e93c50a087cd493b5635c32a069e85c416be2379..9a9fe32cb38d276ff769e130108ca2f1710d119c 100644 (file)
@@ -264,7 +264,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
        case *ast.IndexExpr, *ast.MultiIndexExpr:
                ix := typeparams.UnpackIndexExpr(e)
                // TODO(rfindley): type instantiation should require go1.18
-               return check.instantiatedType(ix, def)
+               return check.instantiatedType(ix.X, ix.Indices, def)
 
        case *ast.ParenExpr:
                // Generic types must be instantiated before they can be used in any form.
@@ -400,45 +400,32 @@ func (check *Checker) typeOrNil(e ast.Expr) Type {
        return Typ[Invalid]
 }
 
-func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) Type {
-       b := check.genericType(ix.X, true) // TODO(gri) what about cycles?
-       if b == Typ[Invalid] {
-               return b // error already reported
+func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named) Type {
+       base := check.genericType(x, true)
+       if base == Typ[Invalid] {
+               return base // error already reported
        }
-       base := asNamed(b)
-       if base == nil {
-               unreachable() // should have been caught by genericType
-       }
-
-       // create a new type instance rather than instantiate the type
-       // TODO(gri) should do argument number check here rather than
-       //           when instantiating the type?
-       // TODO(gri) use InstantiateLazy here (cleanup)
-       typ := new(instance)
-       def.setUnderlying(typ)
 
-       typ.check = check
-       typ.pos = ix.X.Pos()
-       typ.base = base
-       typ.verify = true
-
-       // evaluate arguments (always)
-       typ.targs = check.typeList(ix.Indices)
-       if typ.targs == nil {
+       // evaluate arguments
+       targs := check.typeList(targsx)
+       if targs == nil {
                def.setUnderlying(Typ[Invalid]) // avoid later errors due to lazy instantiation
                return Typ[Invalid]
        }
 
-       // determine argument positions (for error reporting)
-       typ.poslist = make([]token.Pos, len(ix.Indices))
-       for i, arg := range ix.Indices {
-               typ.poslist[i] = arg.Pos()
+       // determine argument positions
+       posList := make([]token.Pos, len(targs))
+       for i, arg := range targsx {
+               posList[i] = arg.Pos()
        }
 
+       typ := check.InstantiateLazy(x.Pos(), base, targs, posList, true)
+       def.setUnderlying(typ)
+
        // make sure we check instantiation works at least once
        // and that the resulting type is valid
        check.later(func() {
-               t := typ.expand()
+               t := typ.(*instance).expand()
                check.validType(t, nil)
        })