NEPLg2 abstraction static verification plan
作成日: 2026-05-12
関連 issue:
- ISS-20260512T143721313Z-GENERIC-AND-TRAIT-ABSTRACTION-MODEL--1F2FF429
- ISS-20260520T052151589Z-TYPE-ASCRIPTION-DOES-NOT-CONSISTENTL-BFF974A9
- NEPLg2 型注釈 expected-check 設計計画
- 静的検査の複雑化解消計画
目的
NEPLg2 の抽象化機能、特に generics、trait、trait bound、overload、monomorphize は、型安全とメモリ安全の入口である。抽象化機能だけを「便利機能」として扱い、文字列 key や optional field で通すと、Resource IR や effect / owner 検査が後段で正確な根拠を失う。
この文書は、抽象化機能にも次の開発方針を適用するための再設計計画である。
- 技術的負債を残さない。
- 後方互換のために不適切な設計を残さない。
- 暫定実装は許容しても、暫定の雑設計は禁止する。
- 静的検査の正確性を必須とする。
- 数値や文字列ではなく enum / typed struct で管理し、
matchの網羅性検査を効かせる。
現状評価
良い点
nepl-core/src/typecheck/はtraits.rs、trait_check.rs、trait_bound_apply.rs、trait_call_apply.rs、overload_selection.rs、selected_call_apply.rsなどに分割済みで、巨大typecheck.rsへ戻ってはいない。TraitCapabilityはCopy/Clone/Dropの enum であり、capability 判定は数値 tag ではない。monomorphizepublic API は unresolved trait call を panic せずMonomorphizeResultで返す。tests/compiler/generics.n.md、tests/compiler/overload.n.md、tests/compiler/generic_impl_trait_args.n.md、tests/compiler/trait_capability_copy.n.md、tutorials/getting_started/18_generics.n.md、19_traits_and_bounds.n.mdが抽象化機能の利用例と regression を持つ。
対応状況
2026-05-13 時点で、当初の不足点は Stage 1-6 の作業で解消済みである。
- trait application identity は typed model に移行済みである。
- parse_trait_ref_name と TraitBoundRef.name は削除済みであり、表示文字列を authority として trait argument を復元しない。
- typecheck は TraitApplication { trait_id: TraitId, args }、HIR は HirTraitApplication、Resource IR は ResourceTraitApplication、monomorphize は MonoTraitApplication を保持する。
- format_trait_ref_name は traits.rs の diagnostic/display helper としてだけ残し、impl lowering / monomorphize lookup / Resource IR の判断材料には使わない。
- impl model は
ImplKindenum に移行済みである。
- ImplInfo は kind: ImplKind を持ち、trait impl identity は ImplKind::Trait { application, self_ty } に集約した。
- trait_name: Option<String> や trait_base_name: Option<String> のような optional field combination は再導入禁止にした。
- type parameter bound identity は
BoundEnvとTypeParamIdに移行済みである。
- 公開境界の raw BTreeMap<TypeId, Vec<TraitBound>> と label fallback は削除済みである。
- BoundEnv 内部 key も TypeParamId になり、call site は type parameter declaration identity を明示して挿入する。
- pending trait check は named model に移行済みである。
- pending_trait_bound_checks は Vec<PendingTraitCheck> で保持し、bound / target_ty / span の意味を型と field 名で固定する。
- monomorphize trait lookup は typed key に移行済みである。
- impl_map、impl_method_index、trait_lookup_cache は MonoTraitLookupKey / MonoTraitMethodKey を key にする。
- impl_entry_index は重複 index として削除済みであり、trait name / method string tuple key には戻さない。
- source policy は final contract として監視済みである。
- nodesrc/test_abstraction_static_verification_policy.js は baseline 増加抑止ではなく、typed model / enum model / named state / typed lookup key の存在と旧 model 再導入禁止を直接検査する。
目標設計
TraitApplication
trait reference は表示文字列ではなく typed value として保持する。
struct TraitApplication {
trait_id: TraitId,
args: Vec<TypeId>,
}TraitId は外部表示名ではなく compiler identity として扱う。現行の名前解決が保持する正規の宣言 identity を包み、TraitApplication の表示文字列や diagnostic 文面から逆算しない。
TraitBound
type parameter bound は TraitBoundRef.name を廃止し、diagnostic だけが表示名を生成する。
struct TraitBound {
application: TraitApplication,
self_ty: TypeId,
}bound satisfaction は TraitApplication 同士を比較し、表示文字列から type argument を parse しない。
ImplKind
impl は field combination ではなく enum で表す。
enum ImplKind {
Inherent,
Trait {
application: TraitApplication,
self_ty: TypeId,
},
}これにより、trait impl なのに trait_base_name がない、inherent impl なのに trait args がある、といった不正状態を型で排除する。
PendingTraitCheck
deferred check は named struct / enum にする。
struct PendingTraitCheck {
bound: TraitBound,
candidate: TypeId,
span: Span,
}将来、ConcreteImplRequired、TypeParamBoundRequired、CapabilityRequired のように分類が必要になったら enum variant として追加する。
MonoTraitLookupKey
monomorphize の trait lookup key は typed struct にする。
struct MonoTraitLookupKey {
application: TraitApplication,
method: TraitMethodId,
self_ty: TypeId,
}TraitMethodId も display string ではなく compiler identity とする。diagnostic 出力時だけ文字列化する。
実装計画
Stage 0: 現状凍結と監査
目的: string-based trait reference authority が増えないようにする。
作業:
nodesrc/test_abstraction_static_verification_policy.jsを追加し、format_trait_ref_name、TraitBound、ImplInfo、trait_lookup_cacheの current baseline を固定する。parse_trait_ref_nameは Stage 1 の作業で 0 baseline になっており、再導入禁止にした。- baseline は最終状態ではない。今後の stage で残りの表示名 field / string key の数を下げる。
完了状態:
- 2026-05-13: Stage 6 の完了により、baseline 凍結は final contract へ移行した。
parse_trait_ref_name/TraitBoundRef/ImplInfooptional field / split HIR・Resource・monomorphize lookup field の再導入禁止は構造検査で固定する。
Stage 1: typed TraitApplication 導入
目的: trait reference を表示文字列ではなく typed value として渡す。
作業:
TraitApplication/TraitIdを typecheck abstraction module に追加する。TraitBoundRefをTraitBoundへ置換する。format_trait_ref_nameは diagnostic/display helper へ移動し、静的検査の分岐から外す。parse_trait_ref_nameを削除する。
進捗:
- 2026-05-12:
function_check.rsの deferred trait bound check は、TraitBoundRef.nameの表示文字列をparse_trait_ref_nameで復元する経路から、trait_base_name/trait_argsを直接比較する typed lookup へ移行した。 - 2026-05-12:
prefix_check.rsの trait method self inference は、表示名を作ってinfer_unique_type_param_for_traitで parse し直す経路から、infer_trait_application_argsのTypeId列を直接infer_unique_type_param_for_trait_refへ渡す経路へ移行した。これによりparse_trait_ref_nameは削除済みになった。 - 2026-05-12:
TraitBoundRefをTraitBoundに改名し、表示名 field を削除した。診断と verbose log はTraitBound::display_nameで境界生成する。 - 2026-05-12:
TraitApplicationを追加し、TraitBoundはapplication: TraitApplicationとtrait_self_tyを持つ形にした。type parameter bound の trait identity は split field ではなく typed value になった。 - 2026-05-12: typecheck 側の impl matching も
TraitApplicationhelper へ寄せた。function_check.rs/trait_check.rs/trait_call_apply.rsはimp.trait_base_name/imp.trait_argsを直接読まず、ImplInfo::matches_trait_applicationを使う。 - 2026-05-13:
ISS-20260512T185123437Z-TYPECHECK-TRAITAPPLICATION-STILL-STO-F6F9CDD1を追加し、typecheck-sideTraitApplicationの trait identity をTraitIdnewtype へ移行した。BoundEnv/ impl matching / trait method inference は raw&strではなくTraitIdを受け取り、文字列化は diagnostic/display 境界に限定する。
検証:
- generic trait argument regression。
- non-primitive trait argument regression。
- nested apply trait argument regression。
- unknown trait / wrong arity diagnostic。
Stage 2: ImplKind 導入
目的: impl の状態を optional field combination ではなく enum にする。
作業:
ImplInfoをImpl { kind: ImplKind, target_ty, type_params, methods }系へ再設計する。- duplicate impl、missing method、method signature mismatch は
match ImplKindで分岐する。 - inherent impl unsupported も
ImplKind::Inherentの明示的診断にする。
検証:
- duplicate impl。
- generic impl trait args。
- generic target rejection。
- capability trait impl validation。
進捗:
- 2026-05-12:
ISS-20260512T153756004Z-IMPLINFO-STILL-ENCODES-TRAIT-IMPL-ID-A4ECD77Bを追加し、verified にした。 - 2026-05-12:
ImplKindを追加し、ImplInfoをkind: ImplKindとtarget_tyの形へ移行した。trait impl identity はImplKind::Trait { application: TraitApplication, self_ty: TypeId }に集約し、optional string field の組み合わせからは切り離した。 - 2026-05-12: duplicate impl / deferred trait check / trait bound satisfaction / trait method application は、split field ではなく
ImplInfohelper 経由で trait application を照合する。 - 残件: final
HirImplとmonomorphize.rsは Stage 5 の typed monomorphize lookup で対応する。ここでは typecheck-side static verification authority の enum 化を完了対象にした。
Stage 3: BoundEnv と type parameter identity
目的: bound map の key を不安定な TypeId / label fallback から分離する。
作業:
- type parameter declaration identity を
TypeParamIdとして保持する。 BoundEnvを追加し、TypeIdresolve と declaration identity の対応を一箇所で管理する。- label fallback を削除し、必要なら明示的な substitution map で処理する。
検証:
- same label but different scope の bound 混線が起きないこと。
- nested generic function unsupported diagnostic。
- generic function calls generic。
進捗:
- 2026-05-12:
ISS-20260512T160137255Z-TRAIT-BOUND-LOOKUP-DUPLICATES-TYPEID-1694BE55を追加し、verified にした。 - 2026-05-12:
trait_check.rsのBlockChecker::type_param_has_bound_refがtraits.rsのtype_param_has_trait_application_boundと同じ TypeId / label fallback lookup を再実装していたため、duplicate 実装を削除し、BlockChecker 側は typed helper へ委譲する薄い method にした。 - 2026-05-12:
ISS-20260512T160950280Z-TRAIT-BOUND-LOOKUP-STILL-ACCEPTS-SAM-C03A85E0を追加し、verified にした。 - 2026-05-12:
type_param_has_trait_application_boundからTypeKind::Varlabel 文字列が一致する別TypeIdを同一 bound とみなす fallback を削除した。 - 2026-05-12:
ISS-20260512T172241782Z-TRAIT-TYPE-PARAMETER-BOUNDS-STILL-EX-09CE8755を追加し、verified にした。 - 2026-05-12:
BoundEnvを追加し、type parameter trait bounds の rawBTreeMap<TypeId, Vec<TraitBound>>をBlockChecker/BindingKind/check_functionの境界から外した。bound lookup はBoundEnv::has_trait_application_boundに閉じ込めた。 - 2026-05-12:
ISS-20260512T173702516Z-BOUNDENV-STILL-KEYS-TYPE-PARAMETER-B-792D9BA4を追加し、TypeParamIdを導入した。BoundEnvはBTreeMap<TypeParamId, Vec<TraitBound>>を保持し、insert/iterの境界でも rawTypeIdを受け取らない。 - 2026-05-12: nested function check と top-level driver の type parameter bound collection は
TypeParamId::new(*p_id)を明示してBoundEnvへ渡す形にし、source policy で rawTypeIdkey の再導入を拒否する。
Stage 4: trait method resolution の構造化
目的: trait method call result を raw FuncRef::Trait 生成に直接落とさず、resolution result enum を経由させる。
作業:
TraitMethodResolutionenum を追加する。- receiver inference、expected self type、type argument inference、effect check を分類する。
- failure は
TypeDiagnosticCode/EffectDiagnosticCodeの typed diagnostic にする。
検証:
- trait method type args unsupported。
- trait method not found。
- pure calls impure trait method。
- receiver / expected self type なしの診断。
進捗:
- 2026-05-12:
ISS-20260512T161908521Z-TRAIT-METHOD-RESOLUTION-STILL-RETURN-21525B05を追加し、verified にした。 - 2026-05-12:
TraitMethodResolutionenum とTraitMethodCallmodel を追加し、selected callable / unbound trait method call の receiver inference と trait application inference を共通 resolver に集約した。 - 2026-05-12:
infer_selected_trait_method_callee -> Option<FuncRef>は削除した。selected callable 側はTraitMethodResolutionを match し、unbound 側は typed failure variant から diagnostic を生成する。 - 2026-05-13:
ISS-20260512T193917855Z-TRAIT-METHOD-RESOLUTION-STILL-CARRIE-0BFEEFA9を追加し、TraitMethodCallとTraitMethodResolution::UnsatisfiedBoundの payload もTraitApplicationへ移行した。trait method resolution の途中で表示名を作るinfer_trait_application_nameは削除し、diagnostic 境界だけでdisplay_nameを呼ぶ。 - 2026-05-12:
ISS-20260512T163228542Z-PENDING-TRAIT-CHECKS-STILL-USE-POSIT-FB7F1082を追加し、verified にした。 - 2026-05-12:
pending_trait_bound_checks: Vec<(TraitBound, TypeId, Span)>をVec<PendingTraitCheck>へ移行し、pending check のbound/target_ty/spanを名前付き field として保持するようにした。
Stage 5: monomorphize lookup key typed 化
目的: typecheck と monomorphize が同じ trait application identity を共有する。
作業:
TraitImplEntryとTraitImplResolutionを typedTraitApplication/MonoTraitLookupKeyへ移行する。- string-keyed
impl_map/impl_method_index/impl_entry_index/trait_lookup_cacheを typed key へ置換する。 - unresolved trait call は引き続き
MonomorphizeResultで構造化して返す。
検証:
monomorphize::tests::public_monomorphize_returns_unresolved_trait_calls_without_panicking- generic impl trait argument resolution。
- generated Drop trait call monomorphize。
- Resource IR drop elaboration origin preservation。
進捗:
- 2026-05-12:
ISS-20260512T164311083Z-MONOMORPHIZE-TRAIT-LOOKUP-KEYS-STILL-DA66AC14を追加し、verified にした。 - 2026-05-12:
monomorphize.rsのimpl_map/impl_method_index/trait_lookup_cacheを positional tuple key からMonoTraitApplication/MonoTraitMethodKey/MonoTraitLookupKeyへ移行した。 - 2026-05-12: 旧
impl_entry_indexはimpl_method_indexと同じ candidate set を二重に保持していたため削除し、trait base name + method の候補 index に統合した。 - 2026-05-12:
ISS-20260512T175900768Z-MONOMORPHIZE-TRAIT-LOOKUP-MODEL-EXCE-55B52B7Eを追加し、MonoTraitApplication/MonoTraitMethodKey/MonoTraitLookupKey/TraitImplEntry/TraitImplResolutionをmonomorphize/trait_lookup.rsへ分離した。typed identity model は維持しつつ、rootmonomorphize.rsの責務集中を戻した。 - 2026-05-12:
ISS-20260512T165852784Z-HIR-TRAIT-CALLS-STILL-SPLIT-TRAIT-AP-405A462Bを追加し、verified にした。 - 2026-05-12:
HirTraitApplicationを追加し、FuncRef::TraitとHirImplの trait identity を split string fields ではなく typed application で保持する形へ移行した。 - 2026-05-12:
ISS-20260512T171317751Z-RESOURCE-IR-TRAIT-CALL-TARGET-STILL--6B70AE36を追加し、verified にした。 - 2026-05-12:
ResourceTraitApplicationを追加し、ResourceCallTarget::Traitも split fields ではなく typed application を保持する形へ移行した。 - 2026-05-13:
ISS-20260512T190305376Z-HIR-AND-RESOURCE-TRAIT-APPLICATIONS--0B41B202を追加し、HIR / Resource IR の trait application identity をHirTraitId/ResourceTraitIdnewtype へ移行した。monomorphize と Resource lowering はas_str()境界でのみ文字列化する。 - 2026-05-13:
ISS-20260512T155153362Z-GENERIC-TRAIT-PROBE-REGRESSION-FIXTU-65BB07DBを verified にした。Stage 5 の trait/generic regression は、PureCallsImpureを弱めず、raw memory を直接呼ぶ generic helper を impure signature に直すことで復旧した。 - 2026-05-13:
ISS-20260512T182144401Z-MONOMORPHIZE-TRAIT-LOOKUP-METHOD-IDE-99EBBCACを追加し、MonoTraitMethodIdnewtype を導入した。MonoTraitMethodKey/MonoTraitLookupKeyは method identity を rawStringではなく typed id として保持する。 - 2026-05-13:
ISS-20260512T183111826Z-MONOMORPHIZE-TRAIT-APPLICATION-STILL-835C27CFを追加し、monomorphize trait identity もMonoTraitIdnewtype へ移行した。MonoTraitApplication/MonoTraitMethodKeyは trait identity を rawStringではなく typed id として保持し、identity type はmonomorphize/trait_identity.rsへ分離した。 - 2026-05-13:
ISS-20260512T191325765Z-HIR-AND-RESOURCE-TRAIT-METHOD-IDENTI-78952D7Bを追加し、HIR / Resource IR の trait method identity もHirTraitMethodId/ResourceTraitMethodIdnewtype へ移行した。FuncRef::Trait/ResourceCallTarget::Traitは rawStringmethod field を持たず、文字列化は lowering / dump / diagnostic 境界のas_str()に限定する。Resource IR 側の trait identity type はresource/trait_identity.rsへ分離し、resource/model.rsの責務上限も維持する。 - 2026-05-13:
ISS-20260512T194845369Z-IMPL-METHOD-LOWERING-STILL-KEEPS-REN-E15DE8F5を追加し、impl method lowering pass もTraitApplicationpayload を持つ形へ移行した。method symbol mangle の境界だけでdisplay_nameを作り、finalHirImplは typed application から HIR application へ変換する。 - 2026-05-13:
ISS-20260512T195620903Z-MONOMORPHIZE-TRAIT-RESOLUTION-STILL--0481CA39を追加し、monomorphize trait resolver の入口もHirTraitApplication/HirTraitMethodIdを直接受け取る形へ移行した。call site で trait name / method string へ分解する旧resolve_trait_impl_nameは削除した。 - 2026-05-14:
ISS-20260513T154226197Z-DROP-INSERTION-PLAN-STILL-CARRIES-RA-EF658B47を追加し、HIR drop insertion のDropPlanもHirTraitApplication/HirTraitMethodIdを保持する形へ移行した。auto-drop 生成は rawtrait_name/method_nameからFuncRef::Traitを組み立てず、typed HIR trait identity payload をそのまま消費する。 - 残件: Stage 5 の typed trait / method identity は typecheck / HIR / monomorphize / Resource IR call target まで到達した。次は policy baseline を整理し、BoundEnv / TypeParamId 残件と Resource IR 側の安全検査 issue に戻る。
Stage 6: policy baseline を 0 に下げる
目的: Stage 0 の凍結線を最終設計へ移す。
作業:
parse_trait_ref_namebaseline は 0 済みであり、再導入禁止を維持する。TraitBoundRef旧 model baseline は 0 済みであり、再導入禁止を維持する。ImplInfooptional field baseline は 2026-05-12 に typecheck-sideImplKind導入で 0 済みであり、source policy はImplInfostruct body だけを検査する。TraitInfo.docのOption<String>は documentation data であり、impl identity policy の baseline には数えない。- source policy を「増加禁止」から「再導入禁止」へ変更する。
進捗:
- 2026-05-12:
ISS-20260512T174845757Z-ABSTRACTION-POLICY-COUNTS-TRAITINFO--FE3DB746を追加し、ImplInfooptional field の policy をtraits.rs全体のOption<String>数ではなくImplInfostruct body 直接検査へ変更した。これによりImplInfoは optional field 0 件を baseline ではなく完了条件として監視する。 - 2026-05-13:
ISS-20260512T193917855Z-TRAIT-METHOD-RESOLUTION-STILL-CARRIE-0BFEEFA9により、trait method resolution result の splittrait_name/trait_args/applied_trait_namepayload 再導入禁止を source policy に追加した。format_trait_ref_namebaseline は 6 から 4 に下げた。 - 2026-05-13:
ISS-20260512T194845369Z-IMPL-METHOD-LOWERING-STILL-KEEPS-REN-E15DE8F5により、impl lowering pass の directformat_trait_ref_nameとapplied_trait_namepayload 再導入禁止を source policy に追加した。format_trait_ref_namebaseline は 4 から 2 に下げた。 - 2026-05-13:
ISS-20260512T143721313Z-GENERIC-AND-TRAIT-ABSTRACTION-MODEL--1F2FF429の最終確認で、source policy を baseline 増加抑止から final contract 検査へ変更した。format_trait_ref_nameはtraits.rsの display boundary に限定し、trait_lookup_cacheは出現数ではなくBTreeMap<MonoTraitLookupKey, Option<TraitImplResolution>>という typed key model を直接検査する。 - 2026-05-13:
ISS-20260513T162705742Z-TRAITSEMANTICS-STORES-CAPABILITY-TRA-C51DB134により、TraitSemanticsの Copy / Clone / Drop capability trait 集合から表示名Stringを削除した。capability category はTraitCapabilityenum の exhaustivematchで選び、保持する identity はTypeIdのみにした。source policy もVec<(String, TypeId)>の再導入を拒否する。
進捗状況
typecheck/traits.rs: Stage 1/2/6 は進行済み。TraitCapability enum、TraitId、TraitApplication、TraitBound、ImplKind が存在する。function-level deferred check の string parsing とTraitBoundRef.nameは除去済みで、type parameter bound はTraitApplicationに集約済み。ImplInfo はImplKindを持ち、optional string model ではない。TraitSemanticsの capability trait 集合は raw name を保持せず、TypeIdとTraitCapabilityの match だけで判定する。typecheck/trait_check.rs: Stage 3/4 実装済み。trait application parse 依存、split impl field 参照、duplicate label fallback 実装は削除済み。typecheck/trait_bound_apply.rs: Stage 4 実装済み。pending check はPendingTraitChecknamed model を使い、tuple state には戻さない。typecheck/trait_call_apply.rs: Stage 4/5 は進行済み。trait method resolution はTraitMethodResolutionenum を match し、resolution payload はTraitApplicationとHirTraitMethodIdを保持する。診断表示名は failure diagnostic を作る境界だけで生成する。typecheck/driver.rs: Stage 5 は進行済み。impl collection と impl method lowering はTraitApplicationを保持し、表示名は method symbol mangle の境界でのみ生成する。passes/drop_insertion.rs: Stage 5 は進行済み。auto-drop 生成のDropPlanはHirTraitApplication/HirTraitMethodIdを保持し、rawtrait_name/method_nameから generated Drop trait call を組み立てない。hir.rs: Stage 5 は進行済み。HirTraitId/HirTraitApplication/HirTraitMethodIdを追加し、FuncRef::Trait/HirImplは typed trait application と typed method identity を保持する。monomorphize.rs: Stage 5 実装済み。trait lookup cache / impl indexes はMonoTraitApplication/MonoTraitMethodKey/MonoTraitLookupKeyへ移行済み。Resolver 入口はHirTraitApplication/HirTraitMethodIdを直接受け取り、monomorphize phase 内のMonoTraitId/MonoTraitMethodIdを含む resolved key へ変換する。resource/model.rs: Stage 5 は実装済み。ResourceTraitId/ResourceTraitApplication/ResourceTraitMethodIdにより Resource IR call target の trait identity と method identity を typed field として保持する。resource/trait_identity.rs: Stage 5 は実装済み。Resource IR の trait / method identity newtype と application payload をここに集約し、resource/model.rsの call target model から identity helper 実装を分離している。monomorphize/trait_identity.rs: Stage 5 は実装済み。monomorphize 内部の trait / method identity newtype をここに集約し、lookup key module から raw string identity field を排除している。nodesrc/test_abstraction_static_verification_policy.js: Stage 6 final contract policy として更新済み。typed model / enum model / named state / typed lookup key の存在と旧 string authority model の再導入禁止を直接検査する。