// scc computes strongly connected components (SCCs) of `g` using the // classical Tarjan's algorithm for SCCs. The result is two slices: // - sccs: the SCCs, each represented as a slice of node indices // - idxToSccID: the inverse map, from node index to SCC number. // // The SCCs are sorted in reverse topological order: for SCCs // with ids X and Y s.t. X < Y, Y comes before X in the topological order. func scc(g *vtaGraph) (sccs [][]idx, idxToSccID []int) { … } func min(x, y int) int { … } // LastIndex returns the index of the last occurrence of v in s, or -1 if v is // not present in s. // // LastIndex iterates backwards through the elements of s, stopping when the == // operator determines an element is equal to v. func slicesLastIndex[S ~[]E, E comparable](s S, v E) int { … } type propType … type propTypeMap … // propTypes returns a go1.23 iterator for the propTypes associated with // node `n` in map `ptm`. func (ptm propTypeMap) propTypes(n node) func(yield func(propType) bool) { … } // propagate reduces the `graph` based on its SCCs and // then propagates type information through the reduced // graph. The result is a map from nodes to a set of types // and functions, stemming from higher-order data flow, // reaching the node. `canon` is used for type uniqueness. func propagate(graph *vtaGraph, canon *typeutil.Map) propTypeMap { … } // hasInitialTypes check if a node can have initial types. // Returns true iff `n` is not a panic, recover, nestedPtr* // node, nor a node whose type is an interface. func hasInitialTypes(n node) bool { … } // getPropType creates a propType for `node` based on its type. // propType.typ is always node.Type(). If node is function, then // propType.val is the underlying function; nil otherwise. func getPropType(node node, canon *typeutil.Map) propType { … }