From 6fde77cd60dca48cc4279c7a1cfcf73f4e111cdc Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 7 Feb 2026 09:28:00 +0100 Subject: [PATCH] internal: Simplify binding hash computation in syntax highlighting --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 4 ++ .../crates/ide/src/syntax_highlighting.rs | 19 ++++----- .../ide/src/syntax_highlighting/highlight.rs | 40 ++++--------------- .../test_data/highlight_rainbow.html | 12 +++--- 4 files changed, 25 insertions(+), 50 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 252d71fb80a4..4b615665167c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -4233,6 +4233,10 @@ impl Local { self.parent(db).module(db) } + pub fn as_id(self) -> u32 { + self.binding_id.into_raw().into_u32() + } + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; let infer = InferenceResult::for_body(db, def); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index e64fd6488f2a..ce1df6a1e7dc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ mod tests; use std::ops::ControlFlow; use either::Either; -use hir::{DefWithBody, EditionedFileId, InFile, InRealFile, MacroKind, Name, Semantics}; +use hir::{DefWithBody, EditionedFileId, InFile, InRealFile, MacroKind, Semantics}; use ide_db::{FxHashMap, FxHashSet, MiniCore, Ranker, RootDatabase, SymbolKind}; use syntax::{ AstNode, AstToken, NodeOrToken, @@ -257,8 +257,7 @@ fn traverse( // FIXME: accommodate range highlighting let mut body_stack: Vec> = vec![]; - let mut per_body_cache: FxHashMap, FxHashMap)> = - FxHashMap::default(); + let mut per_body_cache: FxHashMap> = FxHashMap::default(); // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. @@ -422,14 +421,11 @@ fn traverse( } let edition = descended_element.file_id.edition(sema.db); - let (unsafe_ops, bindings_shadow_count) = match current_body { - Some(current_body) => { - let (ops, bindings) = per_body_cache - .entry(current_body) - .or_insert_with(|| (sema.get_unsafe_ops(current_body), Default::default())); - (&*ops, Some(bindings)) - } - None => (&empty, None), + let unsafe_ops = match current_body { + Some(current_body) => per_body_cache + .entry(current_body) + .or_insert_with(|| sema.get_unsafe_ops(current_body)), + None => &empty, }; let is_unsafe_node = |node| unsafe_ops.contains(&InFile::new(descended_element.file_id, node)); @@ -438,7 +434,6 @@ fn traverse( let hl = highlight::name_like( sema, krate, - bindings_shadow_count, &is_unsafe_node, config.syntactic_name_ref_highlighting, name_like, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index dcc9a8c0d5f7..a94bbc9f041d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -5,12 +5,11 @@ use std::ops::ControlFlow; use either::Either; use hir::{AsAssocItem, HasAttrs, HasVisibility, Semantics}; use ide_db::{ - FxHashMap, RootDatabase, SymbolKind, + RootDatabase, SymbolKind, defs::{Definition, IdentClass, NameClass, NameRefClass}, syntax_helpers::node_ext::walk_pat, }; use span::Edition; -use stdx::hash_once; use syntax::{ AstNode, AstPtr, AstToken, NodeOrToken, SyntaxKind::{self, *}, @@ -64,7 +63,6 @@ pub(super) fn token( pub(super) fn name_like( sema: &Semantics<'_, RootDatabase>, krate: Option, - bindings_shadow_count: Option<&mut FxHashMap>, is_unsafe_node: &impl Fn(AstPtr>) -> bool, syntactic_name_ref_highlighting: bool, name_like: ast::NameLike, @@ -75,22 +73,15 @@ pub(super) fn name_like( ast::NameLike::NameRef(name_ref) => highlight_name_ref( sema, krate, - bindings_shadow_count, &mut binding_hash, is_unsafe_node, syntactic_name_ref_highlighting, name_ref, edition, ), - ast::NameLike::Name(name) => highlight_name( - sema, - bindings_shadow_count, - &mut binding_hash, - is_unsafe_node, - krate, - name, - edition, - ), + ast::NameLike::Name(name) => { + highlight_name(sema, &mut binding_hash, is_unsafe_node, krate, name, edition) + } ast::NameLike::Lifetime(lifetime) => match IdentClass::classify_lifetime(sema, &lifetime) { Some(IdentClass::NameClass(NameClass::Definition(def))) => { highlight_def(sema, krate, def, edition, false) | HlMod::Definition @@ -273,7 +264,6 @@ fn keyword(token: SyntaxToken, kind: SyntaxKind) -> Highlight { fn highlight_name_ref( sema: &Semantics<'_, RootDatabase>, krate: Option, - bindings_shadow_count: Option<&mut FxHashMap>, binding_hash: &mut Option, is_unsafe_node: &impl Fn(AstPtr>) -> bool, syntactic_name_ref_highlighting: bool, @@ -306,12 +296,8 @@ fn highlight_name_ref( }; let mut h = match name_class { NameRefClass::Definition(def, _) => { - if let Definition::Local(local) = &def - && let Some(bindings_shadow_count) = bindings_shadow_count - { - let name = local.name(sema.db); - let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); - *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + if let Definition::Local(local) = &def { + *binding_hash = Some(local.as_id() as u64); }; let mut h = highlight_def(sema, krate, def, edition, true); @@ -432,7 +418,6 @@ fn highlight_name_ref( fn highlight_name( sema: &Semantics<'_, RootDatabase>, - bindings_shadow_count: Option<&mut FxHashMap>, binding_hash: &mut Option, is_unsafe_node: &impl Fn(AstPtr>) -> bool, krate: Option, @@ -440,13 +425,8 @@ fn highlight_name( edition: Edition, ) -> Highlight { let name_kind = NameClass::classify(sema, &name); - if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind - && let Some(bindings_shadow_count) = bindings_shadow_count - { - let name = local.name(sema.db); - let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); - *shadow_count += 1; - *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind { + *binding_hash = Some(local.as_id() as u64); }; match name_kind { Some(NameClass::Definition(def)) => { @@ -474,10 +454,6 @@ fn highlight_name( } } -fn calc_binding_hash(name: &hir::Name, shadow_count: u32) -> u64 { - hash_once::((name.as_str(), shadow_count)) -} - pub(super) fn highlight_def( sema: &Semantics<'_, RootDatabase>, krate: Option, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html index d5401e7aec91..7c64707ac1f9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html @@ -42,14 +42,14 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
fn main() {
-    let hello = "hello";
-    let x = hello.to_string();
-    let y = hello.to_string();
+    let hello = "hello";
+    let x = hello.to_string();
+    let y = hello.to_string();
 
-    let x = "other color please!";
-    let y = x.to_string();
+    let x = "other color please!";
+    let y = x.to_string();
 }
 
 fn bar() {
-    let mut hello = "hello";
+    let mut hello = "hello";
 }
\ No newline at end of file