var doc … var Analyzer … func run(pass *analysis.Pass) (interface{ … } func runFunc(pass *analysis.Pass, fn *ssa.Function) { … } type fact … func (f fact) negate() fact { … } type nilness … const isnonnil … const unknown … const isnil … var nilnessStrings … func (n nilness) String() string { … } // nilnessOf reports whether v is definitely nil, definitely not nil, // or unknown given the dominating stack of facts. func nilnessOf(stack []fact, v ssa.Value) nilness { … } func slice2ArrayPtrLen(v *ssa.SliceToArrayPointer) int64 { … } // If b ends with an equality comparison, eq returns the operation and // its true (equal) and false (not equal) successors. func eq(b *ssa.BasicBlock) (op *ssa.BinOp, tsucc, fsucc *ssa.BasicBlock) { … } // expandFacts takes a single fact and returns the set of facts that can be // known about it or any of its related values. Some operations, like // ChangeInterface, have transitive nilness, such that if you know the // underlying value is nil, you also know the value itself is nil, and vice // versa. This operation allows callers to match on any of the related values // in analyses, rather than just the one form of the value that happened to // appear in a comparison. // // This work must be in addition to unwrapping values within nilnessOf because // while this work helps give facts about transitively known values based on // inferred facts, the recursive check within nilnessOf covers cases where // nilness facts are intrinsic to the underlying value, such as a zero value // interface variables. // // ChangeInterface is the only expansion currently supported, but others, like // Slice, could be added. At this time, this tool does not check slice // operations in a way this expansion could help. See // https://play.golang.org/p/mGqXEp7w4fR for an example. func expandFacts(f fact) []fact { … } type facts … func (ff facts) negate() facts { … } func is[T any](x any) bool { … } func isNillable(t types.Type) bool { … } // isRangeIndex reports whether the instruction is a slice indexing // operation slice[i] within a "for range slice" loop. The operation // could be explicit, such as slice[i] within (or even after) the // loop, or it could be implicit, such as "for i, v := range slice {}". // (These cannot be reliably distinguished.) func isRangeIndex(instr *ssa.IndexAddr) bool { … }