diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go index 378d0166..96289c9b 100644 --- a/internal/pkg/pkg.go +++ b/internal/pkg/pkg.go @@ -1499,41 +1499,52 @@ func (e *CureError) Error() string { return e.Err.Error() } type DependencyCureError []*CureError // unwrapM recursively expands underlying errors into a caller-supplied map. -func (e *DependencyCureError) unwrapM(me map[Artifact]*CureError) { +func (e *DependencyCureError) unwrapM( + ir *IRCache, + me map[unique.Handle[ID]]*CureError, +) { for _, err := range *e { - if _, ok := me[err.A]; ok { + id := ir.Ident(err.A) + if _, ok := me[id]; ok { continue } if _e, ok := err.Err.(*DependencyCureError); ok { - _e.unwrapM(me) + _e.unwrapM(ir, me) continue } - me[err.A] = err + me[id] = err } } // unwrap recursively expands and deduplicates underlying errors. -func (e *DependencyCureError) unwrap() DependencyCureError { - me := make(map[Artifact]*CureError) - e.unwrapM(me) - errs := slices.AppendSeq( - make(DependencyCureError, 0, len(me)), - maps.Values(me), - ) +func (e *DependencyCureError) unwrap(ir *IRCache) DependencyCureError { + me := make(map[unique.Handle[ID]]*CureError) + e.unwrapM(ir, me) + type ent struct { + id unique.Handle[ID] + err *CureError + } + errs := make([]*ent, 0, len(me)) + for id, err := range me { + errs = append(errs, &ent{id, err}) + } var identBuf [2]ID - ir := NewIR() - slices.SortFunc(errs, func(a, b *CureError) int { - identBuf[0], identBuf[1] = ir.Ident(a.A).Value(), ir.Ident(b.A).Value() + slices.SortFunc(errs, func(a, b *ent) int { + identBuf[0], identBuf[1] = a.id.Value(), b.id.Value() return slices.Compare(identBuf[0][:], identBuf[1][:]) }) - return errs + _errs := make(DependencyCureError, len(errs)) + for i, v := range errs { + _errs[i] = v.err + } + return _errs } // Unwrap returns a deduplicated slice of underlying errors. func (e *DependencyCureError) Unwrap() []error { - errs := e.unwrap() + errs := e.unwrap(NewIR()) _errs := make([]error, len(errs)) for i, err := range errs { _errs[i] = err @@ -1543,13 +1554,13 @@ func (e *DependencyCureError) Unwrap() []error { // Error returns a user-facing multiline error message. func (e *DependencyCureError) Error() string { - errs := e.unwrap() + ir := NewIR() + errs := e.unwrap(ir) if len(errs) == 0 { return "invalid dependency cure outcome" } var buf strings.Builder buf.WriteString("errors curing dependencies:") - ir := NewIR() for _, err := range errs { buf.WriteString("\n\t" + reportName(err.A, ir.Ident(err.A)) + ": " + diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go index 4ce4ba6a..9d6757c7 100644 --- a/internal/pkg/pkg_test.go +++ b/internal/pkg/pkg_test.go @@ -1515,6 +1515,8 @@ func TestDependencyCureError(t *testing.T) { makeIdent := func(ident ...byte) pkg.Artifact { var a overrideIdent copy(a.id[:], ident) + // does not compare equal + a.TrivialArtifact = new(stubArtifact) return a }