1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Salsa-tracked FQCN resolution.
//!
//! Bridges the `Arc<dyn ClassResolver>` side-channel (which lives outside
//! salsa because trait objects don't compose with `salsa::Update`) into the
//! salsa invalidation graph via a one-field input ([`ResolverConfig`])
//! whose `revision` is bumped on every resolver change.
//!
//! Phase-3 callers (`find_class` / `find_function` / `find_method` tracked
//! queries) consume [`resolve_fqcn_to_path`] to map FQCN → file path, then
//! demand `collect_file_definitions` on the resulting `SourceFile`. When
//! the resolver changes, salsa correctly invalidates everything downstream.
//!
//! Foundation laid by Phase 2 of
//! `~/.claude/plans/sequential-popping-parasol.md`.
use Arc;
use crateMirDatabase;
use Name;
/// Singleton salsa input that anchors resolver-derived tracked queries on
/// a revision counter. The actual `Arc<dyn ClassResolver>` lives off-db
/// (see `MirDatabase::current_resolver`); `revision` is bumped each time
/// the resolver is replaced so salsa invalidates dependents.
/// Salsa-interned FQCN used as the key for [`resolve_fqcn_to_path`].
///
/// Salsa requires tracked-function arguments to be salsa structs; this
/// gives the FQCN a stable interned identity so the resolution result can
/// be memoized per name. Cheap to construct (`Fqcn::new(db, symbol)`);
/// equality is by ustr pointer (O(1)).
///
/// Never collected: [`Self::interned`] reuses ids without recording a salsa
/// read, which is only sound for slots that can't be reused. Retention is
/// bounded like [`Name`]'s, whose strings are never freed.
/// Resolve an FQCN to its defining file path via the configured resolver.
///
/// Tracked: depends on [`ResolverConfig::revision`], so callers reading
/// this from a tracked context are invalidated when the resolver changes.
/// Reads the resolver side-channel via [`MirDatabase::current_resolver`]
/// — that read is *not* salsa-tracked, but the revision anchor makes it
/// correct as long as every resolver swap bumps the revision (enforced by
/// `MirDbStorage::set_resolver`).
///
/// Returns `None` when no resolver is configured or the resolver couldn't
/// map `fqcn`. The anchor is read even then, so attaching a resolver later
/// invalidates the miss.
/// Composite: resolve an FQCN to a registered [`crate::db::SourceFile`] if
/// the workspace has the defining file's text loaded.
///
/// Not currently tracked: it composes `resolve_fqcn_to_path` (tracked)
/// with `MirDatabase::lookup_source_file` (untracked map read). Phase 3
/// will likely promote the path-keyed lookup to a tracked query to fully
/// participate in salsa's invalidation graph.