Milestone
M5 (diagnostics) — parent #1492. Unblocks triage for #3028–#3031, #3035–#3036, #3041. Script UX slice: #3049. Complements #2988.
Problem
build/selfhost-native-compile-driver logs only:
helloworld_compile_smoke: parseAndCompile returned null (parser/CFG spine)
helloworld_compile_smoke: native emit failed at phase=parseAndCompile
Zend on the same bundle prints actionable errors (2026-05-29 probe):
| Bundle |
Zend parseAndCompile failure: |
ircmaxell-php-cfg |
Unknown type declaration found: */ (#3035) |
ircmaxell-php-types |
Unknown type declaration found: PHPTypes\Type The type (#3036) |
ircmaxell-php-llvm |
Unknown type declaration found: [type] [description] (#3041) |
Implementers must re-run Zend lint manually; build/bootstrap-vendor/*.log tails are useless today.
Implementation plan (ready)
1. Capture last failure in lib/Runtime.php
- Add
private static ?string $lastParseFailure = null (or thread-local) set in parse() / parseAndCompile() catch blocks when RuntimeException escapes PHPTypes/Compiler.
- Public accessor:
Runtime::getLastParseFailure(): ?string for M3 emit bridge (no behavior change on success path).
2. M3 emit bridge (helloworld_compile_smoke.php and shared helper)
- Before
return null on failed parseAndCompile, fprintf(STDERR, "parseAndCompile failure: target=%s: %s\n", $target, Runtime::getLastParseFailure() ?? 'unknown') — match Zend CLI prefix so bootstrap-vendor-objects.php can grep uniformly.
- Ensure
PHP_COMPILER_VENDOR_PRELINK=1 path uses same helper (vendor bundles).
3. Native compiled driver path
- Confirm AOT-compiled
Runtime::parseAndCompile lowering propagates exception message string (may need lib/AOT/runtime string export if currently swallowed) — bisect with BOOTSTRAP_M3_USE_INVENTORY_EMIT_DRIVER=1 on HelloWorld first.
4. script/bootstrap-vendor-objects.php
- On non-zero compile: if log lacks
parseAndCompile failure:, append Runtime::getLastParseFailure from Zend re-run is not acceptable — fix native path only (#3049).
5. Regression
- Add
test/real or script test: fixture PHP that throws known RuntimeException in parse → native M3 smoke stderr contains substring.
| Path |
Work |
lib/Runtime.php |
lastParseFailure + accessor |
test/selfhost/compiler_helloworld_smoke/helloworld_compile_smoke.php |
Stderr on null |
lib/AOT/ |
If native path drops exception text |
script/bootstrap-vendor-objects.php |
Grep-friendly FAIL (#3049) |
Repro
./script/docker-exec.sh --sync-back build/selfhost-native-compile-driver -- bash -lc '
make bootstrap-selfhost-driver-smoke
PHP_COMPILER_VENDOR_PRELINK=1 php script/bootstrap-vendor-objects.php --compile
'
# Native: null only; Zend -l shows Type.php:419 message
Done when
- Native vendor compile stderr/log includes same
parseAndCompile failure: line as Zend -l for all three bundles (before fixing PHPTypes)
bootstrap-vendor-objects.php --compile FAIL lines quote the declaration token (#3049)
- No manual
php bin/compile.php -l required to start work on #3035+
Milestone
M5 (diagnostics) — parent #1492. Unblocks triage for #3028–#3031, #3035–#3036, #3041. Script UX slice: #3049. Complements #2988.
Problem
build/selfhost-native-compile-driverlogs only:Zend on the same bundle prints actionable errors (2026-05-29 probe):
parseAndCompile failure:ircmaxell-php-cfgUnknown type declaration found: */(#3035)ircmaxell-php-typesUnknown type declaration found: PHPTypes\Type The type(#3036)ircmaxell-php-llvmUnknown type declaration found: [type] [description](#3041)Implementers must re-run Zend lint manually;
build/bootstrap-vendor/*.logtails are useless today.Implementation plan (ready)
1. Capture last failure in
lib/Runtime.phpprivate static ?string $lastParseFailure = null(or thread-local) set inparse()/parseAndCompile()catch blocks whenRuntimeExceptionescapes PHPTypes/Compiler.Runtime::getLastParseFailure(): ?stringfor M3 emit bridge (no behavior change on success path).2. M3 emit bridge (
helloworld_compile_smoke.phpand shared helper)return nullon failedparseAndCompile,fprintf(STDERR, "parseAndCompile failure: target=%s: %s\n", $target, Runtime::getLastParseFailure() ?? 'unknown')— match Zend CLI prefix sobootstrap-vendor-objects.phpcan grep uniformly.PHP_COMPILER_VENDOR_PRELINK=1path uses same helper (vendor bundles).3. Native compiled driver path
Runtime::parseAndCompilelowering propagates exception message string (may needlib/AOT/runtimestring export if currently swallowed) — bisect withBOOTSTRAP_M3_USE_INVENTORY_EMIT_DRIVER=1on HelloWorld first.4.
script/bootstrap-vendor-objects.phpparseAndCompile failure:, appendRuntime::getLastParseFailurefrom Zend re-run is not acceptable — fix native path only (#3049).5. Regression
test/realor script test: fixture PHP that throws knownRuntimeExceptionin parse → native M3 smoke stderr contains substring.lib/Runtime.phplastParseFailure+ accessortest/selfhost/compiler_helloworld_smoke/helloworld_compile_smoke.phplib/AOT/script/bootstrap-vendor-objects.phpRepro
Done when
parseAndCompile failure:line as Zend-lfor all three bundles (before fixing PHPTypes)bootstrap-vendor-objects.php --compileFAIL lines quote the declaration token (#3049)php bin/compile.php -lrequired to start work on #3035+