fix: don't drop references with more than one definition.

Implicit field references during struct initialization were
being dropped because get_definition was returning None because
there were multiple definitions.

This adds a new helper, `get_defintions`, that supports returning
more than one definition for a given token and hooks it up.

Fixes #19393
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 1244132..057d635 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -1,17 +1,17 @@
 //! This module provides `StaticIndex` which is used for powering
 //! read-only code browsers and emitting LSIF
 
+use arrayvec::ArrayVec;
 use hir::{Crate, HirFileIdExt, Module, Semantics, db::HirDatabase};
 use ide_db::{
     FileId, FileRange, FxHashMap, FxHashSet, RootDatabase,
     base_db::{RootQueryDb, SourceDatabase, VfsPath},
-    defs::Definition,
+    defs::{Definition, IdentClass},
     documentation::Documentation,
     famous_defs::FamousDefs,
-    helpers::get_definition,
 };
 use span::Edition;
-use syntax::{AstNode, SyntaxKind::*, SyntaxNode, T, TextRange};
+use syntax::{AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T, TextRange};
 
 use crate::navigation_target::UpmappingResult;
 use crate::{
@@ -126,6 +126,22 @@
     )
 }
 
+// FIXME: This is a weird function
+fn get_definitions(
+    sema: &Semantics<'_, RootDatabase>,
+    token: SyntaxToken,
+) -> Option<ArrayVec<Definition, 2>> {
+    for token in sema.descend_into_macros_exact(token) {
+        let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
+        if let Some(defs) = def {
+            if !defs.is_empty() {
+                return Some(defs);
+            }
+        }
+    }
+    None
+}
+
 pub enum VendoredLibrariesConfig<'a> {
     Included { workspace_root: &'a VfsPath },
     Excluded,
@@ -257,11 +273,14 @@
         for token in tokens {
             let range = token.text_range();
             let node = token.parent().unwrap();
-            let def = match get_definition(&sema, token.clone()) {
-                Some(it) => it,
+            match get_definitions(&sema, token.clone()) {
+                Some(it) => {
+                    for i in it {
+                        add_token(i, range, &node);
+                    }
+                }
                 None => continue,
             };
-            add_token(def, range, &node);
         }
         self.files.push(result);
     }
@@ -308,7 +327,7 @@
 #[cfg(test)]
 mod tests {
     use crate::{StaticIndex, fixture};
-    use ide_db::{FileRange, FxHashSet, base_db::VfsPath};
+    use ide_db::{FileRange, FxHashMap, FxHashSet, base_db::VfsPath};
     use syntax::TextSize;
 
     use super::VendoredLibrariesConfig;
@@ -363,6 +382,71 @@
         }
     }
 
+    #[track_caller]
+    fn check_references(
+        #[rust_analyzer::rust_fixture] ra_fixture: &str,
+        vendored_libs_config: VendoredLibrariesConfig<'_>,
+    ) {
+        let (analysis, ranges) = fixture::annotations_without_marker(ra_fixture);
+        let s = StaticIndex::compute(&analysis, vendored_libs_config);
+        let mut range_set: FxHashMap<_, i32> = ranges.iter().map(|it| (it.0, 0)).collect();
+
+        // Make sure that all references have at least one range. We use a HashMap instead of a
+        // a HashSet so that we can have more than one reference at the same range.
+        for (_, t) in s.tokens.iter() {
+            for r in &t.references {
+                if r.is_definition {
+                    continue;
+                }
+                if r.range.range.start() == TextSize::from(0) {
+                    // ignore whole file range corresponding to module definition
+                    continue;
+                }
+                match range_set.entry(r.range) {
+                    std::collections::hash_map::Entry::Occupied(mut entry) => {
+                        let count = entry.get_mut();
+                        *count += 1;
+                    }
+                    std::collections::hash_map::Entry::Vacant(_) => {
+                        panic!("additional reference {r:?}");
+                    }
+                }
+            }
+        }
+        for (range, count) in range_set.iter() {
+            if *count == 0 {
+                panic!("unfound reference {range:?}");
+            }
+        }
+    }
+
+    #[test]
+    fn field_initialization() {
+        check_references(
+            r#"
+struct Point {
+    x: f64,
+     //^^^
+    y: f64,
+     //^^^
+}
+    fn foo() {
+        let x = 5.;
+        let y = 10.;
+        let mut p = Point { x, y };
+                  //^^^^^   ^  ^
+        p.x = 9.;
+      //^ ^
+        p.y = 10.;
+      //^ ^
+    }
+"#,
+            VendoredLibrariesConfig::Included {
+                workspace_root: &VfsPath::new_virtual_path("/workspace".to_owned()),
+            },
+        );
+    }
+
     #[test]
     fn struct_and_enum() {
         check_all_ranges(
@@ -387,6 +471,17 @@
                 workspace_root: &VfsPath::new_virtual_path("/workspace".to_owned()),
             },
         );
+
+        check_references(
+            r#"
+struct Foo;
+enum E { X(Foo) }
+   //      ^^^
+"#,
+            VendoredLibrariesConfig::Included {
+                workspace_root: &VfsPath::new_virtual_path("/workspace".to_owned()),
+            },
+        );
     }
 
     #[test]