diff --git a/gopls/internal/golang/origin.go b/gopls/internal/golang/origin.go
index aa77a9b..cdaec01 100644
--- a/gopls/internal/golang/origin.go
+++ b/gopls/internal/golang/origin.go
@@ -10,7 +10,13 @@
// with the same origin as the provided obj (which may be a synthetic object
// created during instantiation).
func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool {
+ if objSet[obj] {
+ return true // fast path: exact match (common for non-generic code)
+ }
objOrigin := origin(obj)
+ if objOrigin == obj {
+ return false // non-generic: origin is identity, so no match
+ }
for target := range objSet {
if origin(target) == objOrigin {
return true
diff --git a/gopls/internal/golang/references.go b/gopls/internal/golang/references.go
index ed89c33..91e992a 100644
--- a/gopls/internal/golang/references.go
+++ b/gopls/internal/golang/references.go
@@ -599,10 +599,20 @@
return false
}
+ // Collect target names for fast pre-filtering:
+ // skip identifiers whose name can't match any target.
+ targetNames := make(map[string]struct{}, len(targets))
+ for obj := range targets {
+ targetNames[obj.Name()] = struct{}{}
+ }
+
// Scan through syntax looking for uses of one of the target objects.
for _, pgf := range pkg.CompiledGoFiles() {
for curId := range pgf.Cursor().Preorder((*ast.Ident)(nil)) {
id := curId.Node().(*ast.Ident)
+ if _, ok := targetNames[id.Name]; !ok {
+ continue
+ }
if obj, ok := pkg.TypesInfo().Uses[id]; ok && matches(obj) {
report(mustLocation(pgf, id), false)
}