pub struct DiagnosticsLayer { /* private fields */ }Expand description
Subsystem-wide diagnostics state.
Reads are wait-free. Self::diagnostics_for,
Self::line_severity, Self::diagnostics_on_line, and
the count helpers all go through one ArcSwap::load. The
renderer’s per-line line_severity(uri, line) call (50 lines
× 60 Hz = 3000/s on the render thread per the audit) no
longer takes a mutex.
Writes serialise on a brief mutex. Self::apply and the
clear_* methods take a small write-side lock just long
enough to clone the current snapshot, mutate it, recompute
the affected URI’s by_uri entry, and ArcSwap::store it.
Writers don’t block readers (ArcSwap is RCU-flavoured); two
concurrent writers serialise via the write lock.
Cloneable; every clone shares the same ArcSwap cell + the
same write lock (so the layer behaves as one logical state
across actor pumps).
Implementations§
Source§impl DiagnosticsLayer
impl DiagnosticsLayer
Sourcepub fn new(logger: LspLogger) -> Self
pub fn new(logger: LspLogger) -> Self
Build an empty layer. The logger is used for “dropped stale” telemetry.
Sourcepub fn set_wake(&self, wake: Arc<Notify>)
pub fn set_wake(&self, wake: Arc<Notify>)
Install the render-wake Notify (the editor’s async_landed).
Boot calls this once after the layer is built; every subsequent
apply fires it so a pushed diagnostic change repaints
off-keystroke. Idempotent (last wins); shared across all clones.
Sourcepub fn snapshot_revision(&self) -> usize
pub fn snapshot_revision(&self) -> usize
§12 paint gate: a cheap change-token for the current snapshot.
Every Self::apply swaps a fresh Arc<DiagnosticsSnapshot>
into the cell, so the snapshot’s pointer address is a precise,
allocation-free “did the diagnostics change” signal — stable
while unchanged, distinct after any push (including the CLEAR
when an error is fixed). build_render_state folds this into
RenderState::paint_revision so a pushed diagnostics change
(which is an overlay, deliberately excluded from the cells
MatrixVersion — see lattice-cells/src/version.rs) still
requests an off-keystroke paint. Without it, the gutter /
underline / inline-summary would update in the snapshot but not
repaint until the next keypress (the “undo → diagnostic
disappears” report).
Sourcepub fn apply(&self, event: DiagnosticEvent)
pub fn apply(&self, event: DiagnosticEvent)
Apply one DiagnosticEvent. Drops stale events; clears
state on empty diagnostics; otherwise replaces the
(uri, server_id) entry. Single-snapshot publish at the
end: readers either see the prior state or the post-write
state, never a torn intermediate.
Sourcepub fn diagnostics_for(&self, uri: &Uri) -> Vec<Diagnostic>
pub fn diagnostics_for(&self, uri: &Uri) -> Vec<Diagnostic>
All diagnostics for a URI, merged across every server
that’s attached to it. Returns an empty Vec when
there are none.
Sourcepub fn diagnostics_arc(&self, uri: &Uri) -> Option<Arc<[Diagnostic]>>
pub fn diagnostics_arc(&self, uri: &Uri) -> Option<Arc<[Diagnostic]>>
Wait-free Arc<[Diagnostic]> borrow of the merged
diagnostics for uri. Preferred on the hot path
(renderer / picker fan-out) – avoids the per-call
Vec allocation that diagnostics_for does.
Sourcepub fn diagnostics_on_line(&self, uri: &Uri, line: u32) -> Vec<Diagnostic>
pub fn diagnostics_on_line(&self, uri: &Uri, line: u32) -> Vec<Diagnostic>
Diagnostics that overlap line. Half-open at the end:
a range ending on line N column 0 covers lines
start.line ..= end.line - 1 (LSP convention). To match
the gutter glyph behaviour we still surface diagnostics
whose end is exactly at line N column 0 if N is the
current line – callers prefer “show, don’t hide” for
edge cases.
Sourcepub fn line_severity(&self, uri: &Uri, line: u32) -> Option<DiagnosticSeverity>
pub fn line_severity(&self, uri: &Uri, line: u32) -> Option<DiagnosticSeverity>
Most severe severity present on line, or None if no
diagnostic touches it. “Most severe” = lowest enum tag
(Error == 1 < Warning == 2 < Information == 3 <
Hint == 4). Used by the gutter glyph provider; runs once
per visible line per frame, so this path stays
allocation-free (filters the borrowed slice in place).
Sourcepub fn inline_line_summary(
&self,
uri: &Uri,
line: u32,
min_rank: u8,
) -> Option<InlineDiagnosticSummary>
pub fn inline_line_summary( &self, uri: &Uri, line: u32, min_rank: u8, ) -> Option<InlineDiagnosticSummary>
L4a (lsp-architecture.md §15): a one-line end-of-line summary
of the qualifying diagnostics on line of uri, for the
inline cursor-line presentation. A diagnostic qualifies
when its severity rank is <= min_rank (as severe or more
severe than the configured floor); unknown-severity
diagnostics map to rank 4 and so only qualify when min_rank
is itself 4. Returns None when nothing on the line qualifies.
The text is the most-severe qualifying diagnostic’s message
(first line only, truncated to [INLINE_SUMMARY_MAX_CHARS] with
an ellipsis) plus +N when N further qualifying diagnostics
share the line. Most-severe = lowest rank; ties resolve to the
earliest by (line, character) (the merged list is already so
ordered). Wait-free: one snapshot load + a single pass over the
URI’s diagnostics, so it stays on the cheap side of the actor
thread’s publish path.
Sourcepub fn iter_uris(&self) -> Vec<Uri>
pub fn iter_uris(&self) -> Vec<Uri>
Every URI with at least one stored diagnostic. Sorted
alphabetically (stable for the :diagnostics buffer
view).
Sourcepub fn snapshot(&self) -> Vec<(Uri, Vec<Diagnostic>)>
pub fn snapshot(&self) -> Vec<(Uri, Vec<Diagnostic>)>
Snapshot of every (uri, merged-list) pair. Backs the
:diagnostics buffer’s body. URIs sorted; diagnostics
within a URI ordered by (line, column).
Sourcepub fn count(&self) -> usize
pub fn count(&self) -> usize
Total diagnostic count across every URI / server. Used by the modeline summary (“rust: 3 errors, 2 warnings”).
Sourcepub fn severity_counts(&self) -> SeverityCounts
pub fn severity_counts(&self) -> SeverityCounts
Severity tally across every URI: (errors, warnings, info, hints). Modeline / status segment consumer.
Sourcepub fn clear_uri(&self, uri: &Uri)
pub fn clear_uri(&self, uri: &Uri)
Drop every entry for a URI (across all servers). Used when a buffer closes – the diagnostics are no longer relevant since we won’t render them.
Sourcepub fn clear_server(&self, server_id: &Arc<str>)
pub fn clear_server(&self, server_id: &Arc<str>)
Drop every entry for one server – used when a server dies / is detached.
Trait Implementations§
Source§impl Clone for DiagnosticsLayer
impl Clone for DiagnosticsLayer
Source§fn clone(&self) -> DiagnosticsLayer
fn clone(&self) -> DiagnosticsLayer
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for DiagnosticsLayer
impl Debug for DiagnosticsLayer
Source§impl Default for DiagnosticsLayer
impl Default for DiagnosticsLayer
Source§fn default() -> DiagnosticsLayer
fn default() -> DiagnosticsLayer
Auto Trait Implementations§
impl !RefUnwindSafe for DiagnosticsLayer
impl !UnwindSafe for DiagnosticsLayer
impl Freeze for DiagnosticsLayer
impl Send for DiagnosticsLayer
impl Sync for DiagnosticsLayer
impl Unpin for DiagnosticsLayer
impl UnsafeUnpin for DiagnosticsLayer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more