OXIESEC PANEL
- Current Dir:
/
/
opt
/
golang
/
1.19.4
/
src
/
go
/
types
Server IP: 2a02:4780:11:1084:0:327f:3464:10
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
12/01/2022 06:13:56 PM
rwxr-xr-x
📄
api.go
17.05 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
api_test.go
81.16 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
array.go
802 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
assignments.go
12.86 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
basic.go
1.48 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
builtins.go
24.28 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
builtins_test.go
9.7 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
call.go
22.29 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
chan.go
909 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
check.go
17.32 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
check_test.go
12.11 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
context.go
4.34 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
context_test.go
2.33 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
conversions.go
8.28 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
decl.go
28.77 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
errorcodes.go
31.51 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
errorcodes_test.go
4.95 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
errors.go
9.87 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
errors_test.go
1 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
eval.go
3.05 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
eval_test.go
7.4 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
example_test.go
9.03 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
expr.go
51.97 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
exprstring.go
4.81 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
exprstring_test.go
2.36 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
gccgosizes.go
1.02 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
gotype.go
8.33 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
hilbert_test.go
3.61 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
index.go
11.03 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
infer.go
25.18 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
initorder.go
9.48 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
instantiate.go
9.94 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
instantiate_test.go
6.02 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
interface.go
8.08 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
issues_test.go
17.49 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
labels.go
7.17 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
lookup.go
16.93 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
main_test.go
335 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
map.go
658 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
methodset.go
6.75 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
methodset_test.go
5.75 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
mono.go
9.05 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
mono_test.go
2.63 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
named.go
22.37 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
named_test.go
2.69 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
object.go
17.92 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
object_test.go
5.21 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
objset.go
927 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
operand.go
10 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
package.go
2.38 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
pointer.go
634 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
predicates.go
14.71 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
resolver.go
24.38 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
resolver_test.go
4.58 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
return.go
4.21 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
scope.go
9.33 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
selection.go
3.99 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
self_test.go
2.57 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
signature.go
12.49 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
sizeof_test.go
1.26 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
sizes.go
7.56 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
sizes_test.go
3.33 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
slice.go
576 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
stdlib_test.go
9.45 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
stmt.go
26.17 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
struct.go
6.04 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
subst.go
10.76 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
termlist.go
3.68 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
termlist_test.go
7.18 KB
12/01/2022 06:12:58 PM
rw-r--r--
📁
testdata
-
12/01/2022 06:13:56 PM
rwxr-xr-x
📄
token_test.go
1.21 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
tuple.go
928 bytes
12/01/2022 06:12:58 PM
rw-r--r--
📄
type.go
2.92 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typelists.go
1.84 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typeparam.go
4.74 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typeset.go
14.22 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typeset_test.go
2.34 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typestring.go
10.64 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typestring_test.go
4.21 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typeterm.go
3.52 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typeterm_test.go
5.1 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
typexpr.go
14.64 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
unify.go
18.35 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
union.go
6.22 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
universe.go
7.66 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
validtype.go
7.77 KB
12/01/2022 06:12:58 PM
rw-r--r--
📄
version.go
2.2 KB
12/01/2022 06:12:58 PM
rw-r--r--
Editing: subst.go
Close
// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // This file implements type parameter substitution. package types import "go/token" type substMap map[*TypeParam]Type // makeSubstMap creates a new substitution map mapping tpars[i] to targs[i]. // If targs[i] is nil, tpars[i] is not substituted. func makeSubstMap(tpars []*TypeParam, targs []Type) substMap { assert(len(tpars) == len(targs)) proj := make(substMap, len(tpars)) for i, tpar := range tpars { proj[tpar] = targs[i] } return proj } // makeRenameMap is like makeSubstMap, but creates a map used to rename type // parameters in from with the type parameters in to. func makeRenameMap(from, to []*TypeParam) substMap { assert(len(from) == len(to)) proj := make(substMap, len(from)) for i, tpar := range from { proj[tpar] = to[i] } return proj } func (m substMap) empty() bool { return len(m) == 0 } func (m substMap) lookup(tpar *TypeParam) Type { if t := m[tpar]; t != nil { return t } return tpar } // subst returns the type typ with its type parameters tpars replaced by the // corresponding type arguments targs, recursively. subst is pure in the sense // that it doesn't modify the incoming type. If a substitution took place, the // result type is different from the incoming type. // // If expanding is non-nil, it is the instance type currently being expanded. // One of expanding or ctxt must be non-nil. func (check *Checker) subst(pos token.Pos, typ Type, smap substMap, expanding *Named, ctxt *Context) Type { assert(expanding != nil || ctxt != nil) if smap.empty() { return typ } // common cases switch t := typ.(type) { case *Basic: return typ // nothing to do case *TypeParam: return smap.lookup(t) } // general case subst := subster{ pos: pos, smap: smap, check: check, expanding: expanding, ctxt: ctxt, } return subst.typ(typ) } type subster struct { pos token.Pos smap substMap check *Checker // nil if called via Instantiate expanding *Named // if non-nil, the instance that is being expanded ctxt *Context } func (subst *subster) typ(typ Type) Type { switch t := typ.(type) { case nil: // Call typOrNil if it's possible that typ is nil. panic("nil typ") case *Basic: // nothing to do case *Array: elem := subst.typOrNil(t.elem) if elem != t.elem { return &Array{len: t.len, elem: elem} } case *Slice: elem := subst.typOrNil(t.elem) if elem != t.elem { return &Slice{elem: elem} } case *Struct: if fields, copied := subst.varList(t.fields); copied { s := &Struct{fields: fields, tags: t.tags} s.markComplete() return s } case *Pointer: base := subst.typ(t.base) if base != t.base { return &Pointer{base: base} } case *Tuple: return subst.tuple(t) case *Signature: // Preserve the receiver: it is handled during *Interface and *Named type // substitution. // // Naively doing the substitution here can lead to an infinite recursion in // the case where the receiver is an interface. For example, consider the // following declaration: // // type T[A any] struct { f interface{ m() } } // // In this case, the type of f is an interface that is itself the receiver // type of all of its methods. Because we have no type name to break // cycles, substituting in the recv results in an infinite loop of // recv->interface->recv->interface->... recv := t.recv params := subst.tuple(t.params) results := subst.tuple(t.results) if params != t.params || results != t.results { return &Signature{ rparams: t.rparams, // TODO(rFindley) why can't we nil out tparams here, rather than in instantiate? tparams: t.tparams, // instantiated signatures have a nil scope recv: recv, params: params, results: results, variadic: t.variadic, } } case *Union: terms, copied := subst.termlist(t.terms) if copied { // term list substitution may introduce duplicate terms (unlikely but possible). // This is ok; lazy type set computation will determine the actual type set // in normal form. return &Union{terms} } case *Interface: methods, mcopied := subst.funcList(t.methods) embeddeds, ecopied := subst.typeList(t.embeddeds) if mcopied || ecopied { iface := subst.check.newInterface() iface.embeddeds = embeddeds iface.implicit = t.implicit iface.complete = t.complete // If we've changed the interface type, we may need to replace its // receiver if the receiver type is the original interface. Receivers of // *Named type are replaced during named type expansion. // // Notably, it's possible to reach here and not create a new *Interface, // even though the receiver type may be parameterized. For example: // // type T[P any] interface{ m() } // // In this case the interface will not be substituted here, because its // method signatures do not depend on the type parameter P, but we still // need to create new interface methods to hold the instantiated // receiver. This is handled by Named.expandUnderlying. iface.methods, _ = replaceRecvType(methods, t, iface) return iface } case *Map: key := subst.typ(t.key) elem := subst.typ(t.elem) if key != t.key || elem != t.elem { return &Map{key: key, elem: elem} } case *Chan: elem := subst.typ(t.elem) if elem != t.elem { return &Chan{dir: t.dir, elem: elem} } case *Named: // dump is for debugging dump := func(string, ...any) {} if subst.check != nil && trace { subst.check.indent++ defer func() { subst.check.indent-- }() dump = func(format string, args ...any) { subst.check.trace(subst.pos, format, args...) } } // subst is called during expansion, so in this function we need to be // careful not to call any methods that would cause t to be expanded: doing // so would result in deadlock. // // So we call t.Origin().TypeParams() rather than t.TypeParams(). orig := t.Origin() n := orig.TypeParams().Len() if n == 0 { dump(">>> %s is not parameterized", t) return t // type is not parameterized } var newTArgs []Type if t.TypeArgs().Len() != n { return Typ[Invalid] // error reported elsewhere } // already instantiated dump(">>> %s already instantiated", t) // For each (existing) type argument targ, determine if it needs // to be substituted; i.e., if it is or contains a type parameter // that has a type argument for it. for i, targ := range t.TypeArgs().list() { dump(">>> %d targ = %s", i, targ) new_targ := subst.typ(targ) if new_targ != targ { dump(">>> substituted %d targ %s => %s", i, targ, new_targ) if newTArgs == nil { newTArgs = make([]Type, n) copy(newTArgs, t.TypeArgs().list()) } newTArgs[i] = new_targ } } if newTArgs == nil { dump(">>> nothing to substitute in %s", t) return t // nothing to substitute } // Create a new instance and populate the context to avoid endless // recursion. The position used here is irrelevant because validation only // occurs on t (we don't call validType on named), but we use subst.pos to // help with debugging. return subst.check.instance(subst.pos, orig, newTArgs, subst.expanding, subst.ctxt) case *TypeParam: return subst.smap.lookup(t) default: panic("unimplemented") } return typ } // typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid]. // A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_)) // where an array/slice element is accessed before it is set up. func (subst *subster) typOrNil(typ Type) Type { if typ == nil { return Typ[Invalid] } return subst.typ(typ) } func (subst *subster) var_(v *Var) *Var { if v != nil { if typ := subst.typ(v.typ); typ != v.typ { return substVar(v, typ) } } return v } func substVar(v *Var, typ Type) *Var { copy := *v copy.typ = typ copy.origin = v.Origin() return © } func (subst *subster) tuple(t *Tuple) *Tuple { if t != nil { if vars, copied := subst.varList(t.vars); copied { return &Tuple{vars: vars} } } return t } func (subst *subster) varList(in []*Var) (out []*Var, copied bool) { out = in for i, v := range in { if w := subst.var_(v); w != v { if !copied { // first variable that got substituted => allocate new out slice // and copy all variables new := make([]*Var, len(in)) copy(new, out) out = new copied = true } out[i] = w } } return } func (subst *subster) func_(f *Func) *Func { if f != nil { if typ := subst.typ(f.typ); typ != f.typ { return substFunc(f, typ) } } return f } func substFunc(f *Func, typ Type) *Func { copy := *f copy.typ = typ copy.origin = f.Origin() return © } func (subst *subster) funcList(in []*Func) (out []*Func, copied bool) { out = in for i, f := range in { if g := subst.func_(f); g != f { if !copied { // first function that got substituted => allocate new out slice // and copy all functions new := make([]*Func, len(in)) copy(new, out) out = new copied = true } out[i] = g } } return } func (subst *subster) typeList(in []Type) (out []Type, copied bool) { out = in for i, t := range in { if u := subst.typ(t); u != t { if !copied { // first function that got substituted => allocate new out slice // and copy all functions new := make([]Type, len(in)) copy(new, out) out = new copied = true } out[i] = u } } return } func (subst *subster) termlist(in []*Term) (out []*Term, copied bool) { out = in for i, t := range in { if u := subst.typ(t.typ); u != t.typ { if !copied { // first function that got substituted => allocate new out slice // and copy all functions new := make([]*Term, len(in)) copy(new, out) out = new copied = true } out[i] = NewTerm(t.tilde, u) } } return } // replaceRecvType updates any function receivers that have type old to have // type new. It does not modify the input slice; if modifications are required, // the input slice and any affected signatures will be copied before mutating. // // The resulting out slice contains the updated functions, and copied reports // if anything was modified. func replaceRecvType(in []*Func, old, new Type) (out []*Func, copied bool) { out = in for i, method := range in { sig := method.Type().(*Signature) if sig.recv != nil && sig.recv.Type() == old { if !copied { // Allocate a new methods slice before mutating for the first time. // This is defensive, as we may share methods across instantiations of // a given interface type if they do not get substituted. out = make([]*Func, len(in)) copy(out, in) copied = true } newsig := *sig newsig.recv = substVar(sig.recv, new) out[i] = substFunc(method, &newsig) } } return }