From: Robert Griesemer Date: Thu, 13 Apr 2023 20:58:45 +0000 (-0700) Subject: go/types, types2: (slightly) refactor tpWalker.isParameterized (cleanup) X-Git-Tag: go1.21rc1~885 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=13f0b8f421bb37f5c9307eefe2b0c9fdb81c9ed1;p=gostls13.git go/types, types2: (slightly) refactor tpWalker.isParameterized (cleanup) 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 TryBot-Result: Gopher Robot Reviewed-by: Robert Findley Run-TryBot: Robert Griesemer Auto-Submit: Robert Griesemer --- diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go index 62ee1f080d..77e552d3f3 100644 --- a/src/cmd/compile/internal/types2/infer.go +++ b/src/cmd/compile/internal/types2/infer.go @@ -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: diff --git a/src/go/types/infer.go b/src/go/types/infer.go index e1decc8ca1..7ef7646e7d 100644 --- a/src/go/types/infer.go +++ b/src/go/types/infer.go @@ -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: