Fix no std with alloc - #226
Conversation
|
I patched this branch into my current project and it solves the build issue entirely. |
developer0hye
left a comment
There was a problem hiding this comment.
Validated commit f3fd1f5 locally on stable aarch64-apple-darwin. cargo check --no-default-features --features=alloc,grab_spare_slice,latest_stable_rust and cargo fmt --all -- --check both pass. The qualified alloc::vec! call directly fixes the 1.13.0 no_std + alloc regression, and the added workflow command covers the previously missing feature combination. This regression is currently blocking cold unlocked builds in downstream projects, including office2pdf.
|
Successfully used this to fix the cold installation of |
|
Sorry about all this trouble everyone, |
* Hold tinyvec at 1.12 until 1.13 builds again `tinyvec` 1.13.0, published on 2026-09-03, imports `alloc::vec` as a module and then invokes the `vec!` macro. On the nightly this repository pins the macro no longer resolves: ```text error: cannot find macro `vec` in this scope --> tinyvec-1.13.0/src/tinyvec.rs:710:21 note: `vec` is imported here, but it is a module, not a macro ``` The crate arrives transitively through Bevy's text and font stack, and this workspace commits no `Cargo.lock`, so every build resolves the newest compatible release and reaches the broken one. `make lint` and any `--all-features` build fail on untouched `main`; the failure reproduces on a clean detached checkout with an isolated target directory, so it is not a local artefact. Add a tilde requirement, which `AGENTS.md` permits for a documented lock to patch-level updates. It is a resolution constraint only: no code in this workspace names the crate, and the comment says so, so a later reader does not mistake it for a dependency that can simply be dropped. Upstream has not yanked 1.13.0. Lokathor/tinyvec#225 reports the same failure and Lokathor/tinyvec#226 proposes the fix. Removal is tracked by #340. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Catch a bad tinyvec resolution before the build does The constraint had no test, so the only thing standing between a future contributor and the broken release was a comment. Widen the requirement by accident and the symptom is a macro error inside a crate nothing in this workspace mentions. `tests/dependency_resolution.rs` reads what Cargo actually resolved and fails if `tinyvec` 1.13 or later is selected, naming the version and pointing at the requirement. It also fails if the crate leaves the graph entirely, which is the signal that the constraint and the test should both go. Record the constraint in the developers guide as well: what it is for, why a transitive dependency needs a direct requirement, why a tilde rather than a caret, and the condition for removing it. A bare version requirement with no explanation reads as a real dependency, and the next contributor cannot tell whether dropping it is safe. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Say what the resolution test can and cannot catch The guide called `tinyvec` "not a dependency", which is wrong: it is a direct Cargo dependency whose only purpose is to bound resolution. Say that instead, so a reader looking at `Cargo.toml` is not told the opposite of what is there. Both the guide and the test also implied the test runs before the build. It does not. Cargo compiles the dependency graph before an integration test runs, so a selected 1.13.0 fails the build first with the macro error. What the test catches directly is the case that would otherwise pass silently: a widened requirement whose resolved version still compiles but sits outside the range this workspace has verified. Both places now say that, and the guide points at `cargo tree --invert tinyvec` for the case where the build fails first. `ResolvedVersion` replaces the bare minor number. The old helper kept only the second component, so a resolved 2.0.0 read as minor 0 and passed a check meant to reject anything at or beyond 1.13, and the failure message printed `1.[13]` rather than the version Cargo chose. The type keeps the original text for the message and the major and minor pair for the comparison. Also reflow the guide paragraph to 80 columns and wrap the compiler error in double backticks so Rustdoc renders it as one code span. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY
…#382) Version 1.13.0 failed to compile for any no_std consumer. Commit 9f25466 added a bounded range to hold the transitive resolution at 1.12.0, as an explicitly temporary measure. Lokathor/tinyvec#226 merged on 2026-09-04 and closed issue #225. Version 1.13.1 published two minutes later, and 1.13.2 followed. The call in src/tinyvec.rs is now qualified as alloc::vec![...]. The constraint is removed outright, not relaxed to a floor. A floor would keep a permanent phantom direct dependency on a crate this project never uses. It buys nothing over cargo's max-version selection, since 1.13.0 is unreachable once the upper bound is gone. Verified from a regenerated lockfile rather than from the manifest edit: a fresh resolution selects tinyvec 1.13.2, reached only through sqlx -> sqlx-postgres -> stringprep -> unicode-normalization. Fixes: #377
#383) * fix: 🐛 static-modifier order, comment-blind shadowing, @props default values Three follow-ups on the component-member navigation code (#351, plus item 8 from #339 since it lives in the same function): - public_property_types kept one flag for two modifiers, so 'static public string $x' slipped through — the static_modifier child is visited first and the visibility_modifier reset the flag. Separate public/is_static flags now, exactly as public_action_method_names already keeps them; the test pins BOTH modifier orders. - is_template_local_binding scans a comment-blanked copy of the template: Blade ({{-- --}}) and HTML (<!-- -->) comments never execute, so a commented-out @foreach no longer shadows its loop variable for the rest of the file, and '<!-- @php -->' no longer opens a phantom block that turns every later assignment-looking line into a local. Blanked (newlines kept) rather than stripped, so line numbers stay stable. Directives in ordinary prose still bind — Blade genuinely compiles those; escaping them is what @@ is for. - @props/@AWare capture only KEYS and bare entries: a quoted string right after => is a prop's default VALUE (['size' => 'md'] declares $size, never $md) and binds nothing. * fix: 🐛 Require a comment terminator, and reuse the shared comment scanner. Change-request items 3, 4 and 5 on #352. blank_template_comments no longer hand-rolls a fourth comment scanner. It blanks the spans blade_directive_tokens::blade_comment_spans returns, which also settles the unterminated-opener rule: that scanner's regex requires the closer, and so does Blade. CompilesComments::compileComments is a single preg_replace with /{{--(.*?)--}}/s, which returns the input unchanged when --}} is absent, and Blade never handles <!-- at all. Blanking to end of input was a regression wider than the bug it fixed: one stray <!-- in a <script> unbound every directive below it. The doc comment said the opposite and is corrected. Three tests passed against pre-fix code and could not detect a regression: multiline_blade_comment_blanks_its_whole_body now asserts inside the comment body, between the push and the pop; html_comment_does_not_open_a_php_block asserts on the assignment-shaped line past the scan's break condition; and uncommented_directives_still_bind_next_to_commented_ones gives the two loops different variable names. A new test pins the terminator rule itself. The .expect on String::from_utf8 becomes a fail-soft unwrap_or_else, matching blade_var_rename::mask_non_code. * refactor: ♻️ Consolidate the crate's comment maskers onto one dead-region scanner. Issue #369 Part A, items A1 and A5. The crate carried four implementations of "which regions does Blade not execute", disagreeing on two axes: whether <!-- --> and @verbatim count as dead, and what an unterminated opener does. blade_directive_tokens now owns the only one. dead_region_spans covers Blade comments, HTML comments and @verbatim bodies; blank_dead_regions blanks them preserving length and newlines. blade_var_rename::mask_delimited and livewire_resolver::blank_template_comments are deleted, and mask_non_code is a one-line delegation kept for the rename module's own vocabulary. The unterminated-opener rule is settled once, the way Blade settles it: a missing terminator yields no span. CompilesComments::compileComments is a single preg_replace with /{{--(.*?)--}}/s, which returns the input unchanged without the closer, and Blade never handles <!-- at all. @verbatim follows the same rule so the three cannot drift apart again. Two behaviour changes fall out, both previously invisible to the suite and both now pinned: blade_var_rename treats <!-- --> as dead, which its two siblings already did, and it no longer masks an unterminated opener to end of file, which used to make every variable below one stray <!-- un-renameable. A1 arrives as a consequence: is_template_local_binding now runs over a template with @verbatim bodies blanked, so a @foreach there no longer shadows its loop variable. The @verbatim span is its BODY, captured in group 1, not the whole match — @verbatim and @endverbatim are themselves compiled directives and must still tokenise for semantic highlighting. * build: 📌 Pin tinyvec below 1.13 until the upstream no_std fix ships. tinyvec 1.13.0, published today, does not compile for any consumer that leaves its `std` feature off. The new `with_initial_len` calls `vec![]`, but the crate is `no_std` and imports `alloc::vec` as a module, so the macro is not in scope. Reported as Lokathor/tinyvec#225 with a fix open in #226; the release is not yanked, so cargo still selects it. It reaches us four levels down and is not a dependency we chose: sqlx -> sqlx-postgres -> stringprep -> unicode-normalization -> tinyvec. Cargo.lock is deliberately gitignored, so CI re-resolves every build and took the broken release within hours of publication, on all three runners. A bounded range in the manifest is the pin that survives that; a caret range is not, and neither is a bare upper bound — see the comment. Temporary. Remove when #226 releases. * fix: 🐛 Honour Blade's @@ escape — an escaped directive executes nothing. The crate had no handling for @@ anywhere. grep -rn '@@' src/ found only a comment in livewire_resolver that cited @@ as the reason prose directives are honoured, while the code ignored it. Blade's rule, from BladeCompiler: compileStatements matches /\B@(@?\w+(?:::\w+)?)([ \t]*)(\( [\S\s]*? \))?/x and compileStatement opens with `if (str_contains($match[1], '@'))`, replacing the match with its own text instead of compiling it. So the test is whether the preceding byte is another @. A run of three or more behaves identically — \B makes the match start at the second @, group 1 carries the leading @, and it is emitted literally — so there is no parity rule. is_escaped_directive lands beside the shared dead-region scanner and is applied at the four sites that scan for directives: semantic tokens, @verbatim region detection, template-local binding, and @use alias extraction. Each was verified wrong before and right after by running it. Not fixed here: blade_var_rename::in_scope_spans still treats an escaped loop header as live. Its scanner is in blade_loops, and whether an escaped loop scopes its variable for RENAME is a separate question from whether it binds. Filed rather than guessed. * fix: 🐛 An escaped @@foreach opens no loop block, and @@Endforeach closes none. Completes the @@ escape handling from the previous commit. blade_loops scans directive text at three sites and none of them knew about escaping: * LOOP_HEAD_RE in find_loop_blocks — @@foreach opened a block, so text below literal documentation was treated as loop scoped. * LOOP_END_RE in find_loop_blocks — @@Endforeach closed a live block, so a real loop ended at the literal text and its body fell out of scope. This is the dangerous direction. * LOOP_HEAD_RE in unbalanced_loop_head_lines — an escaped head with an unclosed paren was reported unbalanced, and in_scope_spans refuses a rename outright inside an unresolved region, so literal text could disable rename for the whole file. All three consult blade_directive_tokens::is_escaped_directive rather than re-deriving the rule. Verified against the real compiler rather than by reading it: running BladeCompiler::compileString from test-project/vendor gives "@@foreach ($rows as $row)" -> "@foreach($rows as $row)" (literal), "@@Endforeach" -> "@Endforeach", and "@@verbatim $x @endverbatim" -> "@verbatim $x @endverbatim". The same escape is what makes Alpine bindings work on names that collide with real directives: "<div @Class=\"a\">" compiles to broken markup, "<div @@Class=\"a\">" renders "<div @Class=\"a\">". Not changed: a $var inside an escaped header is still a rename site. That is a question about editing literal display text, not about scoping. * build: ⬆️ Take tree-sitter 0.27, drop the tinyvec pin, and guard the Blade grammar. tree-sitter 0.27 carries two breaking changes that both reach this crate. QueryMatch::captures became a private field behind a captures() accessor, which broke five sites in queries.rs. Node::child_count() also changed from usize to u32 while named_child_count() stayed usize, making the `as u32` cast at the child() call redundant, which clippy rejects under -D warnings. CI never reported that cast, because compilation aborted at the private-field errors first. Verified against the vendored crate that the two counts really did diverge (binding_rust/lib.rs:1836 and :1857), so the named_child_count() casts in salsa_impl.rs and vendor_translations.rs stay as they are. The tinyvec constraint goes with it. Main removed the pin in f4ace8c (#382) once Lokathor/tinyvec#226 merged and 1.13.1 shipped the no_std fix. This branch reached the same pin through its own commit 9f25466, which is not an ancestor of main, so the merge base held no pin and e15b3b2 kept this branch's addition over main's removal, with nothing flagged as a conflict. A fresh resolution of all 290 packages selects tinyvec 1.13.2 through sqlx -> sqlx-postgres -> stringprep -> unicode-normalization, matching main. Removed outright rather than floored: a floor would keep a permanent phantom direct dependency on a crate this project never uses. The new tests guard a risk the upgrade makes sharper. build.rs fetches tree-sitter-blade from main, not a tag, because upstream's newest release (v0.12.3, 2025-08-25) sits 21 commits behind. Tracking main stays the right call while upstream is not cutting releases, but it lets an upstream regression arrive with no local change to explain it. Four unreleased upstream changes were measured against our own extractors by swapping the cached grammar. Two are observable and are covered: - An escaped @@directive inside an HTML attribute value (upstream #129). On v0.12.3 it yields a phantom view reference to a template the page never includes. At top level both grammars already yield nothing, so the test pins the one context where they differ. - Conditional attributes (upstream #130), on two surfaces: the reported arguments, which v0.12.3 truncates mid-identifier, and the embedded PHP region, which v0.12.3 omits entirely, leaving the member inside a conditional attribute invisible to hover and go-to-definition. Two are not covered. Scoped slots (upstream #133) gave identical output across sixteen shapes, because our query matches the tag name and that is unchanged. The parser.c regeneration makes no behavioural claim. No test was written to fill either slot. Each test drives a public extraction surface and asserts our own behaviour; none asserts a node kind or a parse-tree shape. All three pass on main and fail on v0.12.3, so an upstream regression reddens the suite. --------- Co-authored-by: Marlon Arno Basten <marlon-arno.basten@haendlerbund.de>
Resolves #225.
It looks like the functionality added in #224 accidentally calls the bare vec! macro.
This was not caught in tests, because no test configuration ran with alloc but without std.
This just changes it to match invocations elsewhere, plus adds test coverage.