Repository navigation
Conversation
Angle::eql in the Zig reference compares via toDegrees(), so any container holding an Angle (Transform, Rotate, LineDirection, ConicGradient, FontStyle) sees Deg(180) and Turn(0.5) as equal. The Rust port derived PartialEq structurally, and the containers route CssEql through PartialEq via css_eql_partialeq!, so the rule merger stopped collapsing adjacent rules whose angle values differed only in unit. Replace the derived PartialEq with a manual impl that compares to_degrees(), matching the Zig semantics and restoring the cross-unit merge.
|
Warning Review limit reached
More reviews will be available in 3 minutes and 22 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
Walkthrough
ChangesAngle Semantic Equality and CSS Rule Merging
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
Updated 10:09 AM PT - Jun 15th, 2026
❌ @robobun, your commit f31c0ee has 2 failures in
🧪 To try this PR locally: bunx bun-pr 32307That installs a local version of the PR into your bun-32307 --bun |
|
This also covers the minify_test(".foo { font-style: oblique 15.5555556grad }", ".foo{font-style:oblique}");
minify_test("@font-face { font-style: oblique 15.5555556grad }", "@font-face{font-style:oblique}");
minify_test("@font-face { font-style: oblique 18deg 20grad }", "@font-face{font-style:oblique 18deg}");
prefix_test(
".foo { font-style: oblique; font-style: oblique 15.5555556grad; }",
indoc`.foo { font-style: oblique; }`,
{ firefox: 50 << 16 },
);Happy to push these onto this branch if useful. |
There was a problem hiding this comment.
LGTM — the CssHash divergence is now documented, thanks.
Extended reasoning...
Overview
This PR replaces #[derive(PartialEq)] on the Angle enum in src/css/values/angle.rs with a manual impl that compares via to_degrees(), so Deg(180) == Turn(0.5) == Grad(200). The inherent Angle::eql and CssEql for Angle now both forward to ==, giving a single source of truth. Seven minify_test cases are added in test/js/bun/css/css.test.ts covering rule-merging across transform/rotate/skew/gradient/font-style plus a negative case. A follow-up commit (2a22263) added a comment documenting that CssHash remains intentionally structural to match angle.zig.
Security risks
None. This is a pure value-equality change inside the CSS minifier; no auth, crypto, filesystem, network, or untrusted-input parsing surface is touched. Worst-case failure mode is suboptimal or over-merged CSS output, not a security issue.
Level of scrutiny
Low-to-moderate. The change is small (~15 lines of logic + comments + tests), restores documented parity with the Zig reference (angle.zig:200), and the previous CssEql impl already had exactly these semantics — this just propagates them to containers via derived PartialEq. The blast radius is confined to CSS minification quality, and the existing 1093 css tests reportedly continue to pass.
Other factors
- My prior review raised one minor nit (structural
CssHashvs semanticPartialEq); the author addressed it with the documenting comment I suggested, and the thread is resolved. - The bug-hunting system found no issues.
- The CI failures on the build bot are infrastructure-related (Windows agent creation failures, musl LTO data-layout linking) and unrelated to this diff; the latest commit only adds comments.
- No CODEOWNERS entry covers
src/css. Angledoes not implementEqorcore::hash::Hash, so no stdHash/Eqcontract is at risk.
There was a problem hiding this comment.
LGTM — the comment addressing the CssHash divergence resolves my earlier nit.
Extended reasoning...
Overview
This PR replaces the derived (structural) PartialEq on Angle in src/css/values/angle.rs with a manual impl that compares via to_degrees(), restoring parity with angle.zig. The inherent Angle::eql and CssEql impl now both forward to == so there is a single source of truth. Seven minify_test cases are added to test/js/bun/css/css.test.ts covering rule-merging across transform, rotate, linear-gradient, conic-gradient, and font-style: oblique, plus a negative case.
Security risks
None. This is a pure value-equality change in the CSS minifier. There is no parsing, I/O, auth, or memory-safety surface here; the only behavioral effect is that semantically-equal angles in different units now compare equal, enabling additional (correct) rule merging. Worst-case failure mode is suboptimal minification, not incorrect output.
Level of scrutiny
Low–medium. The diff is ~15 lines of Rust plus tests, mechanically aligns the Rust port with the Zig reference (angle.zig:200), and is well-covered by new tests that fail before / pass after. I verified there is no Eq impl on Angle (so no std Hash/Eq contract is at stake), and a grep for Angle::Variant(...) usages shows only pattern-matches and constructors — nothing that depended on the old structural ==.
Other factors
In my prior review I flagged that #[derive(CssHash)] remains structural while PartialEq/CssEql are now degree-based. The author addressed this in 2a22263 by adding a comment documenting that the divergence is intentional (matches angle.zig) and that no consumer keys a CssHash map on an Angle-containing value with CssEql as equality. That thread is resolved. The robobun comment suggesting additional font-style: oblique / @font-face test cases is non-blocking — the existing tests already exercise the fix adequately. CI was retriggered in f31c0ee; the code change itself is correct independent of any infra flakes.
|
All 280 test jobs that ran passed. The remaining red is the darwin test lanes ( |
|
Stale PR review: keep open, rework. The change is still wanted. Main still derives structural The diff cannot merge as posted because one hunk edits the inherent |
|
Closing as part of a cleanup of stale pull requests. This PR has had no new commits since 2026-06-15, it conflicts with main, and its last CI run failed. This is not a judgment on the fix itself. If the problem still reproduces on a current build, reopen this PR after a rebase or open a new one against main. |
Problem
Angle::eqlinangle.zigcompares viatoDegrees(), and Zig'scss.implementEqlrecursively calls.eql()on nested fields, so any container holding anAngle(Transform,Rotate,LineDirection,ConicGradient,FontStyle, ...) treatsDeg(180)andTurn(0.5)as equal.The Rust port kept that semantics in
impl CssEql for Angle, but the enum also#[derive(PartialEq)], which is structural (Deg(180.0) != Turn(0.5)). The containers use#[derive(PartialEq)]on themselves and thencss_eql_partialeq!(...)to bridgeCssEqlto==, so a nestedAngleis compared structurally. The rule merger / declaration deduper compares declaration values through these paths, so adjacent rules whose values contain semantically equal angles in different units stopped merging under--minify. Output is still correct CSS, just larger than the Zig build produced.Fix
Replace the derived
PartialEqonAnglewith a manual impl that comparesto_degrees(), matchingangle.zig:200. This propagates through every container's derivedPartialEq(and therefore theirCssEql) without touching any of them. The inherentAngle::eqland theCssEqlimpl now forward to==so there is a single source of truth.Tests
Added
minify_testcases intest/js/bun/css/css.test.tscoveringtransform(rotateZ, skew), therotateproperty,linear-gradientdirection,conic-gradientfrom-angle, andfont-style: oblique, plus a negative case (same unit, different value stays unmerged). All fail on the unfixed build and pass with this change; the existing 1093 css tests continue to pass.