Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/unreleased/duplicate-libraries-walk.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- The duplicate-library check of #1462 keeps only the first declaration of each library package name until a second is met, instead of a list per name. Loading an empty model into a REPL allocates 2 038 times instead of 2 155, recovering most of what #1462 added over 0.11.0's 2 022 on the same toolchain; the walk over every library document's root packages remains, so the load is not back to 0.11.0's time.
14 changes: 9 additions & 5 deletions internal/check/workspace/duplicate_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type duplicate struct {
// are grouped by the pair of trees the copies lie in, so two copies of the whole
// standard library are one warning, not one per file.
func DuplicateLibraries(idx *symbols.Index) []Finding {
// Nearly every library package is declared once, so only the first
// declaration of a name is kept until a second is met.
first := map[string]*symbols.Symbol{}
byName := map[string][]*symbols.Symbol{}
var order []string
for _, doc := range idx.Documents() {
Expand All @@ -65,19 +68,20 @@ func DuplicateLibraries(idx *symbols.Index) []Finding {
if sym.Name == "" || sym.Kind != symbols.SymbolPackage || !(library || symbols.IsLibraryPackage(sym)) {
return true
}
if _, seen := byName[sym.Name]; !seen {
if before, seen := first[sym.Name]; !seen {
first[sym.Name] = sym
} else if syms := byName[sym.Name]; syms == nil {
order = append(order, sym.Name)
byName[sym.Name] = []*symbols.Symbol{before, sym}
} else {
byName[sym.Name] = append(syms, sym)
}
byName[sym.Name] = append(byName[sym.Name], sym)
return true
})
}
var dups []duplicate
for _, name := range order {
syms := byName[name]
if len(syms) < 2 {
continue
}
used := usedDeclaration(idx, name, syms)
d := duplicate{name: name, used: used}
seen := map[string]bool{used.DocName: true}
Expand Down
Loading