decision tree codegen and projection abstraction#1174
decision tree codegen and projection abstraction#1174sbillig merged 27 commits intoargotorg:masterfrom
Conversation
cf916d4 to
6a4d0b6
Compare
- Apply LoadableScalar conversions (masking, sign-ext) for PlaceLoad - Add defensive fallbacks for empty/missing field type info - Fix merge_block return consistency for terminating arms - Remove debug prints, add proper error handling for missing body - Include variant index in hash_place for dedup safety
- Convert defensive fallbacks in lower_place_address to hard YulError failures for any field_types query returning empty or out-of-bounds - Error on target field access when field doesn't exist in type info - Include enum_ty in hash_place via pretty_print to preserve type system semantics during MIR function deduplication - Improve comment for Absent patterns explaining the design decision
6a4d0b6 to
0b712b4
Compare
- Add generic Projection/ProjectionPath types with Infallible for HIR index slots - Refactor match lowering to use Place with projections (defer offsets to codegen) - Extract shared layout module eliminating duplicate ty_size_bytes implementations - Inline field loads in codegen, removing helper function indirection
Trust decision tree's default block rather than rediscovering wildcard arms. This fixes Outer::First(_) patterns being incorrectly routed to top-level wildcards.
c2fe225 to
b6f6763
Compare
|
@micahscopes What's the status on this? Reviewable? I'm wrapping up the contract lowering, and would like to rebase on this if you don't anticipate big changes. |
|
@sbillig no big changes planned on my end |
Code reviewFound 1 issue:
fe/crates/codegen/src/yul/emitter/control_flow.rs Lines 401 to 407 in b6f6763 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
|
More input from Claude: When computing the byte offset of a field in a struct/tuple, there are two approaches in the codebase:
Why this matters: Consider a struct { a: MyEnum, b: u8 } where MyEnum has unknown size:
These happen to match here. But for { a: u8, b: MyEnum, c: u16 }:
|
|
@sbillig those are good catches, thank you Both should be fixed now. I also found one more area of duplicated logic in this API stub I'd added and tightened it up. I also added comments about the stubs, feel free to keep / delete them in your followup stuff. |
This PR introduces a projection abstraction for navigating into data structures. Field access and pattern matching now work via semantic paths rather than scattered offset calculations.
What changed
The projection system flows through the whole pipeline:
Projection<Ty, Var, Idx>vocabulary used by the decision treePlace { base, projection }for both field access and match loweringlower_place_address) to emit pointer arithmeticThis replaces the old approach of calling
GetField/GetVariantFieldhelpers everywhere, which made it hard to reason about layout correctness.Changes / To-do
hir/src/projection.rs) withProjection<Ty, Var, Idx>Idx = Infallibleso pattern matching can't construct dynamic indexingPlace { base, projection, address_space }withPlaceLoad/PlaceRefPlaceabstractionlower_place_address)let tmp := 0for nested switches)match_nested_enum.fe)field_offset_bytes/variant_field_offset_bytesunwrap_or(32)in codegenFuture directions
Near-term
storage_size_bytes/field_storage_size_bytesin layout APIunwrap_or(32)Medium-term
Index/Derefprojection variants (for arrays, references)may_alias()on projection paths, needed for SROA, escape analysisEditable/EditablePathtraits (stubbed out, not yet implemented)FieldAccessView::as_projection()Long-term
AddressSpaceKindfromPlace, add explicitAlloca