From 70c20c39de4d87633a3275fda3f2bc54b20e50b7 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Thu, 24 Sep 2026 16:28:18 -0700 Subject: [PATCH] Exercise rename refusals directly on the bounded test stack --- .../project/ordinary_index/rename/tests.rs | 67 +++++++++---------- ...xed-rename-plan-implementation-20260924.md | 8 +++ 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/crates/oa-core/src/language/analysis_source/mixed/project/ordinary_index/rename/tests.rs b/crates/oa-core/src/language/analysis_source/mixed/project/ordinary_index/rename/tests.rs index 03922c31..f006b742 100644 --- a/crates/oa-core/src/language/analysis_source/mixed/project/ordinary_index/rename/tests.rs +++ b/crates/oa-core/src/language/analysis_source/mixed/project/ordinary_index/rename/tests.rs @@ -34,18 +34,7 @@ fn renamed(layer: Layer) -> Project { p } fn rejected(bundle: &SourceBundle, desired: &Project, contains: &str) { - fn phase(message: &str) { - use std::io::Write; - let mut stderr = std::io::stderr().lock(); - writeln!(stderr, "rename rejected helper: {message}").unwrap(); - stderr.flush().unwrap(); - } - phase("entered; before authored"); - let source = authored(bundle); - phase("after authored; before plan"); - let result = source.plan_rename(desired); - phase("after plan; before result match"); - let e = match result { + let e = match authored(bundle).plan_rename(desired) { Ok(_) => panic!("unexpected accepted target"), Err(e) => e, }; @@ -489,16 +478,9 @@ fn combined_shrink_offsets_typed_growth_and_counts_untouched_files() { } #[test] fn deep_and_wide_equality_and_late_refusal_drop_on_small_stack() { - fn phase(message: &str) { - use std::io::Write; - let mut stderr = std::io::stderr().lock(); - writeln!(stderr, "rename small-stack: {message}").unwrap(); - stderr.flush().unwrap(); - } std::thread::Builder::new() .stack_size(128 * 1024) .spawn(|| { - phase("entered worker"); for (expression, result, nodes) in [ ( format!("{}1{}", "abs(".repeat(127), ")".repeat(127)), @@ -515,30 +497,43 @@ fn deep_and_wide_equality_and_late_refusal_drop_on_small_stack() { "calculation c \"C\" id \"{}\" {{ result {result}; body {expression}; }}", id(2) )); - phase(if nodes == 128 { - "deep: before authored" - } else { - "wide: before authored" - }); let source = authored(&bundle); - phase("after authored; before original clone"); assert_eq!(source.indexed.resolved.expressions.len(), nodes); let original = source.project().clone(); - phase("after original clone; before plan"); - let plan = source.plan_rename(&original).unwrap(); - phase("after plan; before plan drop"); - drop(plan); - phase("after plan drop; before desired clone"); + drop(source.plan_rename(&original).unwrap()); + + // Keep the complete admission pipeline on this worker, without + // nesting it inside the general rejection assertion helper. let mut desired = original.clone(); desired.definitions.get_mut(&id(2)).unwrap().alias = "p".into(); - phase("before collision rejection"); - rejected(&bundle, &desired, "collide"); - phase("after collision rejection; before second desired clone"); + let source = authored(&bundle); + let failure = match source.plan_rename(&desired) { + Ok(_) => panic!("colliding rename accepted"), + Err(failure) => failure, + }; + assert_eq!(failure.diagnostics.len(), 1); + assert_eq!( + failure.diagnostics[0].diagnostic.message, + "Rename aliases collide in their final namespace." + ); + drop(failure); + drop(desired); + let mut desired = original.clone(); calculation(&mut desired, 2).body = a::Binding::Unbound; - phase("before semantic rejection"); - rejected(&bundle, &desired, "non-name"); - phase("after semantic rejection; before iteration drop"); + let source = authored(&bundle); + let failure = match source.plan_rename(&desired) { + Ok(_) => panic!("non-name mutation accepted"), + Err(failure) => failure, + }; + assert_eq!(failure.diagnostics.len(), 1); + assert_eq!( + failure.diagnostics[0].diagnostic.message, + "Rename target changes non-name project semantics." + ); + drop(failure); + drop(desired); + drop(original); } }) .unwrap() diff --git a/harness/analysis-mixed-rename-plan-implementation-20260924.md b/harness/analysis-mixed-rename-plan-implementation-20260924.md index 68cb0686..686e3439 100644 --- a/harness/analysis-mixed-rename-plan-implementation-20260924.md +++ b/harness/analysis-mixed-rename-plan-implementation-20260924.md @@ -17,3 +17,11 @@ Storage oracle: rich OA B=resolved+65, E15/Q11/R11/M27; added peak38 and retenti Combined-size oracle uses original930 bytes: ordinary31-byte node alias shrinks to1 while three typed f aliases grow to9; complete924 fits although typed-only intermediate954 would not. A12-byte replacement produces933 and must fail under the same inherited930-byte cap, including the untouched213-byte file. This tests planned sizing only, never output correctness. All source/tests require parent compilation, focused runtime tests and existing broader gates. Direct rustfmt is the only executed Rust tool during authoring. Parent owns commit/publication and verification evidence; no Cargo/build/test execution was performed by this implementation agent. + +## Recorded first runtime failure and narrow test repair + +Parent's `9388fcf2` focused run compiled and passed four tests before the 128 KiB deep/wide worker terminated with Windows stack-overflow exit 0xc00000fd. Parent separately ran the remaining 16 tests from that exact original artifact: all passed, explicitly excluding the crashing test. This is not a 17-test acceptance result. + +Diagnostic source `9e8e77e1` established that deep admission, whole original clone, rename success and successful plan drop completed; failure followed entry into the collision-rejection helper. Diagnostic source `8159a17d` further located the overflow inside that helper's `authored(bundle)` call: its flushed before-admission marker appeared, but its after-admission/before-plan marker did not. Thus that failing helper invocation had not entered rename planning. These observations do not prove a particular compiler frame size or establish model cloning as the cause. + +The bounded repair removes diagnostic markers and restores the general helper. Only this small-stack test directly creates each fresh owner at worker scope and matches each planning result there. It still uses 128 KiB, deep 128 and wide 129 expression nodes, complete admission on the worker, success/plan-drop, late final-namespace collision/refusal-drop and non-name semantic refusal/drop for both shapes. Prior plan, diagnostic and desired owners are explicitly dropped before subsequent cases. No fixture depth/width or stack allowance is weakened; no production code changes. The repaired full 17-test focused run and broader gates remain parent-owned and pending.