]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: use InstantiateLazy to create instance...
authorRobert Griesemer <gri@golang.org>
Fri, 9 Jul 2021 22:04:15 +0000 (15:04 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 13 Jul 2021 04:40:20 +0000 (04:40 +0000)
This change concentrates the creation is lazily instantiated types
in one place (InstantiateLazy). This should also make it easier to
replace the implementation of lazily instantiated types (e.g. getting
rid of instance types).

Change-Id: I452c463219b466ce79f227c44fb67b79d428842a
Reviewed-on: https://go-review.googlesource.com/c/go/+/333669
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/noder/reader2.go
src/cmd/compile/internal/types2/instance.go
src/cmd/compile/internal/types2/instantiate.go
src/cmd/compile/internal/types2/typexpr.go

index 92569ff843f87df5ddcb3891079aaca987346a17..ac29f6f519280f0de96e9604948193c6dd8c715a 100644 (file)
@@ -224,7 +224,7 @@ func (r *reader2) doTyp() (res types2.Type) {
                obj, targs := r.obj()
                name := obj.(*types2.TypeName)
                if len(targs) != 0 {
-                       return r.p.check.InstantiateLazy(syntax.Pos{}, name.Type(), targs, false)
+                       return r.p.check.InstantiateLazy(syntax.Pos{}, name.Type(), targs, nil, false)
                }
                return name.Type()
 
index 65c201550736f392d51500d12b57b36869003a10..798d58811f536b4867c50863a3957544a3bb6bce 100644 (file)
@@ -15,7 +15,7 @@ type instance struct {
        pos     syntax.Pos   // position of type instantiation; for error reporting only
        base    *Named       // parameterized type to be instantiated
        targs   []Type       // type arguments
-       poslist []syntax.Pos // position of each targ; for error reporting only
+       posList []syntax.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 5ccd511acb080af65c86e11b849cdd8ee9b709a8..cc96375027f41c28b3415435591f76aa9cb90c03 100644 (file)
@@ -112,19 +112,21 @@ func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posLis
 }
 
 // InstantiateLazy is like Instantiate, but avoids actually
-// instantiating the type until needed.
-func (check *Checker) InstantiateLazy(pos syntax.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 syntax.Pos, typ Type, targs []Type, posList []syntax.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 d69dd3c496ffb53dc5e765b3dcc907f5cba49241..a14d498cec0d2f1422944207c46c71ebad19e9e6 100644 (file)
@@ -410,45 +410,32 @@ func (check *Checker) typOrNil(e syntax.Expr) Type {
        return Typ[Invalid]
 }
 
-func (check *Checker) instantiatedType(x syntax.Expr, targs []syntax.Expr, def *Named) Type {
-       b := check.genericType(x, true) // TODO(gri) what about cycles?
-       if b == Typ[Invalid] {
-               return b // error already reported
+func (check *Checker) instantiatedType(x syntax.Expr, targsx []syntax.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 = x.Pos()
-       typ.base = base
-       typ.verify = true
-
-       // evaluate arguments (always)
-       typ.targs = check.typeList(targs)
-       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([]syntax.Pos, len(targs))
-       for i, arg := range targs {
-               typ.poslist[i] = syntax.StartPos(arg)
+       // determine argument positions
+       posList := make([]syntax.Pos, len(targs))
+       for i, arg := range targsx {
+               posList[i] = syntax.StartPos(arg)
        }
 
+       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)
        })