mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-12 23:40:45 -07:00
The render tag wrote `self:` attributes directly into @scopes[0] under key 'self', which shadowed the SelfDrop. `self[var]` lookups inside the snippet then did strict key access on the bound object instead of walking the scope chain, resolving to nil for any key not in the object. SelfDrop now holds an optional `bound_self`; `[]` and `key?` consult it first via duck typing (matches lib/liquid/variable_lookup.rb), then fall through to the scope-chain walk on miss. Render#render_tag routes attribute key Expression::SELF to inner_context.self_drop.bound_self= instead of the generic scope write. Lookup order is bound-first; existing self: users' hits stay intact, previously-nil misses now resolve via fallthrough. PR #2060 introduced the SelfDrop and bare-bracket prohibition but had no coverage for the {% render 'snippet', self: obj %} interaction. Adds 8 tests including two-deep nested renders with leak detection and a composite chain combining renders, top-level self[var], and regular variables. Discovered while investigating SFR strict-parser migration parity diffs.