Repository navigation
Conversation
…ed files use them
The probe now also detects WeakMap/WeakReference; the pipeline docs also omitted the existing tokenizer, fileinfo and web-environment groups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The core prelude decides whether to declare
WeakMapandWeakReferenceby looking only at the entry program. That decision runs before the Composer autoload pass. So when only an autoloaded class names one of them, the class is pruned and the autoloaded file fails to compile:revolt/event-loop hits this (
Internal\DriverSuspension,Internal\AbstractDriver,FiberLocal), so no program built on Revolt compiles today.With this PR, the existing
autoload::prelude_probe, which already does this for PDO, mysqli, curl, hash, fileinfo and others, also detectsWeakMapandWeakReferencein the autoload closure.core_prelude::inject_if_usedthen keeps them.Repro
composer.json:{"autoload":{"psr-4":{"App\\":"src/"}}}main(145426b)error[src/Registry.php:5:5]: Unknown type: WeakMap11How it works
flowchart TD A[parse entry + resolve includes] --> B[autoload::Registry::build<br/>composer.json PSR-4 / classmap / files] B --> C["autoload-prelude-probe<br/>(disposable copy)"] C --> C1[name_resolver::resolve on a clone] C1 --> C2[autoload::run: load the whole class closure] C2 --> C3["run every PROBED_GROUPS detector<br/>… + weak_map, weak_reference"] C3 --> C4[restore span / anon-class counters] C4 --> D{"autoloaded(group)"} D --> E["preludes: pdo, mysqli, tz, image, hash, tokenizer, …"] D --> F["core_prelude::inject_if_used(ast,<br/>autoloaded(weak_map), autoloaded(weak_reference))"] F --> G[name resolution] G --> H["real autoload::run<br/>(class files now see WeakMap/WeakReference)"] H --> I[type check → EIR → codegen]PROBED_GROUPS:core_prelude::program_uses_weak_map/program_uses_weak_referenceapply the entry-program test (usage.classes/usage.literals) to the autoload closure.inject_if_usedtakes the two probed flags. The rest of the selection is unchanged:WeakMapstill impliesWeakReference, and introspection or dynamic construction still keeps both.pipeline.rspassesautoloaded("weak_map")andautoloaded("weak_reference"). Test frontends without autoload passfalse, false.docs/compiling/compilation-pipeline.md,docs/internals/how-elephc-works.mdanddocs/internals/architecture.mdnow name every group. Before this PR they also left out tokenizer, fileinfo and web-environment.Compile-time cost. Each new detector adds one
prelude_prune::usage::collectwalk over the closure. I timed a generated PSR-4 project with 200 autoloaded classes (12 methods each), using a debug build and--timings. Theautoload-prelude-probephase took 1.66 s on main and 1.00 s on the branch, out of about 410 s total in both cases. The difference is within noise, so there is no measurable cost.Tests
probe_detects_weak_references_in_autoloaded_classesweak_mapfor a promoted\WeakMapproperty and for anew \WeakMap()body, andweak_referencefor a?\WeakReferencepropertytest_weak_map_composer_autoload_activation1|other(same as php 8.5). It fails on main withUnknown type: WeakMapRuns on c9eb795:
cargo test -p elephc --lib prelude_probe: 5 passed.cargo test --test codegen_tests weak: 78 passed.cargo test --test error_tests weak: 3 passed.cargo build: no new warnings.git diff --check: clean.Note
CI status: this PR comes from a fork, so the
CI,PDO Live DatabasesandPHP extension host SDKworkflows are waiting for maintainer approval (action_required). The focused tests above ran locally on macOS arm64, and the codegen tests were also compared with PHP 8.5.12. The change has no target-specific code.Limits
The probe is still an allow-list. The same bug affects other usage-gated preludes that are not probed. Each case below was measured on this branch with a PSR-4 class that uses the surface and an entry file that never names it. Each one compiles fine when the entry names the surface, and php 8.5 runs each one:
new \Random\Randomizer(new \Random\Engine\Mt19937(42))Undefined class: Random\Engine\Mt199371\mt_srand(42); \mt_rand(1, 100)Undefined function: mt_srand43new \BcMath\Number("1.5")Undefined class: BcMath\Number3.75\DateTimeZone::listIdentifiers(...)Undefined function: __elephc_list_identifiers1\gmp_add(...)call to unknown function __elephc_gmp_add123…891Follow-ups
random,bcmath,gmpandlist_id. For random, bcmath and gmp this also needs the bridge-archive and link selection to see the probed flag, so it is more than a one-linePROBED_GROUPSentry. That is why it is left out of this PR.