Source File
context.go
Belonging Package
go/types
// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.// Source: ../../cmd/compile/internal/types2/context.go// Copyright 2021 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.package typesimport ()// This file contains a definition of the type-checking context; an opaque type// that may be supplied by users during instantiation.//// Contexts serve two purposes:// - reduce the duplication of identical instances// - short-circuit instantiation cycles//// For the latter purpose, we must always have a context during instantiation,// whether or not it is supplied by the user. For both purposes, it must be the// case that hashing a pointer-identical type produces consistent results// (somewhat obviously).//// However, neither of these purposes require that our hash is perfect, and so// this was not an explicit design goal of the context type. In fact, due to// concurrent use it is convenient not to guarantee de-duplication.//// Nevertheless, in the future it could be helpful to allow users to leverage// contexts to canonicalize instances, and it would probably be possible to// achieve such a guarantee.// A Context is an opaque type checking context. It may be used to share// identical type instances across type-checked packages or calls to// Instantiate. Contexts are safe for concurrent use.//// The use of a shared context does not guarantee that identical instances are// deduplicated in all cases.type Context struct {mu sync.MutextypeMap map[string][]ctxtEntry // type hash -> instances entriesnextID int // next unique IDoriginIDs map[Type]int // origin type -> unique ID}type ctxtEntry struct {orig Typetargs []Typeinstance Type // = orig[targs]}// NewContext creates a new Context.func () *Context {return &Context{typeMap: make(map[string][]ctxtEntry),originIDs: make(map[Type]int),}}// instanceHash returns a string representation of typ instantiated with targs.// The hash should be a perfect hash, though out of caution the type checker// does not assume this. The result is guaranteed to not contain blanks.func ( *Context) ( Type, []Type) string {assert( != nil)assert( != nil)var bytes.Buffer:= newTypeHasher(&, ).string(strconv.Itoa(.getID()))// Because we've already written the unique origin ID this call to h.typ is// unnecessary, but we leave it for hash readability. It can be removed later// if performance is an issue..typ()if len() > 0 {// TODO(rfindley): consider asserting on isGeneric(typ) here, if and when// isGeneric handles *Signature types..typeList()}return strings.ReplaceAll(.String(), " ", "#")}// lookup returns an existing instantiation of orig with targs, if it exists.// Otherwise, it returns nil.func ( *Context) ( string, Type, []Type) Type {.mu.Lock()defer .mu.Unlock()for , := range .typeMap[] {if identicalInstance(, , .orig, .targs) {return .instance}if debug {// Panic during development to surface any imperfections in our hash.panic(fmt.Sprintf("non-identical instances: (orig: %s, targs: %v) and %s", , , .instance))}}return nil}// update de-duplicates inst against previously seen types with the hash h.// If an identical type is found with the type hash h, the previously seen// type is returned. Otherwise, inst is returned, and recorded in the Context// for the hash h.func ( *Context) ( string, Type, []Type, Type) Type {assert( != nil).mu.Lock()defer .mu.Unlock()for , := range .typeMap[] {if == nil || Identical(, .instance) {return .instance}if debug {// Panic during development to surface any imperfections in our hash.panic(fmt.Sprintf("%s and %s are not identical", , .instance))}}.typeMap[] = append(.typeMap[], ctxtEntry{orig: ,targs: ,instance: ,})return}// getID returns a unique ID for the type t.func ( *Context) ( Type) int {.mu.Lock()defer .mu.Unlock(), := .originIDs[]if ! {= .nextID.originIDs[] =.nextID++}return}
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64)