blob: b94d048a13509f05c05027bfde4e8c45a081a2b7 [file] [log] [blame]
Test of local Implementation queries using function signatures.
Assertions:
- Query on "func" of a function type returns the corresponding concrete functions.
- Query on "func" of a concrete function returns corresponding function types.
- Query on "(" of a dynamic function call returns corresponding function types.
- Different signatures (Nullary vs Handler) don't correspond.
The @loc markers use the suffixes Func, Type, Call for the three kinds.
Each query maps between these two sets: {Func} <=> {Type,Call}.
-- go.mod --
module example.com
go 1.18
-- a/a.go --
package a
// R is short for Record.
type R struct{}
// H is short for Handler.
type H func(*R) //@ loc(HType, "func"), implementation("func", aFunc, bFunc, cFunc)
func aFunc(*R) {} //@ loc(aFunc, "func"), implementation("func", HType, hParamType, hCall)
var bFunc = func(*R) {} //@ loc(bFunc, "func"), implementation("func", hParamType, hCall, HType)
func nullary() { //@ loc(nullaryFunc, "func"), implementation("func", Nullary, fieldCall)
cFunc := func(*R) {} //@ loc(cFunc, "func"), implementation("func", hParamType, hCall, HType)
_ = cFunc
}
type Nullary func() //@ loc(Nullary, "func")
func _(
h func(*R)) { //@ loc(hParamType, "func"), implementation("func", aFunc, bFunc, cFunc)
_ = aFunc // pacify unusedfunc
_ = nullary // pacify unusedfunc
_ = h
h(nil) //@ loc(hCall, "("), implementation("(", aFunc, bFunc, cFunc)
}
// generics:
func _[T any](complex128) {
f1 := func(T) int { return 0 } //@ loc(f1Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call)
f2 := func(string) int { return 0 } //@ loc(f2Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call)
f3 := func(int) int { return 0 } //@ loc(f3Func, "func"), implementation("func", f1Call)
f1(*new(T)) //@ loc(f1Call, "("), implementation("(", f1Func, f2Func, f3Func, f4Func)
f2("") //@ loc(f2Call, "("), implementation("(", f1Func, f2Func, f4Func)
_ = f3 // not called
}
func f4[T any](T) int { return 0 } //@ loc(f4Func, "func"), implementation("func", fParamType, fCall, f1Call, f2Call)
var _ = f4[string] // pacify unusedfunc
func _(
f func(string) int, //@ loc(fParamType, "func"), implementation("func", f1Func, f2Func, f4Func)
err error) {
f("") //@ loc(fCall, "("), implementation("(", f1Func, f2Func, f4Func)
struct{x Nullary}{}.x() //@ loc(fieldCall, "("), implementation("(", nullaryFunc)
// Calls that are not dynamic function calls:
_ = len("") //@ implementation("(", err="not a dynamic function call")
_ = int(0) //@ implementation("(", err="not a dynamic function call")
_ = error.Error(nil) //@ implementation("(", err="not a dynamic function call")
_ = err.Error() //@ implementation("(", err="not a dynamic function call")
_ = f4(0) //@ implementation("(", err="not a dynamic function call"), loc(f4Call, "(")
}