// Package diag holds plumb's diagnostic vocabulary: the located, user-facing// error type, the sentinel errors every phase wraps, and the position helpers// that order diagnostics deterministically. It is the leaf every other package// reaches for when it must reject input or compare source positions.
package diagimport ()// ErrorKind is a sentinel diagnostic kind: a constant string that implements// error. Making it a named string type lets the sentinels below be true compile-// time constants while still being wrappable and matchable with errors.Is (a// string is comparable, so errors.Is compares them by value).typeErrorKindstring// Error returns the sentinel's message.func ( ErrorKind) () string { returnstring() }// Sentinel errors for every condition plumb can reject. Each diagnostic wraps// one of these, so callers and tests can classify a failure with errors.Is// rather than matching message text. The human-readable specifics travel in the// wrapped detail; the source position travels on *Error.const (ErrNoDirectivesErrorKind = "no //plumb: directives found"ErrInvalidSetNameErrorKind = "invalid set name"ErrMisplacedDirectiveErrorKind = "directive in an unsupported position"ErrDuplicateDirectiveErrorKind = "duplicate provider directive"ErrInvalidConversionErrorKind = "invalid conversion"ErrUntypedConstantErrorKind = "untyped constant provider"ErrBlankProviderErrorKind = "blank provider name"ErrInitProviderErrorKind = "provider directive on func init"ErrEmbeddedFieldErrorKind = "provider directive on embedded field"ErrEmbeddedInterfaceErrorKind = "provider directive on embedded interface"ErrConstraintInterfaceMethodErrorKind = "method provider on constraint interface"ErrStructProviderErrorKind = "invalid struct-type provider"ErrAmbiguousProducerErrorKind = "ambiguous producer"ErrMultipleErrorsErrorKind = "multiple error results"ErrDependencyCycleErrorKind = "dependency cycle"ErrUnusedTemplateErrorKind = "unused result-generic template"ErrBareTypeParamResultErrorKind = "bare type-parameter result"ErrAmbiguousTemplatesErrorKind = "ambiguous templates"ErrNonTerminatingErrorKind = "non-terminating generic instantiation"ErrUnexportedProviderErrorKind = "unexported provider referenced across a package boundary"ErrUnreachableTypeErrorKind = "type not reachable from the destination package"ErrInvalidTypeErrorKind = "type does not type-check"ErrReservedNameErrorKind = "reserved function name with a non-empty signature"ErrShadowsPredeclaredErrorKind = "set name shadows a predeclared identifier"ErrDestShadowsPredeclaredErrorKind = "destination declaration shadows a predeclared identifier"ErrSetNameCollisionErrorKind = "set name collides with an existing declaration")// Error is a located, user-facing diagnostic. It wraps one of the sentinel// errors above (reachable with errors.Is and errors.Unwrap) and carries the// source position where the problem occurred. Violations of plumb's own// internal invariants are panics instead, never *Error.typeErrorstruct {postoken.Position// the offending source position; zero if none applieserrerror// sentinel wrapped with the specific detail}func ( *Error) () string {if .pos.IsValid() {returnfmt.Sprintf("%s: %s", .pos, .err.Error()) }return .err.Error()}// Unwrap exposes the wrapped chain so errors.Is/As reach the sentinel.func ( *Error) () error { return .err }// Errorf builds a located *Error wrapping the given sentinel kind. detail is a// Printf-style format describing the specifics; it should not repeat the// sentinel's own words.func ( token.Position, ErrorKind, string, ...any) *Error { := fmt.Errorf("%w: "+, append([]any{}, ...)...)return &Error{pos: , err: }}// Sentinel returns a positionless *Error wrapping msg. It exists for internal// control-flow signals that ride the *Error return channel but are compared by// identity, never by content: unlike a zero-value *Error (whose nil wrapped err// makes Error() panic), a Sentinel is safe to format if one is ever accidentally// printed or logged.func ( string) *Error {return &Error{err: errors.New()}}// PosIn resolves p to a token.Position within fset, returning the zero Position// when fset is nil or p is invalid.func ( *token.FileSet, token.Pos) token.Position {if == nil || !.IsValid() {returntoken.Position{} }return .Position()}// CmpPos orders positions deterministically: by file name, then byte offset.// This is the single ordering authority for source-anchored decisions. Read// order (of packages, files, or map entries) never participates. It is the// int-returning comparator backing slices.SortFunc/SortStableFunc/MinFunc.func (, token.Position) int {returncmp.Or(cmp.Compare(.Filename, .Filename), cmp.Compare(.Offset, .Offset))}// Earlier returns the source-earlier of two diagnostics by CmpPos, treating a nil// *Error as "no fault" (later than any real one); it returns nil only when both// are nil. Use it to report the fault a reader would fix first when a phase finds// faults out of source order.func (, *Error) *Error {switch {case == nil:returncase == nil:returncaseCmpPos(.pos, .pos) < 0:returndefault:return }}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)