Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:29:38.724Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

entity_update_in_render.rs

67 lines · 2.0 KB · rust
1use clippy_utils::diagnostics::span_lint;
2use rustc_hir::{Expr, ExprKind};
3use rustc_lint::{LateContext, LateLintPass};
4
5use crate::render_helpers::{
6    is_directly_in_render_method, is_gpui_entity_or_weak, is_unit_or_result_unit,
7};
8
9rustc_session::declare_lint! {
10    /// ### What it does
11    ///
12    /// Flags calls to `Entity::update` or `WeakEntity::update` that execute
13    /// synchronously inside a `Render::render` or `RenderOnce::render` method
14    /// and whose closure returns `()` (indicating mutation rather than reading).
15    ///
16    /// ### Why is this bad?
17    ///
18    /// The `render` method should be a pure function of state. Calling
19    /// `.update()` mutates an entity during the render pass, which can trigger
20    /// re-renders mid-render and lead to inconsistent UI state or infinite
21    /// render loops.
22    pub ENTITY_UPDATE_IN_RENDER,
23    Warn,
24    "mutating an entity via `.update()` during render"
25}
26
27pub(crate) struct EntityUpdateInRender;
28
29rustc_session::impl_lint_pass!(EntityUpdateInRender => [ENTITY_UPDATE_IN_RENDER]);
30
31impl<'tcx> LateLintPass<'tcx> for EntityUpdateInRender {
32    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
33        if expr.span.from_expansion() {
34            return;
35        }
36
37        let ExprKind::MethodCall(segment, receiver, _args, _span) = &expr.kind else {
38            return;
39        };
40
41        if segment.ident.name.as_str() != "update" {
42            return;
43        }
44
45        let receiver_ty = cx.typeck_results().expr_ty(receiver);
46        if !is_gpui_entity_or_weak(cx, receiver_ty) {
47            return;
48        }
49
50        let call_ty = cx.typeck_results().expr_ty(expr);
51        if !is_unit_or_result_unit(cx, call_ty) {
52            return;
53        }
54
55        if !is_directly_in_render_method(cx, expr.hir_id) {
56            return;
57        }
58
59        span_lint(
60            cx,
61            ENTITY_UPDATE_IN_RENDER,
62            expr.span,
63            "entity `.update()` called during render mutates state in the render pass",
64        );
65    }
66}
67
Served at tenant.openagents/omega Member data and write actions are omitted.