diff --git a/rust/kcl-lib/src/execution/exec_ast.rs b/rust/kcl-lib/src/execution/exec_ast.rs index edb71d59b07..86ee1691fd5 100644 --- a/rust/kcl-lib/src/execution/exec_ast.rs +++ b/rust/kcl-lib/src/execution/exec_ast.rs @@ -1485,10 +1485,12 @@ pub(crate) async fn execute_pipe_body( // should use the previous child expression for %. // This means there's no more need for the previous pipe_value from the parent AST node above this one. let previous_pipe_value = exec_state.mod_local.pipe_value.replace(output); + let previous_pipe_size = exec_state.mod_local.pipe_size.replace(body.len()); // Evaluate remaining elements. let result = inner_execute_pipe_body(exec_state, body, ctx).await; // Restore the previous pipe value. exec_state.mod_local.pipe_value = previous_pipe_value; + exec_state.mod_local.pipe_size = previous_pipe_size; result } diff --git a/rust/kcl-lib/src/execution/state.rs b/rust/kcl-lib/src/execution/state.rs index 31cb559d61b..9feb7092e07 100644 --- a/rust/kcl-lib/src/execution/state.rs +++ b/rust/kcl-lib/src/execution/state.rs @@ -94,6 +94,8 @@ pub(super) struct ModuleState { /// The current value of the pipe operator returned from the previous /// expression. If we're not currently in a pipeline, this will be None. pub pipe_value: Option, + /// How many pipes are in the pipeline. + pub pipe_size: Option, /// The closest variable declaration being executed in any parent node in the AST. /// This is used to provide better error messages, e.g. noticing when the user is trying /// to use the variable `length` inside the RHS of its own definition, like `length = tan(length)`. @@ -299,6 +301,10 @@ impl ExecState { self.mod_local.pipe_value.as_ref() } + pub(crate) fn pipe_size(&self) -> Option { + self.mod_local.pipe_size + } + pub(crate) fn error_with_outputs( &self, error: KclError, @@ -482,6 +488,7 @@ impl ModuleState { id_generator: IdGenerator::new(module_id), stack: memory.new_stack(), pipe_value: Default::default(), + pipe_size: Default::default(), being_declared: Default::default(), module_exports: Default::default(), explicit_length_units: false, diff --git a/rust/kcl-lib/src/std/sketch.rs b/rust/kcl-lib/src/std/sketch.rs index a6ba682f6df..d6da5c1a9a3 100644 --- a/rust/kcl-lib/src/std/sketch.rs +++ b/rust/kcl-lib/src/std/sketch.rs @@ -974,6 +974,7 @@ pub(crate) async fn inner_start_profile( _ => {} } + let heuristic_num_paths = exec_state.pipe_size().unwrap_or(1); let enable_sketch_id = exec_state.next_uuid(); let path_id = exec_state.next_uuid(); let move_pen_id = exec_state.next_uuid(); @@ -1038,7 +1039,7 @@ pub(crate) async fn inner_start_profile( original_id: path_id, artifact_id: path_id.into(), on: sketch_surface.clone(), - paths: vec![], + paths: Vec::with_capacity(heuristic_num_paths), inner_paths: vec![], units, mirror: Default::default(),