{"record":{"id":"c42833281f5fd2d2","repo":"golang/go","slug":"s-does-not-s-s-s","errorCode":null,"errorMessage":"%s does not %s %s (%s)","messagePattern":"(.+?) does not (.+?) (.+?) \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/compile/internal/types2/instantiate.go","lineNumber":228,"sourceCode":"\t}\n\n\tpanic(fmt.Sprintf(\"%v: %s\", pos, msg))\n}\n\n// check may be nil; pos is used only if check is non-nil.\nfunc (check *Checker) verify(pos syntax.Pos, tparams []*TypeParam, targs []Type, ctxt *Context) (int, error) {\n\tsmap := makeSubstMap(tparams, targs)\n\tfor i, tpar := range tparams {\n\t\t// Ensure that we have a (possibly implicit) interface as type bound (go.dev/issue/51048).\n\t\ttpar.iface()\n\t\t// The type parameter bound is parameterized with the same type parameters\n\t\t// as the instantiated type; before we can use it for bounds checking we\n\t\t// need to instantiate it with the type arguments with which we instantiated\n\t\t// the parameterized type.\n\t\tbound := check.subst(pos, tpar.bound, smap, nil, ctxt)\n\t\tvar cause string\n\t\tif !check.implements(targs[i], bound, true, &cause) {\n\t\t\treturn i, errors.New(cause)\n\t\t}\n\t}\n\treturn -1, nil\n}\n\n// implements checks if V implements T. The receiver may be nil if implements\n// is called through an exported API call such as AssignableTo. If constraint\n// is set, T is a type constraint.\n//\n// If the provided cause is non-nil, it may be set to an error string\n// explaining why V does not implement (or satisfy, for constraints) T.\nfunc (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {\n\tVu := V.Underlying()\n\tTu := T.Underlying()\n\tif !isValid(Vu) || !isValid(Tu) {\n\t\treturn true // avoid follow-on errors\n\t}\n\tif p, _ := Vu.(*Pointer); p != nil && !isValid(p.base.Underlying()) {","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/compile/internal/types2/instantiate.go#L210-L246","documentation":"Produced by types2 Checker.verify (src/cmd/compile/internal/types2/instantiate.go:228) when instantiating a generic type/function and a type argument fails to satisfy its type-parameter bound. The actual message text is assembled in Checker.implements via check.sprintf(\"%s does not %s %s (%s)\", V, verb, T, detail); verify wraps the cause string in errors.New. The verb is 'satisfy' for constraints or 'implement' for interfaces, and detail explains the specific mismatch (e.g. 'X is not an interface', or a missing method).","triggerScenarios":"Instantiating a generic type or function with a concrete type argument that does not meet its constraint: either the bound is not an interface at all, or the type lacks a required method, or the type is not in the constraint's type set. Examples: type T[P fmt.Stringer] instantiated with T[int]; type Set[T comparable] instantiated with Set[[]byte].","commonSituations":"Passing a non-comparable type to a comparable-constrained generic (slices, maps); passing a struct without a required method to a method-constrained generic; a constraint that was narrowed and old call sites no longer fit; cross-package generic API misuse.","solutions":["Read the parenthesized detail to identify the missing method or the non-interface bound, then satisfy it on the type argument.","If the argument is correct, relax/fix the constraint (e.g. add the method to an embedded interface, or use constraints.Ordered / comparable correctly).","For comparable constraints, switch to a comparable type argument or wrap the value.","Re-check the generic signature against the call site after any refactor of the constraint."],"exampleFix":"// before\npackage main\nimport \"fmt\"\ntype Stringer[T any] interface{ String() string }\nfunc Print[T fmt.Stringer](v T) { fmt.Println(v.String()) }\nfunc main() { Print(42) } // int has no String()\n// after\ntype MyInt int\nfunc (m MyInt) String() string { return fmt.Sprint(int(m)) }\nfunc main() { Print(MyInt(42)) }","handlingStrategy":"validation","validationCode":"// Use types2 to pre-check that a type argument satisfies a generic constraint\n// before committing to the instantiation at scale.\n// (Conceptual; in real code, rely on the compiler error and adjust the type/constraint.)\nfunc satisfiesConstraint(typeArg, constraintExpr string) bool {\n    // pseudo: invoke go/types Instantiate + Check in a test harness\n    return true // placeholder\n}","typeGuard":"// Narrow a type argument to a method-bearing constraint at compile time.\ntype Stringer interface { String() string }\nfunc assertStringer[T any](v T) Stringer {\n    s, ok := any(v).(Stringer)\n    if !ok { panic(\"type argument does not satisfy fmt.Stringer constraint\") }\n    return s\n}","tryCatchPattern":null,"preventionTips":["Read the parenthesized detail to find the missing method or non-interface bound before changing code.","Keep constraints minimal and well-documented so callers know what is required.","Add unit tests that instantiate generics with representative type arguments to catch violations early.","When narrowing a constraint, audit all existing instantiation sites."],"tags":["compiler","generics","type-checking","constraints","types2","type-arguments"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}