{"record":{"id":"126b40008dd6e3dc","repo":"golang/go","slug":"s-doesn-t-contain-type-split","errorCode":null,"errorMessage":"%s doesn't contain type split","messagePattern":"(.+?) doesn't contain type split","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/compile/internal/ir/expr.go","lineNumber":1244,"sourceCode":"\tif !types.IsExported(msym.Name) && msym.Pkg != rpkg {\n\t\tb.WriteString(\".\")\n\t\tb.WriteString(msym.Pkg.Prefix)\n\t}\n\n\tb.WriteString(\".\")\n\tb.WriteString(msym.Name)\n\tb.WriteString(suffix)\n\treturn rpkg.LookupBytes(b.Bytes())\n}\n\n// LookupMethodSelector returns the types.Sym of the selector for a method\n// named in local symbol name, as well as the types.Sym of the receiver.\n//\n// TODO(prattmic): this does not attempt to handle method suffixes (wrappers).\nfunc LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {\n\ttypeName, methName := splitType(name)\n\tif typeName == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"%s doesn't contain type split\", name)\n\t}\n\n\tif len(typeName) > 3 && typeName[:2] == \"(*\" && typeName[len(typeName)-1] == ')' {\n\t\t// Symbol name is for a pointer receiver method. We just want\n\t\t// the base type name.\n\t\ttypeName = typeName[2 : len(typeName)-1]\n\t}\n\n\ttyp = pkg.Lookup(typeName)\n\tmeth = pkg.Selector(methName)\n\treturn typ, meth, nil\n}\n\n// splitType splits a local symbol name into type and method (fn). If this a\n// free function, typ == \"\".\n//\n// N.B. closures and methods can be ambiguous (e.g., bar.func1). These cases\n// are returned as methods.","sourceCodeStart":1226,"sourceCodeEnd":1262,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/compile/internal/ir/expr.go#L1226-L1262","documentation":"Returned by LookupMethodSelector when splitType(name) yields an empty type name, meaning the symbol name has no dot at the top bracket level (it is a free function, not a method). The function expects a method symbol of the form TypeName.MethodName and refuses anything that does not contain that type/method split.","triggerScenarios":"Calling ir.LookupMethodSelector(pkg, name) with a name like \"foo\" (no dot) — splitType returns (\"\", \"foo\"), typeName == \"\" triggers the error. Names like \"Foo.Bar\" or \"(*Foo).Bar\" (after pointer stripping) are accepted.","commonSituations":"Compiler/linker internals: passing a free-function or generated symbol (closures \"foo.func1\" are treated as methods by splitType, so the real trigger is a name with literally no dot). User code does not call this directly.","solutions":["Ensure the name passed is a method symbol containing a top-level dot (e.g. Foo.Bar).","Guard the caller: if strings.Contains(name, \".\") is false or name has no method split, do not call LookupMethodSelector.","For pointer receivers, pass the (*Type).Method form; the function strips the pointer wrapper itself."],"exampleFix":"// before\n LookupMethodSelector(pkg, \"freestanding\")\n// after\n LookupMethodSelector(pkg, \"MyType.Method\")","handlingStrategy":"validation","validationCode":"// Only call LookupMethodSelector for names that look like methods.\nif !strings.Contains(name, \".\") {\n    return nil, nil, fmt.Errorf(\"not a method symbol: %s\", name)\n}\ntyp, meth, err := ir.LookupMethodSelector(pkg, name)","typeGuard":"// isMethodSymbol reports whether name is a TypeName.MethodName symbol.\nfunc isMethodSymbol(name string) bool {\n    bracket := 0\n    for _, r := range name {\n        switch r {\n        case '[': bracket++\n        case ']': bracket--\n        case '.':\n            if bracket == 0 { return true }\n        }\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Call LookupMethodSelector only on symbols known to be methods.","For pointer receivers, pass the (*Type).Method form."],"tags":["go-compiler","ir","symbols","methods","internal"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}