]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: consolidate verification logic
authorRobert Findley <rfindley@google.com>
Fri, 13 Aug 2021 17:52:55 +0000 (13:52 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 18 Aug 2021 20:12:37 +0000 (20:12 +0000)
Change an internal call of instantiateLazy to call Instantiate, so that
we can consolidate the logic for invoking verification.

This made verification of signatures lazy, which is not necessary but
should be harmless.

Change-Id: I2e59b04ac859e08c2e2910ded3c183093d1e34a7
Reviewed-on: https://go-review.googlesource.com/c/go/+/342149
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/cmd/compile/internal/types2/instantiate.go
src/cmd/compile/internal/types2/typexpr.go

index d2383db35c5680e9740fbecf1b7d282cb5d4329d..ef92574a5c896f7606fd1d1283e8e85725a62154 100644 (file)
@@ -26,12 +26,12 @@ import (
 // instantiated.
 func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posList []syntax.Pos, verify bool) (res Type) {
        // TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
-       var tparams []*TypeName
+       var inst Type
        switch t := typ.(type) {
        case *Named:
-               return check.instantiateLazy(pos, t, targs, posList, verify)
+               inst = check.instantiateLazy(pos, t, targs)
        case *Signature:
-               tparams = t.TParams().list()
+               tparams := t.TParams().list()
                defer func() {
                        // If we had an unexpected failure somewhere don't panic below when
                        // asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
@@ -50,18 +50,35 @@ func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posLis
                        // anymore; we need to set tparams to nil.
                        res.(*Signature).tparams = nil
                }()
+               inst = check.instantiate(pos, typ, tparams, targs, nil)
        default:
                // only types and functions can be generic
                panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
        }
-       inst := check.instantiate(pos, typ, tparams, targs, nil)
 
        if verify {
-               assert(len(posList) <= len(targs))
-               if len(tparams) == len(targs) {
-                       check.verify(pos, tparams, targs, posList)
+               if check == nil {
+                       panic("cannot have nil Checker if verifying constraints")
                }
+               assert(len(posList) <= len(targs))
+               check.later(func() {
+                       // Collect tparams again because lazily loaded *Named types may not have
+                       // had tparams set up above.
+                       var tparams []*TypeName
+                       switch t := typ.(type) {
+                       case *Named:
+                               tparams = t.TParams().list()
+                       case *Signature:
+                               tparams = t.TParams().list()
+                       }
+                       // Avoid duplicate errors; instantiate will have complained if tparams
+                       // and targs do not have the same length.
+                       if len(tparams) == len(targs) {
+                               check.verify(pos, tparams, targs, posList)
+                       }
+               })
        }
+
        return inst
 }
 
@@ -101,20 +118,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName,
 
 // instantiateLazy avoids actually instantiating the type until needed. typ
 // must be a *Named type.
-func (check *Checker) instantiateLazy(pos syntax.Pos, orig *Named, targs []Type, posList []syntax.Pos, verify bool) Type {
-       if verify {
-               if check == nil {
-                       // Provide a more useful panic instead of panicking at check.later below.
-                       panic("cannot have nil Checker if verifying constraints")
-               }
-               assert(len(posList) <= len(targs))
-               if orig.TParams().Len() == len(targs) {
-                       check.later(func() {
-                               check.verify(pos, orig.tparams.list(), targs, posList)
-                       })
-               }
-       }
-
+func (check *Checker) instantiateLazy(pos syntax.Pos, orig *Named, targs []Type) Type {
        h := instantiatedHash(orig, targs)
        if check != nil {
                // typ may already have been instantiated with identical type arguments. In
@@ -136,9 +140,6 @@ func (check *Checker) instantiateLazy(pos syntax.Pos, orig *Named, targs []Type,
 }
 
 func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type, posList []syntax.Pos) {
-       if check == nil {
-               panic("cannot have nil Checker if verifying constraints")
-       }
        smap := makeSubstMap(tparams, targs)
        for i, tname := range tparams {
                // best position for error reporting
index a53319c153932eb3525fc1272365961789a0dad9..4df8ab68a196f55aa243f74bb476aea7c113f4ff 100644 (file)
@@ -444,7 +444,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, targsx []syntax.Expr, def
                posList[i] = syntax.StartPos(arg)
        }
 
-       typ := check.instantiateLazy(x.Pos(), base, targs, posList, true)
+       typ := check.Instantiate(x.Pos(), base, targs, posList, true)
        def.setUnderlying(typ)
 
        // make sure we check instantiation works at least once