Fix render-expr in eval position: wrap result in raw-html

The spec's eval-list calls render-expr for HTML tags/components in eval
position but returned a plain string. When that string was later passed
through _arender (e.g. as a component keyword arg), it got HTML-escaped.

Fix in eval.sx: wrap render-expr result in make-raw-html so the value
carries the raw-html type through any evaluator boundary. Also add
is_render_expr check in async_eval_ref.py as belt-and-suspenders for
the same issue in the async wrapper.

This fixes the streaming demo where suspense placeholder divs were
displayed as escaped text instead of real DOM elements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 18:58:42 +00:00
parent 309579aec7
commit 668a46bec0
3 changed files with 20 additions and 5 deletions

View File

@@ -172,9 +172,12 @@
(let ((mac (env-get env name)))
(make-thunk (expand-macro mac args env) env))
;; Render expression — delegate to active adapter
;; Render expression — delegate to active adapter.
;; Wrap in raw-html so the result keeps its type when
;; used as a value in eval position (e.g. bound to a
;; component keyword arg then rendered later).
(is-render-expr? expr)
(render-expr expr env)
(make-raw-html (render-expr expr env))
;; Fall through to function call
:else (eval-call head args env)))