Skip to content

feat(compiler): add compiler-only type pipeline for range iterator storage#51

Merged
SuperIceCN merged 16 commits into
masterfrom
feat/frontend/compiler-type
Jul 3, 2026
Merged

feat(compiler): add compiler-only type pipeline for range iterator storage#51
SuperIceCN merged 16 commits into
masterfrom
feat/frontend/compiler-type

Conversation

@SuperIceCN

Copy link
Copy Markdown
Collaborator

Summary

Introduce GdCompilerType as a compiler-only storage abstraction and wire the first concrete GdccForRangeIterType through frontend guards, LIR validation, and C backend intrinsics. This keeps lowered for range(...) iterator state on backend-owned paths while preventing compiler-only types from leaking into source-facing or ABI-facing surfaces.

What changed

  • Add GdCompilerType and GdccForRangeIterType, plus shared type-check helpers and updated type-system/runtime/backend docs.
  • Teach frontend semantic analysis and lowering to fail fast when compiler-only types leak into published expression facts, condition typing, typed boundaries, or writeback/materialization paths.
  • Extend LIR support with compiler::<Name> local-variable grammar, parser/serializer updates, use-site handling, and a new LirPublicAbiValidator that rejects compiler-only types on ABI-like surfaces.
  • Add C backend support for compiler-only storage contracts, prepare-block init/destroy handling, explicit gdcc.for_range_iter.* intrinsics, and guards that seal ordinary codegen paths against compiler-only types.
  • Add focused tests across type, frontend, LIR, backend, and docs to cover the new contracts and regression risks.

Why

  • Lowered for range(...) iterator state needs an internal storage type that is not a source-facing GDScript type and should not be modeled as Variant.
  • Without an explicit compiler-only type contract, codegen and metadata paths can silently fall back to default godot_* naming or ABI surfaces, which is incorrect and hard to diagnose.
  • Centralizing the contract around GdCompilerType makes future compiler-owned storage types extend the same leak guards, LIR rules, lifecycle handling, and backend naming rules.

Affected packages/files

  • gd.script.gdcc.type: GdCompilerType, GdccForRangeIterType, GdType
  • gd.script.gdcc.frontend.*: semantic analyzers, lowering session/processors, writeback support
  • gd.script.gdcc.lir.*: parser/serializer, type use-site handling, LirPublicAbiValidator
  • gd.script.gdcc.backend.c.* and src/main/c/codegen/include_451/gdcc/gdcc_intrinsic.h
  • doc/gdcc_type_system.md, doc/gdcc_low_ir.md, doc/gdcc_c_backend.md, doc/module_impl/frontend/frontend_gdcompiler_type_implementation.md

Validation

  • .\gradlew.bat test --tests gd.script.gdcc.type.GdCompilerTypeTest --tests gd.script.gdcc.frontend.lowering.FrontendLoweringBodyInsnPassTest --tests gd.script.gdcc.lir.validation.LirPublicAbiValidatorTest --tests gd.script.gdcc.backend.c.gen.GdccForRangeIterIntrinsicTest --no-daemon --info --console=plain
  • .\gradlew.bat classes --no-daemon --info --console=plain

Result: BUILD SUCCESSFUL

Risks / Notes

  • Compiler-only types are still intentionally limited to function-local LIR variables and backend-owned intrinsic paths; function parameters, returns, properties, signals, and captures remain rejected.
  • This PR establishes the storage/intrinsic pipeline and leak guards, but it does not expose compiler-only types as declared source types or broaden ordinary assignment/conversion behavior.

Key behaviors covered (Optional)

  • compiler::GdccForRangeIter round-trips only on function-local variables and is rejected on ABI-like LIR surfaces.
  • Frontend published-type, condition, and typed-boundary paths fail fast on compiler-only leaks instead of degrading into ordinary Variant or declared-type behavior.
  • C backend uses explicit gdcc_* storage/init/destroy/intrinsic helpers and rejects compiler-only values on ordinary Godot runtime/codegen paths.

Diff stats (Optional)

  • 81 files changed, 3978 insertions, 91 deletions.

Breaking changes (Optional)

  • None

Related docs (Optional)

  • doc/gdcc_type_system.md
  • doc/gdcc_low_ir.md
  • doc/gdcc_c_backend.md
  • doc/module_impl/frontend/frontend_gdcompiler_type_implementation.md

- Document the design risk analysis for the compiler-only type branch,
  including sealed-interface risks, fact sources reviewed, and
  recommended boundaries.
- Outline the implementation plan covering target boundary, scope,
  cross-module contract, and acceptance criteria.
…erType protocol

- Add GdccForRangeIterType to GdType sealed permits
- Define stable internal name, LIR-only text, C storage/init/destroy helpers
- Fail-fast on godot_* default helpers: pack/unpack, default-value, engine ABI
- Render C storage as gdcc_for_range_iter and destroy as gdcc_for_range_iter_destroy
- Reject compiler-only types in frontend ordinary boundary and writeback analysis
- Add positive protocol tests and negative family/helper barrier tests

Affected packages: type, backend/c/gen, frontend/sema/lowering
- Add use-site aware type parsing/serialization for LIR XML: only function
  `<variables>` may carry `compiler::GdccForRangeIter`; signal/property/parameter/
  return/capture surfaces fail-fast on compiler-only type leak.
- Reject unknown `compiler::...` grammar with explicit error instead of guessing
  Object type.
- Cover source-facing resolvers/registries and LIR round-trip with new tests.
- Mark stage 2 of frontend_gdcompiler_type_plan as completed.
…into semantic facts and lowering boundaries

- Reject compiler-only types in expression type publish/resolve and inferred-local backfill paths
- Reject compiler-only resolved initializer in local slot stabilization
- Reject compiler-only types in condition published facts and condition normalization
- Reject compiler-only source/target in frontend boundary materialization
- Add tests covering all new guard points
…ct sources

- Insert Phase 4 (GdCompilerType sealed interface + GdccForRangeIterType migration) into the plan, renumber subsequent phases 5→9
- Update risk analysis: GdCompilerType is now a planned requirement, not an open question
- Add compiler-only type category and compatibility boundary to gdcc_type_system.md
- Document compiler::<Name> grammar for backend-owned locals in gdcc_low_ir.md
- Add compiler-only storage naming rules (gdcc_* over godot_*) to gdcc_c_backend.md
- Introduce sealed interface for compiler-only storage types with shared protocol and design invariants
- Migrate existing concrete type to the new abstraction, removing duplicated defaults
- Update all consumer-side type checks across frontend, backend, and LIR to use the abstraction
- Add contract tests and update existing tests to anchor abstraction membership
- Sync implementation plan status
…uards

- Cover property store, subscript, call arg, and return paths
- Verify fail-fast behavior across all frontend boundary sources
- Ensure each leak site produces the expected diagnostic context
…ABI surfaces

- reject compiler-only type on property, signal, function param/return and lambda capture
- hidden functions share the same restriction as public ones in MVP
- integrate validator into CCodegen.generate() before backend synthesis
- update phase-5 plan status and add tests for validator and codegen integration
…pare-block scaffolding

- Replace IllegalStateException with CallIntrinsicInsn for compiler-only local initialization in prepare block
- Add intrinsic that emits gdcc_*_init(&var) with type validation for range iterator storage
- Register intrinsic in manager so compiler-only init helpers are routed through intrinsic dispatch
- Add tests covering init, assign, destruct and CALL_GLOBAL rejection for compiler-only types
- Update phase-6 plan status and document completed scope
…and refactor prepare-block init

- add gdcc.for_range_iter.init/should_continue/next/get with C runtime helpers and contract validation
- rework default storage init to callAssign-based no-arg intrinsic with result-type enforcement
- register all range-iterator intrinsics in manager and reject compiler-only type on non-range calls
- document intrinsic contracts in LIR spec and mark phase-7 closure in implementation plan
- add tests covering parser/serializer roundtrip, registry dispatch, codegen output and boundary rejection
…s and consolidate validation utilities

- Add centralized rejectCompilerOnly guards in InsnGenSupport and wire them into all instruction generators for receiver, operand, argument, result target and Variant boundary checks
- Unify outward metadata, typed container leaf and call wrapper paths in CGenHelper under explicit compiler-only rejection
- Extract shared LirTypeUseSite enum from duplicated parser/serializer definitions and consolidate requireNonCompilerOnly logic into TypeCheckUtil utility
- Delete private redundant reject/require methods across BackendMethodCallResolver, LirPublicAbiValidator and CGenHelper
- Document phase-8 completion in compiler-type plan and add targeted negative tests covering every guarded code path
…hs and sync docs

- Add negative tests for compiler-only variable rejection in construct_builtin, own/release and argument address-of paths
- Gate compiler-only type from builtin constructor synthesis and object lifecycle paths
- Document compiler-only type contracts, LIR-only grammar boundaries and assignability exclusion in type/low-ir/runtime-lib specs
- Record phase-9 completion in compiler-type plan with doc diff summary
- Add parser guard tests for malformed compiler:: grammar variants
…t conventions to explicit protocol

- Add isPassedByPointerInC/getCCopyHelperName/isDirectStructAssignmentSafe/validateCStorageContract triad to GdCompilerType interface
- Migrate CGenHelper, CBodyBuilder, CBodyBuilderAliasSafetySupport and CCodegen to read explicit protocol over empty-string heuristics
- Implement explicit protocol in GdccForRangeIterType to lock in direct-assignment and pointer-parameter behavior
- Add fail-fast validation preventing silent fallback to godot_* copy paths for future compiler-only types
- Extend test coverage for compiler-only assignment, return, destruct, alias-safety edges and protocol contract assertions
- Remove source-level assertions that tightly couple tests to C helper implementation text
- Clarify zero-step fallback as always-terminating with step=1, document as programming error
- Drop unused imports
- Replace the planning document with the implementation document as the canonical reference for compiler-only type
- Update the four range-iterator intrinsic sections in the LIR spec to point at the new doc
- Archive the planning doc now that all phases are completed and recorded
- Tighten the doc comment of the compiler-only range-iterator type to reflect its post-MVP status
- Keep the new implementation document untracked as the durable source of truth
Copilot AI review requested due to automatic review settings July 3, 2026 00:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a compiler-only type lane (GdCompilerType) and wires an initial concrete implementation (GdccForRangeIterType) end-to-end across frontend analysis/lowering, LIR parsing/serialization/validation, and the C backend (including new gdcc.for_range_iter.* intrinsics and gdcc_* runtime helpers). The goal is to keep lowered for range(...) iterator state in backend-owned storage while preventing compiler-only types from leaking into source-facing typing facts or ABI-facing surfaces.

Changes:

  • Add GdCompilerType + GdccForRangeIterType and central “leak guard” helpers to reject compiler-only types at source-facing / ABI-facing boundaries.
  • Extend LIR XML typing to support compiler::<Name> only for function-local variables, plus add LirPublicAbiValidator to enforce ABI surface rules.
  • Add C backend support for compiler-only storage (prepare-block init, destroy, direct-assignment contract) and range iterator intrinsics/runtime helpers, with broad regression tests and docs.

Reviewed changes

Copilot reviewed 81 out of 81 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/test/java/gd/script/gdcc/type/GdCompilerTypeTest.java Contract tests for compiler-only type protocol defaults and helper naming.
src/test/java/gd/script/gdcc/type/GdccForRangeIterTypeTest.java Concrete type tests ensuring stable protocol and non-user-facing classification.
src/test/java/gd/script/gdcc/scope/resolver/ScopeTypeResolverTest.java Ensures compiler-only texts/names don’t resolve as declared/source-facing types.
src/test/java/gd/script/gdcc/scope/ClassRegistryTypeMetaTest.java Ensures compiler-only types don’t publish type-meta.
src/test/java/gd/script/gdcc/lir/validation/LirPublicAbiValidatorTest.java Validates rejection of compiler-only types on ABI-like LIR surfaces.
src/test/java/gd/script/gdcc/lir/parser/SimpleLirBlockInsnSerializerTest.java Serializer coverage for range iterator intrinsic call shapes.
src/test/java/gd/script/gdcc/lir/parser/SimpleLirBlockInsnParserTest.java Parser round-trip and operand validation for range iterator intrinsics.
src/test/java/gd/script/gdcc/lir/parser/DomLirSerializerTest.java XML serializer uses compiler::... grammar for locals and rejects ABI leakage.
src/test/java/gd/script/gdcc/lir/parser/DomLirParserTest.java XML parser accepts compiler-only locals only; rejects other surfaces and malformed grammar.
src/test/java/gd/script/gdcc/frontend/sema/FrontendDeclaredTypeSupportTest.java Declared type resolution warns/falls back for compiler-only texts.
src/test/java/gd/script/gdcc/frontend/sema/analyzer/support/FrontendVariantBoundaryCompatibilityTest.java Frontend typed boundary rejects compiler-only types.
src/test/java/gd/script/gdcc/frontend/sema/analyzer/FrontendTypeCheckAnalyzerTest.java Condition typing fails fast if compiler-only fact leaks.
src/test/java/gd/script/gdcc/frontend/sema/analyzer/FrontendLocalTypeStabilizationAnalyzerTest.java Local stabilization fails fast on compiler-only initializer publication.
src/test/java/gd/script/gdcc/frontend/sema/analyzer/FrontendExprTypeAnalyzerTest.java Prevents publishing compiler-only types into expressionTypes().
src/test/java/gd/script/gdcc/frontend/lowering/pass/body/FrontendBodyLoweringSessionTest.java Boundary materialization rejects compiler-only source/target.
src/test/java/gd/script/gdcc/frontend/lowering/FrontendWritableTypeWritebackSupportTest.java Writeback analysis rejects compiler-only carrier types.
src/test/java/gd/script/gdcc/frontend/lowering/FrontendLoweringBodyInsnPassTest.java Lowering fails fast for multiple compiler-only leak vectors (condition, stores, calls, return).
src/test/java/gd/script/gdcc/backend/c/gen/IndexStoreInsnGenTest.java Backend index store rejects compiler-only operands pre-pack/writeback.
src/test/java/gd/script/gdcc/backend/c/gen/IndexLoadInsnGenTest.java Backend index load rejects compiler-only result targets.
src/test/java/gd/script/gdcc/backend/c/gen/GdccForRangeIterIntrinsicTest.java End-to-end C intrinsic generation contract tests for iterator operations.
src/test/java/gd/script/gdcc/backend/c/gen/CStorePropertyInsnGenTest.java Property store rejects compiler-only values early.
src/test/java/gd/script/gdcc/backend/c/gen/CPackUnpackVariantInsnGenTest.java Variant pack/unpack reject compiler-only source/target.
src/test/java/gd/script/gdcc/backend/c/gen/COwnReleaseObjectInsnGenTest.java Own/release object paths reject compiler-only variables.
src/test/java/gd/script/gdcc/backend/c/gen/COperatorInsnGenTest.java Operator paths reject compiler-only operands/result targets.
src/test/java/gd/script/gdcc/backend/c/gen/CLoadStaticInsnGenTest.java Static loads reject compiler-only result targets.
src/test/java/gd/script/gdcc/backend/c/gen/CLoadPropertyInsnGenTest.java Property loads reject compiler-only result targets.
src/test/java/gd/script/gdcc/backend/c/gen/CIntrinsicManagerTest.java Intrinsic registry includes range iterator intrinsics and raw init intrinsic.
src/test/java/gd/script/gdcc/backend/c/gen/CGenHelperTest.java Validates C helper rendering for compiler-only types and rejects Variant/metadata paths.
src/test/java/gd/script/gdcc/backend/c/gen/CDestructInsnGenTest.java Destruct emits gdcc_*_destroy for compiler-only values (explicit + finally).
src/test/java/gd/script/gdcc/backend/c/gen/CConstructInsnGenTest.java Builtin constructors reject compiler-only targets (avoid inventing godot_*).
src/test/java/gd/script/gdcc/backend/c/gen/CCodegenTest.java Codegen enforces ABI validator; prepare-block emits compiler-only init.
src/test/java/gd/script/gdcc/backend/c/gen/CBodyBuilderPhaseCTest.java Ensures & passing, prepare-block assignment semantics, and return semantics for compiler-only types.
src/test/java/gd/script/gdcc/backend/c/gen/CBodyBuilderAliasSafetySupportTest.java Alias-safety rules for compiler-only direct-assignment overwrite.
src/test/java/gd/script/gdcc/backend/c/gen/CAssignInsnGenTest.java Assignment generation uses direct struct assignment for compiler-only types.
src/test/java/gd/script/gdcc/backend/c/gen/CallMethodInsnGenTest.java Dynamic call paths reject compiler-only args/result targets before Variant pack/unpack.
src/test/java/gd/script/gdcc/backend/c/gen/CallIntrinsicInsnGenTest.java CALL_INTRINSIC dispatch supports range iterator intrinsic family.
src/test/java/gd/script/gdcc/backend/c/gen/CallGlobalInsnGenTest.java Global calls reject compiler-only args and ensure raw init helper isn’t exposed as a utility.
src/test/java/gd/script/gdcc/backend/c/gen/binding/EngineMethodAbiCodecTest.java ABI codec rejects compiler-only types.
src/main/java/gd/script/gdcc/util/TypeCheckUtil.java Shared helper to reject compiler-only types with consistent error messaging.
src/main/java/gd/script/gdcc/type/GdType.java Extends sealed hierarchy to permit compiler-only types.
src/main/java/gd/script/gdcc/type/GdCompilerType.java Defines the compiler-only type protocol (LIR text + C storage/init/copy/destroy contract).
src/main/java/gd/script/gdcc/type/GdccForRangeIterType.java Concrete compiler-only range iterator storage type.
src/main/java/gd/script/gdcc/lir/validation/LirPublicAbiValidator.java Central validator preventing compiler-only types on ABI-like LIR surfaces.
src/main/java/gd/script/gdcc/lir/parser/DomLirSerializer.java Emits compiler::... for locals; rejects compiler-only types on other surfaces.
src/main/java/gd/script/gdcc/lir/parser/DomLirParser.java Parses compiler-only grammar only where allowed; rejects unknown/malformed compiler-only texts.
src/main/java/gd/script/gdcc/lir/LirTypeUseSite.java Encodes which LIR type use-sites permit compiler-only types.
src/main/java/gd/script/gdcc/frontend/sema/analyzer/support/FrontendVariantBoundaryCompatibility.java Rejects compiler-only types at ordinary frontend boundary decision points.
src/main/java/gd/script/gdcc/frontend/sema/analyzer/FrontendTypeCheckAnalyzer.java Condition fact validation rejects compiler-only types.
src/main/java/gd/script/gdcc/frontend/sema/analyzer/FrontendLocalTypeStabilizationAnalyzer.java Prevents compiler-only types from stabilizing ordinary locals.
src/main/java/gd/script/gdcc/frontend/sema/analyzer/FrontendExprTypeAnalyzer.java Prevents compiler-only types from being published/backfilled into expression/local facts.
src/main/java/gd/script/gdcc/frontend/lowering/pass/body/FrontendCfgNodeInsnLoweringProcessors.java Condition normalization rejects compiler-only types.
src/main/java/gd/script/gdcc/frontend/lowering/pass/body/FrontendBodyLoweringSession.java Boundary materialization rejects compiler-only source/target types.
src/main/java/gd/script/gdcc/frontend/lowering/FrontendWritableTypeWritebackSupport.java Writeback support rejects compiler-only types.
src/main/java/gd/script/gdcc/backend/c/gen/intrinsic/CForRangeIterRawInitIntrinsic.java Prepare-block intrinsic for default compiler-only iterator storage initialization.
src/main/java/gd/script/gdcc/backend/c/gen/intrinsic/CForRangeIterIntrinsic.java Implements gdcc.for_range_iter.* intrinsic family and type/arity validation.
src/main/java/gd/script/gdcc/backend/c/gen/insn/StorePropertyInsnGen.java Rejects compiler-only receiver/value early on property stores.
src/main/java/gd/script/gdcc/backend/c/gen/insn/PackUnpackVariantInsnGen.java Uses shared unpack helper and rejects compiler-only targets/sources.
src/main/java/gd/script/gdcc/backend/c/gen/insn/OperatorInsnGen.java Rejects compiler-only operands/result targets for operator paths.
src/main/java/gd/script/gdcc/backend/c/gen/insn/LoadStaticInsnGen.java Rejects compiler-only result targets for static loads.
src/main/java/gd/script/gdcc/backend/c/gen/insn/LoadPropertyInsnGen.java Rejects compiler-only receiver/result targets; uses shared unpack helper.
src/main/java/gd/script/gdcc/backend/c/gen/insn/InsnGenSupport.java Centralizes compiler-only rejection and shared Variant unpack helper.
src/main/java/gd/script/gdcc/backend/c/gen/insn/IndexStoreInsnGen.java Rejects compiler-only index-store operands; uses shared unpack helper for writeback.
src/main/java/gd/script/gdcc/backend/c/gen/insn/IndexLoadInsnGen.java Rejects compiler-only index-load operands/targets; uses shared unpack helper.
src/main/java/gd/script/gdcc/backend/c/gen/insn/DestructInsnGen.java Ensures compiler-only values are destroyed via helper name rendering.
src/main/java/gd/script/gdcc/backend/c/gen/insn/CallMethodInsnGen.java Rejects compiler-only receiver/args/results; uses shared unpack helper for dynamic results.
src/main/java/gd/script/gdcc/backend/c/gen/insn/CallGlobalInsnGen.java Rejects compiler-only args/results (fixed + vararg) for globals/utilities.
src/main/java/gd/script/gdcc/backend/c/gen/insn/BackendMethodCallResolver.java Rejects compiler-only receiver/args before method resolution.
src/main/java/gd/script/gdcc/backend/c/gen/CIntrinsicManager.java Registers new range iterator intrinsic functions.
src/main/java/gd/script/gdcc/backend/c/gen/CGenHelper.java Adds compiler-only rendering/validation hooks for C names, init/copy/destroy, and metadata/Variant boundaries.
src/main/java/gd/script/gdcc/backend/c/gen/CCodegen.java Runs ABI validator pre-synthesis; emits compiler-only prepare-block init intrinsics.
src/main/java/gd/script/gdcc/backend/c/gen/CBodyBuilderAliasSafetySupport.java Extends alias-safety logic to respect compiler-only direct-assignment vs copy-helper semantics.
src/main/java/gd/script/gdcc/backend/c/gen/CBodyBuilder.java Enforces compiler-only constraints in default values, argument passing, copy/assign/return logic.
src/main/java/gd/script/gdcc/backend/c/gen/binding/EngineMethodAbiCodec.java Rejects compiler-only types when producing engine ABI descriptors.
src/main/c/codegen/include_451/gdcc/gdcc_intrinsic.h Adds compiler-only range iterator storage struct and runtime helper implementations.
doc/module_impl/frontend/frontend_gdcompiler_type_implementation.md Long-lived spec describing compiler-only type boundaries and contracts across the pipeline.
doc/gdcc_type_system.md Documents compiler-only types as a separate non-source-facing type family.
doc/gdcc_runtime_lib.md Documents new compiler-only runtime helpers in gdcc_intrinsic.h.
doc/gdcc_low_ir.md Documents compiler::<Name> grammar and where it’s permitted in LIR XML.
doc/gdcc_lir_intrinsic.md Adds documentation for gdcc.for_range_iter.* intrinsics and their contracts.
doc/gdcc_c_backend.md Notes compiler-only storage types must render via explicit gdcc_* helpers (no godot_* fallback).
doc/analysis/gdcompiler_type_design_risk_analysis.md Design/risk analysis documenting leak risks and mitigation strategy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/gd/script/gdcc/backend/c/gen/CGenHelper.java Outdated
- remove duplicated `gd.script.gdcc.scope.*` import
- remove duplicated `gd.script.gdcc.type.*` import
- keep the change limited to import cleanup for review feedback
@SuperIceCN SuperIceCN merged commit 168e501 into master Jul 3, 2026
1 check passed
@SuperIceCN SuperIceCN deleted the feat/frontend/compiler-type branch July 3, 2026 01:10
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.

3 participants