Skip to content

[rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] [rustjava-adopt-classfile-error-cause-decision-p0-fix2] [rustjava-adopt-classfile-error-cause-decision-p0-conflict-resolve] - #67

Merged
Jun025 merged 5 commits into
mainfrom
feat/rustjava-classfile-error-cause
Sep 18, 2026

Conversation

@Jun025

@Jun025 Jun025 commented Sep 17, 2026

Copy link
Copy Markdown
Owner

채택 제안 2026-09-17-classfile-error-cause-decision#p0. 제품 동작 변경 있음
ClassFormatError 메시지가 모든 거부에 같던 「Invalid class file」 에서 사유별 문장이 된다.

제안이 스스로 all-or-nothing 이라 못박았다(타입만 고치면 관측되는 것이 없고, || 사슬을 안 쪼개면
평평함이 사라지는 게 아니라 옮겨갈 뿐). 넷 다 했다:

ClassFileError::InvalidFormat(&'static str)
 → ClassDefinitionError::InvalidClassFile(&'static str)   ← From 이 «버리던» 자리
    → jvm.exception("java/lang/ClassFormatError", cause)  ← 두 자리 모두

validate_class8항 || 사슬 → 규칙마다 if 하나(사유 13개).

사유를 꿰자마자 «평평한 오류가 가리던 것 둘»이 나왔다

  1. 테스트가 어느 층이 거부하는지를 틀리게 믿었다 — 「인덱스가 엉뚱한 종류를 가리킨다」는
    검증이 아니라 파서가 거부한다. ★코드를 추측에 맞추지 않고 단언을 실측에 맞췄다.
  2. 술어 이름이 낡아 있었다..._are_in_the_pool 은 이름과 달리 「적재 가능 상수인가」까지 본다
    (직전 회차가 넓혔다). 사유는 규칙대로 적고 ★이름은 바꾸지 않았다(리팩터 = 범위 밖).

양방향 — 세 층 전부에 개악

M1 경계가 다시 문자열을 박는다 → red · M2 From 이 사유를 버린다(제안이 지목한 그 버그) → red ·
M3 두 사유를 한 문자열로 접는다 → red(dedup 단언이 잡는다 — 이게 없으면 전부 되돌려도 통과) ·
복원 17/0.

대가 (실측한 구멍 포함)

cargo test --all 578 → 579 / 0 failed / 1 ignored · DoD 7명령 rc=0.

jun0 added 2 commits September 18, 2026 00:21
… 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다
…한 dedup 단언을 걷어내고 귀속을 사실로 되돌린다

F1(major) — 비공허성의 근거로 내세운 dedup 단언이 «상수 대 상수»였다. `seen` 이 담던 것은 제품의
출력이 아니라 표의 «기대 리터럴»이라 제품이 무엇을 내든 결과가 같았다. 처방은 ⒝(걷어내고 사실대로
적기)를 골랐다 — 측정이 그것을 가리킨다: 두 사유를 한 문자열로 접으면 터지는 곳은 줄마다의
`assert!(err.contains(cause))` 이고 루프 끝에 도달조차 하지 않으며, 개악을 유지한 채 `contains` 만
무력화하면 시험이 «통과»한다(= dedup 이 잡는 것은 0). 귀속 문장은 ★여섯 곳을 고쳤다(검수 지적은
네 곳이었으나 worklog .md 의 표·한계 절에 둘이 더 있었다).

F2(minor) — 「사유 13개(메서드 2)」 → 직접 센 **14개(클래스 8 · 필드 3 · 메서드 3)**. 네 곳.
F3(minor) — 「DoD 7명령 rc=0」은 CLAUDE.md §DoD 가 금지한 «직접 센 수»다 ⇒ 검사기 출력 인용으로 교체.
F4(minor) — 이 PR 이 거짓으로 만든 현재형 주석 2곳(`make_cp_fixtures.py` · `test_class_format.rs`)을 과거형으로.

제품 동작 추가 변경 0 · 새 시험·픽스처 0 · `validate_class` 항 추가/삭제 0.
`cargo test --all` 579/0/1 · check-dod-ci-parity OK(명령 6 · toolchain 2 대칭차 0).
@Jun025 Jun025 changed the title [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] Sep 17, 2026
…이 덮는다」 잔존 3곳을 닫고 포인터를 :450 으로 고친다

R1(major) — dedup 블록은 f1c1a1d 에서 제거됐는데 그것이 «존재하며 무언가를 덮는다»고 말하는 문장이
셋 남았다: worklog issues[1](★기계가 읽는 자리) · REPORT.md:11 ⒝ · worklog .md:46.
셋 다 HEAD 에서 거짓이고, 같은 파일의 다른 줄(REPORT :10 · worklog .md:53)이 「걷어냈다」고 적어
자기모순이었다. 셋 다 과거형 교정으로 닫았다.

★직전 회차의 전수 검색이 왜 놓쳤나: 패턴이 «잡는다»라는 «동사»에 묶여 있었고 잔존 셋은 전부 다른
동사였다(covers · 덮는다 · 단언한다). 이번엔 검수자 처방대로 «주어»로 훑었다(dedup · 서로 다름 ·
seen · distinct) — 잔존 6건 전부 「걷어냈다」 문맥임을 확인했다.

권고분 — `:452` 포인터 4곳을 `:450` 으로. HEAD 의 :452 는 `}` 라 허공을 가리켰다.
줄번호는 베끼지 않고 직접 셌다(grep -n 'err.contains(cause)' → 450).

양방향 재확인(내 측정): 정상 green 17/0 · 제품이 두 사유를 접음 → red at :450 ·
개악 유지한 채 contains 무력화 → green(= contains 가 유일한 포수).
접촉 4파일 전부 문서 — `.rs` 무접촉(제품 동작 추가 변경 0) · cargo test --all 579/0/1.
@Jun025 Jun025 changed the title [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] [rustjava-adopt-classfile-error-cause-decision-p0-fix2] Sep 17, 2026
Jun025 pushed a commit that referenced this pull request Sep 18, 2026
… 카드를 실측에 맞추고 「전부 겹친다」를 두 축으로 가른다

게이트② 반려 3건. 세 지적이 «한 뿌리»에서 나왔다 — 「겹침이 전부다」로 읽고 그 위에 S 를 얹었다.
코드 0행(이 회차는 대전제 ⓒ 로 «멈춘» 회차다 — 구현은 그 카드가 진다).

⑶ verification[1] 을 두 축으로 갈랐다: 편집 영역은 «전부» 겹치지만(target 두 파일을 #67 이 정확히
고친다) 전달된 값은 «3 중 1» 이다(기대만 · 인덱스·실제는 &'static str 이라 구조적으로 불가).
대전제 ⓒ 가 묻는 것은 후자이므로 「전부」는 축을 갈아탄 말이었다.

⑴ 카드를 실측에 맞췄다. 두 선택지를 각각 재서 골랐다:
  ⒝ 페이로드를 넓힌다 → 생성 17곳(validation 14 + class 3) + 값 매치 11곳 전건
  ⒜ 새 variant      → 생성 1곳 · 값 매치 0곳 강제
⒜ 를 고르되 effort 는 S → M 으로 올렸다. 크기를 정하는 것은 편집 수가 아니라 «건너는 층»이고,
잔여도 #67 과 같은 3층을 건넌다(중간층 jvm-bytecode 도 &'static str · 경계 exception(&str) 이라
runtime.rs·test-utils 에서 포맷해야 한다) ⇒ target 5파일 / 3크레이트를 전부 적었다.
★원 제안이 «전체»를 M 으로 값했는데 «미전달된 절반»을 S 로 값하면 순서가 뒤집힌다.
⒜ 의 대가도 카드에 적었다 — 거부 오류가 두 갈래가 되고 이후 규칙마다 어느 쪽인지 답해야 한다.

⑵ 「네 크레이트」의 «명사»를 고쳤다(수 13·8·7·5 는 맞으니 무접촉). Cargo.toml 로 확인하니
classfile 3 + jvm-bytecode 1 = 파일 4 / 크레이트 2 이고, 루트 2건은 주석이다. 5곳 전부 고쳤다.

cargo test --all 583/0/1(base 8c7b473, 불변) · adoptedProposals 원 ref 유지 · #67 무접촉.
…— 코드 2파일을 «각자 한 일»로 합친다

게이트③ 계약 2-c⒝ 로 머지 회차가 풀 수 없던 충돌 4파일(원장 2 + 코드 2)을 해소한다.
base 뒤처짐 25 · 승인(pin acada3c)의 내용은 무접촉.

★충돌의 정체: 두 쪽이 «같은 함수에 각자 다른 일»을 했다.
· ours(#67) = validate_class 의 8항 || 사슬을 «규칙마다 if» 로 쪼개 사유를 달았다(호출부 재구성)
· theirs(#66, 착지) = 마지막 항의 술어 자체를 «일반화»했다
  (at_most_one_bootstrap_methods_attribute → at_most_one_of_each_single_class_attribute,
   BootstrapMethods 는 그 판별자 3번으로 «포함»된다)
⇒ 한쪽을 취하면 다른 쪽이 죽는다. ours 의 구조를 취하되 마지막 항을 theirs 의 일반화 술어로 바꿨다.
★사유 문면도 규칙에 맞췄다(「multiple BootstrapMethods attributes」 → 「a single-valued class
attribute appears more than once」) — 이 PR 자신의 교리 그대로다: 「규칙이 넓어지면 이름이 아니라
사유가 문면을 맞춘다」. 그 결과 ours 의 시험 단정도 같은 문면으로 따라갔다.

★tests/test_class_format.rs 는 theirs 판본에 ours 의 세 hunk(주석 2 + 새 시험 1)를 얹었다.
ours 의 새 시험이 원래 붙어 있던 앵커를 theirs 가 지웠기 때문에 git 이 꼬리를 접었다.
함수 22개 = base 16 − theirs 제거 2 + theirs 추가 7 + ours 추가 1.

★삭제줄은 «부모별로» 판정했다(일괄 계약 금지):
· theirs 에 있었는데 결과에 없는 것 = 두 파일 모두 «0»
· ours 쪽 3건은 전부 «의도»다 — at_most_one_bootstrap_methods_attribute 는 theirs 가 일반화해
  흡수했고, 지워진 시험 2개는 #61 회차가 «LambdaMetafactory 는 링크되지 않는다» 단언이 거짓이 되어
  일부러 없앤 것으로 이미 main 에 반영돼 있다.

원장 2파일은 양쪽 다 남기기(합집합) · 기여 불변 --numstat 양방향 정확 일치.
cargo test --all 584/0/1(해소 전 main 583 + 이 PR 의 새 시험 1) · 양측 핵심 시험 전건 ok.
@Jun025 Jun025 changed the title [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] [rustjava-adopt-classfile-error-cause-decision-p0-fix2] [rustjava-adopt-classfile-error-cause-decision-p0] fix(classfile): 거부 사유를 세 층에 꿴다 — validate_class 를 규칙마다 쪼갠다 [rustjava-adopt-classfile-error-cause-decision-p0-fix] [rustjava-adopt-classfile-error-cause-decision-p0-fix2] [rustjava-adopt-classfile-error-cause-decision-p0-conflict-resolve] Sep 18, 2026
Jun025 pushed a commit that referenced this pull request Sep 18, 2026
… test(ci): 필터를 넓히고 면제 예시를 «작동하는» 형식으로 고친다

게이트② 반려 2건. 제품 코드 0행.

① 필터가 좁아 «둘째 사고»를 삼켰다. 초판은 theirs 가 건드린 파일만 봤고 그 근거로 「only files the
merged-in branch actually changed can have lost its work」라 적었는데, 이 repo 자신의 둘째 사고가
그 문장을 반증한다 — 514d5b0e53b214 와 같은 넷을 떨어뜨렸는데 초판은 「0 file(s) examined」
rc=0 으로 통과시켰다. 해소가 «상대가 건드리지도 않은» 파일을 되돌리는 것이야말로 이 검사기의 존재
이유인데 그것을 못 봤다.
⇒ 술어를 「theirs 가 바꾼 파일 ∪ 머지가 바꾼 파일」로 넓혔다. 이제 두 사고 둘 다 rc=1 · 6정의다.
★좁힌 채 두지 않은 이유: 좁은 필터를 정당화하던 문장이 거짓이므로 그대로 두면 「없는 보장을 있다고
적는」 형태가 된다 — 이 리니지가 #67 의 F1 에서 정확히 그것으로 반려됐다.
대가는 숨기지 않았다: 83머지 소급 8건/19정의 → 10건/45정의(게이트② 실측 · 다시 재지 않았다).
늘어난 것에 진짜 사고 1건이 들어 있지만 읽을 것과 trailer 도 는다. Scope 문단에 그대로 적었다.

② docstring 의 유일한 작동 예시가 작동하지 않았다. `Pool.fieldref` 라 적혀 있는데 검사기는
`method fieldref` 를 내보내고 «글자 그대로» 대조한다 ⇒ 예시대로 적은 사람은 면제에 실패한다.
합성 머지로 양방향 확인했다: 출력에서 복사한 이름은 rc=0, 예쁜 형식은 rc=1.
예시를 출력 형식으로 고치고 ★「이름은 검사기 출력에서 글자 그대로 복사해야 한다」를 계약에 박았다
— 예시만 고치면 다음 형식이 또 갈린다. 전 이력 1,286커밋에 trailer 0건이라 깨진 기존 등재는 없다.

재확인: 스쿼시(부모 1개) rc=0 · 정상 머지 rc=0 · 이 PR 범위 rc=0 · DoD 문서축 전건 rc=0.
…erge origin/main — 원장 2파일 합집합(PR #69 착지분과 같은 자리)
@Jun025
Jun025 merged commit f19acf7 into main Sep 18, 2026
10 checks passed
@Jun025
Jun025 deleted the feat/rustjava-classfile-error-cause branch September 18, 2026 04:31
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.

1 participant