From 31f6ac69794361cdaee52cba0213a1b4da4932ac Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 4 Jul 2026 03:20:23 +0900 Subject: fix(event-dispatcher): avoid reentrant RefCell panics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related "already borrowed" panics reachable from AutoloadGenerator::dump() (which holds the local-repository, installation-manager, and config RefCells for the duration of its own statement, per the temporary-lifetime-extension pattern fixed separately in create_project_command.rs): - ensure_bin_dir_is_in_path called config.borrow_mut() to read "bin-dir", but Config::get only needs &self; use borrow() so it can coexist with an outer borrow instead of conflicting with it. - make_autoloader's real body needed composer_handle.borrow_mut() plus the same local-repository/installation-manager RefCells the caller already holds mutably, which cannot be made reentrant-safe without a larger restructuring. Since all 3 call sites already discard its return value, and its only effect (registering a Composer-generated ClassLoader for autoloading during event-listener PHP execution) is unobservable in this port — there's no embedded PHP interpreter to register it into, and class_exists for user-defined classes is a hardcoded-false shim so the caller's very next check always treats the class as unavailable regardless — make it a genuine no-op. This unblocks the post-autoload-dump event for any script listener naming a PHP class (e.g. Illuminate\Foundation\ComposerScripts), which every create-project/install run reaches once real packages get installed. Co-Authored-By: Claude Sonnet 5 --- crates/shirabe/tests/command/require_command_test.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'crates/shirabe/tests/command') diff --git a/crates/shirabe/tests/command/require_command_test.rs b/crates/shirabe/tests/command/require_command_test.rs index 2464f3d..e618650 100644 --- a/crates/shirabe/tests/command/require_command_test.rs +++ b/crates/shirabe/tests/command/require_command_test.rs @@ -17,7 +17,6 @@ fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { #[test] #[serial] -#[ignore = "shirabe_php_shim::phpversion(extension) is a todo!() (per-extension version strings not modeled); reached while checking the ext-foobar platform requirement during version selection"] fn test_require_throws_if_none_matches() { let composer_json = serde_json::json!({ "repositories": { @@ -59,7 +58,10 @@ fn test_require_throws_if_none_matches() { #[test] #[serial] -#[ignore = "Phase-C re-entrancy: EventDispatcher::make_autoloader calls Composer borrow_mut while the Composer is already borrowed up the installer-event-dispatch stack, panicking with \"RefCell already borrowed\" (composer.rs:507)"] +#[ignore = "the prior RefCell re-entrancy panic is fixed; now fails on the pre-operations-exec \ + listener dispatch with \"Subscriber ?::? for event pre-operations-exec is not \ + callable\" (event_dispatcher.rs TODO(plugin): is_callable/invoke for non-string \ + callables is unimplemented)"] fn test_require_warns_if_resolved_to_feature_branch() { let composer_json = serde_json::json!({ "repositories": { @@ -264,7 +266,10 @@ Using version 1.1.0 for required/pkg", #[test] #[serial] -#[ignore = "Phase-C re-entrancy: EventDispatcher::make_autoloader calls Composer borrow_mut while the Composer is already borrowed up the installer-event-dispatch stack, panicking with \"RefCell already borrowed\" (composer.rs:507)"] +#[ignore = "the prior RefCell re-entrancy panic is fixed; now fails on the pre-operations-exec \ + listener dispatch with \"Subscriber ?::? for event pre-operations-exec is not \ + callable\" (event_dispatcher.rs TODO(plugin): is_callable/invoke for non-string \ + callables is unimplemented)"] fn test_require() { for (label, composer_json, command, expected) in provide_require() { let _tear_down = init_temp_composer(Some(&composer_json), None, None, true); @@ -335,7 +340,10 @@ fn provide_inconsistent_require_keys() -> Vec<(bool, bool, &'static str)> { #[test] #[serial] -#[ignore = "update/solver pipeline incomplete: the require run fails with \"Fixed package __root__ 1.0.0+no-version-set was not added to solver pool.\" (the root package is not seeded into the solver pool)"] +#[ignore = "the solver-pool root-package issue is fixed; now panics in shirabe_php_shim::preg \ + (\"look-around, including look-ahead and look-behind, is not supported\") because \ + the dev-branch pattern `^dev-(?!main$|master$|trunk$|latest$)` uses a lookahead the \ + `regex` crate cannot express (see docs/dev/regex-porting.md)"] fn test_inconsistent_require_keys() { for (is_dev, is_interactive, expected_warning) in provide_inconsistent_require_keys() { let current_key = if is_dev { "require" } else { "require-dev" }; -- cgit v1.3.1