]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: (slightly) refactor tpWalker.isParameterized (cleanup)
authorRobert Griesemer <gri@golang.org>
Thu, 13 Apr 2023 20:58:45 +0000 (13:58 -0700)
committerGopher Robot <gobot@golang.org>
Mon, 17 Apr 2023 13:22:51 +0000 (13:22 +0000)
Match the structure of cycleFinder. Removes a TODO.

Change-Id: Iec0abfc809cd522f64db8900a1f8a70cbba504ee
Reviewed-on: https://go-review.googlesource.com/c/go/+/484615
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/infer.go
src/go/types/infer.go

index 62ee1f080d1c8d94cb2b037f90e0f1a31f8b688f..77e552d3f3112c77c47ed74a44ffa62c0c1358dd 100644 (file)
@@ -401,7 +401,7 @@ func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params
        //   }
        //
        // In this example, without type parameter renaming, the P used in the
-       // instantation f[P] has the same pointer identity as the P we are trying
+       // instantiation f[P] has the same pointer identity as the P we are trying
        // to solve for through type inference. This causes problems for type
        // unification. Because any such self-recursive call is equivalent to
        // a mutually recursive call, type parameter renaming can be used to
@@ -463,15 +463,15 @@ func typeParamsString(list []*TypeParam) string {
 // isParameterized reports whether typ contains any of the type parameters of tparams.
 func isParameterized(tparams []*TypeParam, typ Type) bool {
        w := tpWalker{
-               seen:    make(map[Type]bool),
                tparams: tparams,
+               seen:    make(map[Type]bool),
        }
        return w.isParameterized(typ)
 }
 
 type tpWalker struct {
-       seen    map[Type]bool
        tparams []*TypeParam
+       seen    map[Type]bool
 }
 
 func (w *tpWalker) isParameterized(typ Type) (res bool) {
@@ -485,8 +485,8 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
        }()
 
        switch t := typ.(type) {
-       case nil, *Basic: // TODO(gri) should nil be handled here?
-               break
+       case *Basic:
+               // nothing to do
 
        case *Array:
                return w.isParameterized(t.elem)
@@ -495,22 +495,14 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                return w.isParameterized(t.elem)
 
        case *Struct:
-               for _, fld := range t.fields {
-                       if w.isParameterized(fld.typ) {
-                               return true
-                       }
-               }
+               return w.varList(t.fields)
 
        case *Pointer:
                return w.isParameterized(t.base)
 
-       case *Tuple:
-               n := t.Len()
-               for i := 0; i < n; i++ {
-                       if w.isParameterized(t.At(i).typ) {
-                               return true
-                       }
-               }
+       // case *Tuple:
+       //      This case should not occur because tuples only appear
+       //      in signatures where they are handled explicitly.
 
        case *Signature:
                // t.tparams may not be nil if we are looking at a signature
@@ -520,7 +512,7 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                // Similarly, the receiver of a method may declare (rather then
                // use) type parameters, we don't care about those either.
                // Thus, we only need to look at the input and result parameters.
-               return w.isParameterized(t.params) || w.isParameterized(t.results)
+               return t.params != nil && w.varList(t.params.vars) || t.results != nil && w.varList(t.results.vars)
 
        case *Interface:
                tset := t.typeSet()
@@ -540,22 +532,26 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                return w.isParameterized(t.elem)
 
        case *Named:
-               return w.isParameterizedTypeList(t.TypeArgs().list())
+               for _, t := range t.TypeArgs().list() {
+                       if w.isParameterized(t) {
+                               return true
+                       }
+               }
 
        case *TypeParam:
                // t must be one of w.tparams
                return tparamIndex(w.tparams, t) >= 0
 
        default:
-               unreachable()
+               panic(fmt.Sprintf("unexpected %T", typ))
        }
 
        return false
 }
 
-func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
-       for _, t := range list {
-               if w.isParameterized(t) {
+func (w *tpWalker) varList(list []*Var) bool {
+       for _, v := range list {
+               if w.isParameterized(v.typ) {
                        return true
                }
        }
@@ -613,9 +609,9 @@ func killCycles(tparams []*TypeParam, inferred []Type) {
 }
 
 type cycleFinder struct {
-       tparams []*TypeParam
-       types   []Type
-       seen    map[Type]bool
+       tparams  []*TypeParam
+       inferred []Type
+       seen     map[Type]bool
 }
 
 func (w *cycleFinder) typ(typ Type) {
@@ -626,7 +622,7 @@ func (w *cycleFinder) typ(typ Type) {
                if tpar, _ := typ.(*TypeParam); tpar != nil {
                        if i := tparamIndex(w.tparams, tpar); i >= 0 {
                                // cycle through tpar
-                               w.types[i] = nil
+                               w.inferred[i] = nil
                        }
                }
                // If we don't have one of our type parameters, the cycle is due
@@ -690,8 +686,8 @@ func (w *cycleFinder) typ(typ Type) {
                }
 
        case *TypeParam:
-               if i := tparamIndex(w.tparams, t); i >= 0 && w.types[i] != nil {
-                       w.typ(w.types[i])
+               if i := tparamIndex(w.tparams, t); i >= 0 && w.inferred[i] != nil {
+                       w.typ(w.inferred[i])
                }
 
        default:
index e1decc8ca1b4662a627f5d339621b19c44ca3362..7ef7646e7dacf78026c479500951390bce41942b 100644 (file)
@@ -403,7 +403,7 @@ func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, params
        //   }
        //
        // In this example, without type parameter renaming, the P used in the
-       // instantation f[P] has the same pointer identity as the P we are trying
+       // instantiation f[P] has the same pointer identity as the P we are trying
        // to solve for through type inference. This causes problems for type
        // unification. Because any such self-recursive call is equivalent to
        // a mutually recursive call, type parameter renaming can be used to
@@ -465,15 +465,15 @@ func typeParamsString(list []*TypeParam) string {
 // isParameterized reports whether typ contains any of the type parameters of tparams.
 func isParameterized(tparams []*TypeParam, typ Type) bool {
        w := tpWalker{
-               seen:    make(map[Type]bool),
                tparams: tparams,
+               seen:    make(map[Type]bool),
        }
        return w.isParameterized(typ)
 }
 
 type tpWalker struct {
-       seen    map[Type]bool
        tparams []*TypeParam
+       seen    map[Type]bool
 }
 
 func (w *tpWalker) isParameterized(typ Type) (res bool) {
@@ -487,8 +487,8 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
        }()
 
        switch t := typ.(type) {
-       case nil, *Basic: // TODO(gri) should nil be handled here?
-               break
+       case *Basic:
+               // nothing to do
 
        case *Array:
                return w.isParameterized(t.elem)
@@ -497,22 +497,14 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                return w.isParameterized(t.elem)
 
        case *Struct:
-               for _, fld := range t.fields {
-                       if w.isParameterized(fld.typ) {
-                               return true
-                       }
-               }
+               return w.varList(t.fields)
 
        case *Pointer:
                return w.isParameterized(t.base)
 
-       case *Tuple:
-               n := t.Len()
-               for i := 0; i < n; i++ {
-                       if w.isParameterized(t.At(i).typ) {
-                               return true
-                       }
-               }
+       // case *Tuple:
+       //      This case should not occur because tuples only appear
+       //      in signatures where they are handled explicitly.
 
        case *Signature:
                // t.tparams may not be nil if we are looking at a signature
@@ -522,7 +514,7 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                // Similarly, the receiver of a method may declare (rather then
                // use) type parameters, we don't care about those either.
                // Thus, we only need to look at the input and result parameters.
-               return w.isParameterized(t.params) || w.isParameterized(t.results)
+               return t.params != nil && w.varList(t.params.vars) || t.results != nil && w.varList(t.results.vars)
 
        case *Interface:
                tset := t.typeSet()
@@ -542,22 +534,26 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                return w.isParameterized(t.elem)
 
        case *Named:
-               return w.isParameterizedTypeList(t.TypeArgs().list())
+               for _, t := range t.TypeArgs().list() {
+                       if w.isParameterized(t) {
+                               return true
+                       }
+               }
 
        case *TypeParam:
                // t must be one of w.tparams
                return tparamIndex(w.tparams, t) >= 0
 
        default:
-               unreachable()
+               panic(fmt.Sprintf("unexpected %T", typ))
        }
 
        return false
 }
 
-func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
-       for _, t := range list {
-               if w.isParameterized(t) {
+func (w *tpWalker) varList(list []*Var) bool {
+       for _, v := range list {
+               if w.isParameterized(v.typ) {
                        return true
                }
        }
@@ -615,9 +611,9 @@ func killCycles(tparams []*TypeParam, inferred []Type) {
 }
 
 type cycleFinder struct {
-       tparams []*TypeParam
-       types   []Type
-       seen    map[Type]bool
+       tparams  []*TypeParam
+       inferred []Type
+       seen     map[Type]bool
 }
 
 func (w *cycleFinder) typ(typ Type) {
@@ -628,7 +624,7 @@ func (w *cycleFinder) typ(typ Type) {
                if tpar, _ := typ.(*TypeParam); tpar != nil {
                        if i := tparamIndex(w.tparams, tpar); i >= 0 {
                                // cycle through tpar
-                               w.types[i] = nil
+                               w.inferred[i] = nil
                        }
                }
                // If we don't have one of our type parameters, the cycle is due
@@ -692,8 +688,8 @@ func (w *cycleFinder) typ(typ Type) {
                }
 
        case *TypeParam:
-               if i := tparamIndex(w.tparams, t); i >= 0 && w.types[i] != nil {
-                       w.typ(w.types[i])
+               if i := tparamIndex(w.tparams, t); i >= 0 && w.inferred[i] != nil {
+                       w.typ(w.inferred[i])
                }
 
        default: