internal: Simplify binding hash computation in syntax highlighting

This commit is contained in:
Lukas Wirth 2026-02-07 09:28:00 +01:00
parent 9aebf045fb
commit 6fde77cd60
4 changed files with 25 additions and 50 deletions

View file

@ -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);

View file

@ -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<Option<DefWithBody>> = vec![];
let mut per_body_cache: FxHashMap<DefWithBody, (FxHashSet<_>, FxHashMap<Name, u32>)> =
FxHashMap::default();
let mut per_body_cache: FxHashMap<DefWithBody, FxHashSet<_>> = 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,

View file

@ -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<hir::Crate>,
bindings_shadow_count: Option<&mut FxHashMap<hir::Name, u32>>,
is_unsafe_node: &impl Fn(AstPtr<Either<ast::Expr, ast::Pat>>) -> 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<hir::Crate>,
bindings_shadow_count: Option<&mut FxHashMap<hir::Name, u32>>,
binding_hash: &mut Option<u64>,
is_unsafe_node: &impl Fn(AstPtr<Either<ast::Expr, ast::Pat>>) -> 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<hir::Name, u32>>,
binding_hash: &mut Option<u64>,
is_unsafe_node: &impl Fn(AstPtr<Either<ast::Expr, ast::Pat>>) -> bool,
krate: Option<hir::Crate>,
@ -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::<ide_db::FxHasher>((name.as_str(), shadow_count))
}
pub(super) fn highlight_def(
sema: &Semantics<'_, RootDatabase>,
krate: Option<hir::Crate>,

View file

@ -42,14 +42,14 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="18084384843626695225" style="color: hsl(154,95%,53%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="5697120079570210533" style="color: hsl(268,86%,80%);">x</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="18084384843626695225" style="color: hsl(154,95%,53%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="4222724691718692706" style="color: hsl(156,71%,51%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="18084384843626695225" style="color: hsl(154,95%,53%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="0" style="color: hsl(74,59%,48%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="1" style="color: hsl(152,51%,64%);">x</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="0" style="color: hsl(74,59%,48%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2" style="color: hsl(272,82%,82%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="0" style="color: hsl(74,59%,48%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="17855021198829413584" style="color: hsl(230,76%,79%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="16380625810977895757" style="color: hsl(262,75%,75%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="17855021198829413584" style="color: hsl(230,76%,79%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration reference" data-binding-hash="3" style="color: hsl(107,98%,81%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration" data-binding-hash="4" style="color: hsl(241,93%,64%);">y</span> <span class="operator">=</span> <span class="variable reference" data-binding-hash="3" style="color: hsl(107,98%,81%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">bar</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable reference" data-binding-hash="18084384843626695225" style="color: hsl(154,95%,53%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable reference" data-binding-hash="0" style="color: hsl(74,59%,48%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span>
<span class="brace">}</span></code></pre>