Skip to content

test: characterize structs and methods - #104

Open
shayyz-code wants to merge 3 commits into
mainfrom
test/87-characterize-structs
Open

shayyz-code wants to merge 3 commits into
mainfrom
test/87-characterize-structs

Conversation

@shayyz-code

@shayyz-code shayyz-code commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds 21 conformance cases under tests/conformance/structs/ that record how v0.1.11 handles structs and methods, so the upcoming refactor changes them on purpose. The cases cover declarations with typed fields, pub, construction with Name::{...}, field access, construction errors, impl { } and impl Target { } methods, self, Self return types, and inherits. No interpreter or harness changes.

Current behaviour (blessed, 12 cases): field_access, pub_modifier_not_enforced, field_type_mismatch, missing_field, undefined_struct, unknown_field_access, method_reads_self, method_with_argument, impl_target_block, method_returns_self_type, static_method_call_rejected, inherits_parent_method.

Known failures (9 cases, hand-written intended output plus .ignore):

Case Issue Today
unknown_field_rejected #64 Point::{x, y, z} is accepted silently
struct_typed_field #64 a Point value for a Point field is rejected (expected Map({...}) but got Map({}))
vec_typed_field #63 parse error Unexpected token: TInt. The case returns the vector instead of indexing it, because indexing after a field access is a separate defect (#107)
field_assignment #106 c.count = 2; on a mut binding fails with Unexpected token: Assignment, expected: SemiColon; there is no field assignment syntax yet
method_returns_int_field #50 self.x is typed String, so >> int fails with "Return type mismatch"
method_result_binding #50 poo n <: p.get_name(); fails with "Undefined method 'get_name' for object of type Map(...)" (inference panic caught by the hook)
method_mutates_self #65 self.count = 0; does not parse at all (Unexpected token: Assignment, see #106), so the case fails before the lost-mutation bug can show
inherits_parent_without_impl #57 Runtime error: called Option::unwrap() on a None value (exit 1, because the panic hook turns the panic into an error)
print_struct #69 prints Rust Debug of the backing map, e.g. {"x": Int(1), "y": Int(2), "__prototypes__": Map({})}, in a different key order from run to run. With methods, it also dumps the method AST. It does not panic as #69 says

Not included: override resolution (#56). A child overriding a parent method returned the child's result in 20 of 60 runs and the parent's in the other 40. A case expecting the child to win would pass about one run in three, and the harness fails the run when an ignored case passes, so it would make CI flaky. #56 stays without a corpus case until the lookup is deterministic.

Recorded as they are now, decision still open:

  • pub_modifier_not_enforced: pub is parsed, but fields without pub can still be read from outside the struct.
  • missing_field: a missing field is rejected with the confusing message Mismatched key 'y' on struct compound - 'Point'.
  • unknown_field_access: reading an unknown field says Value for key z does not exist in the map, which talks about a map, not a struct.
  • static_method_call_rejected: Point::origin() fails with Expected struct compound after namespace access. Methods can only be called on an instance, so a >> Self constructor can't be called without one.

Defects found while writing these cases: #106 (struct field assignment does not parse), #107 (indexing after a field access), and #109 (impl Other { } naming a struct that doesn't exist is accepted, and its methods attach to the enclosing struct; no case here).

Also seen: type-mismatch messages for struct-typed fields print the expected Map({...}) in random key order, so .error files must not include that part.

Issue

Closes #87

Verification

  • BLESS=1 POO_CASE=structs/ cargo test --test conformance, then checked every blessed .stdout and .error by hand.
  • First commit: ran cargo test --test conformance 5 times, each conformance: 17 passed, 9 known failures, 0 failed; POO_CASE=structs/ 20 more times, each 13 passed, 8 known failures, 0 failed (21 matched).
  • After the review commits: ran cargo test --test conformance 3 times on the branch tip, each conformance: 16 passed, 10 known failures, 0 failed (structs: 12 passed, 9 known failures, 21 matched). The middle commit alone gives 17 passed, 9 known failures, 0 failed.
  • Before writing the cases, ran each candidate program 30 times with the poo binary. Every recorded output was the same on all 30 runs.
  • just check passes on the branch tip.
  • Each commit is a self-contained Conventional Commit and passes just check

Documentation and Visual Impact

None. The only changes are test files under tests/conformance/structs/.

🤖 Generated with Claude Code

shayyz-code and others added 3 commits October 14, 2026 12:41
Pin down v0.1.11 behaviour of struct declarations, construction, field
access, impl blocks, self, Self and inheritance in the conformance
corpus. Cases for known defects (#50, #57, #63, #64, #65, #69) carry an
.ignore file with the intended output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Indexing after a field access is tracked separately (#107), so the case
now returns the vector instead and only depends on #63.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Field assignment on a mut binding should update the field (#106), so
the case is now a known failure with the intended output instead of a
blessed parse error. The self-mutation case notes the same dependency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: characterize structs and methods

1 participant