11use std:: { collections:: HashMap , ops:: Deref } ;
22
3- use air_parser:: ast:: AccessType ;
3+ use air_parser:: ast:: { AccessType , RangeExpr , RangeBound } ;
44use air_pass:: Pass ;
55use miden_diagnostics:: { DiagnosticsHandler , Severity , SourceSpan , Spanned } ;
66
@@ -496,7 +496,7 @@ impl Visitor for InliningSecondPass<'_> {
496496fn check_evaluator_argument_sizes (
497497 args : & [ Link < Op > ] ,
498498 callee_params : Vec < Vec < Link < Op > > > ,
499- diagnostics : & DiagnosticsHandler ,
499+ _diagnostics : & DiagnosticsHandler ,
500500) -> Result < ( ) , CompileError > {
501501 for ( ( trace_segment_id, trace_segments_params) , trace_segments_arg) in
502502 callee_params. iter ( ) . enumerate ( ) . zip ( args. iter ( ) )
@@ -565,6 +565,16 @@ fn check_evaluator_argument_sizes(
565565 ) ;
566566 }
567567 } ,
568+ AccessType :: Slice ( range_expr) => {
569+ // Slice access - calculate the size from the range
570+ match calculate_slice_size ( range_expr) {
571+ Ok ( size) => trace_segments_arg_vector_len += size,
572+ Err ( _) => {
573+ // TODO: Add proper diagnostic for non-constant range bounds
574+ return Err ( CompileError :: Failed ) ;
575+ }
576+ }
577+ } ,
568578 _ => {
569579 // Other access types - fallback to 1
570580 trace_segments_arg_vector_len += 1 ;
@@ -576,33 +586,45 @@ fn check_evaluator_argument_sizes(
576586 }
577587
578588 if trace_segments_params. len ( ) != trace_segments_arg_vector_len {
579- diagnostics
580- . diagnostic ( Severity :: Error )
581- . with_message ( "argument count mismatch" )
582- . with_primary_label (
583- SourceSpan :: UNKNOWN ,
584- format ! (
585- "expected call to have {} arguments in trace segment {}, but got {}" ,
586- trace_segments_params. len( ) ,
587- trace_segment_id,
588- trace_segments_arg_vector_len
589- ) ,
590- )
591- . with_secondary_label (
592- SourceSpan :: UNKNOWN ,
593- format ! (
594- "this functions has {} parameters in trace segment {}" ,
595- trace_segments_params. len( ) ,
596- trace_segment_id
597- ) ,
598- )
589+ _diagnostics. diagnostic ( miden_diagnostics:: Severity :: Error )
590+ . with_message ( & format ! ( "Argument count mismatch in trace segment {}" , trace_segment_id) )
591+ . with_primary_label ( trace_segments_arg. span ( ) ,
592+ & format ! ( "expected {} arguments, got {}" ,
593+ trace_segments_params. len( ) ,
594+ trace_segments_arg_vector_len) )
599595 . emit ( ) ;
600596 return Err ( CompileError :: Failed ) ;
601597 }
602598 }
603599 Ok ( ( ) )
604600}
605601
602+ /// Calculate the size of a slice from a RangeExpr
603+ /// For example: [0..5] returns 5 (5 - 0 = 5)
604+ /// Returns an error for non-constant bounds that cannot be resolved at compile time
605+ fn calculate_slice_size ( range_expr : & RangeExpr ) -> Result < usize , CompileError > {
606+ let start = match & range_expr. start {
607+ RangeBound :: Const ( spanned) => spanned. item ,
608+ RangeBound :: SymbolAccess ( _) => {
609+ // For non-constant bounds, we can't determine the size at compile time
610+ // TODO: Implement constant resolution for SymbolAccess
611+ return Err ( CompileError :: Failed ) ;
612+ }
613+ } ;
614+
615+ let end = match & range_expr. end {
616+ RangeBound :: Const ( spanned) => spanned. item ,
617+ RangeBound :: SymbolAccess ( _) => {
618+ // For non-constant bounds, we can't determine the size at compile time
619+ // TODO: Implement constant resolution for SymbolAccess
620+ return Err ( CompileError :: Failed ) ;
621+ }
622+ } ;
623+
624+ // Range is exclusive at the end, so size = end - start
625+ Ok ( end - start)
626+ }
627+
606628/// Helper function to unpack the arguments of a call to an evaluator
607629fn unpack_evaluator_arguments ( args : & [ Link < Op > ] ) -> Vec < Link < Op > > {
608630 let mut args_unpacked = Vec :: new ( ) ;
@@ -649,9 +671,34 @@ fn unpack_evaluator_arguments(args: &[Link<Op>]) -> Vec<Link<Op>> {
649671 } else if let Some ( _parameter) = arg. as_parameter ( ) {
650672 args_unpacked. push ( arg. clone ( ) ) ;
651673 } else if let Some ( accessor) = arg. as_accessor ( ) {
652- let Accessor { indexable, .. } = accessor. deref ( ) ;
674+ let Accessor { indexable, access_type , .. } = accessor. deref ( ) ;
653675
654- if let Some ( value) = indexable. as_value ( ) {
676+ // Handle Slice access type specifically
677+ if let AccessType :: Slice ( range_expr) = access_type {
678+ // Slice access - expand the slice elements from the underlying vector
679+ if let Some ( vector) = indexable. as_vector ( ) {
680+ let start = match & range_expr. start {
681+ RangeBound :: Const ( spanned) => spanned. item ,
682+ _ => 0 , // fallback for non-constant start
683+ } ;
684+ let end = match & range_expr. end {
685+ RangeBound :: Const ( spanned) => spanned. item ,
686+ _ => vector. children ( ) . borrow ( ) . len ( ) , // fallback for non-constant end
687+ } ;
688+
689+ // Extract the slice elements
690+ let children = vector. children ( ) ;
691+ let borrowed_children = children. borrow ( ) ;
692+ for i in start..end. min ( borrowed_children. len ( ) ) {
693+ if let Some ( child) = borrowed_children. get ( i) {
694+ args_unpacked. push ( child. clone ( ) ) ;
695+ }
696+ }
697+ } else {
698+ // For non-vector indexable, fallback to push the accessor as-is
699+ args_unpacked. push ( arg. clone ( ) ) ;
700+ }
701+ } else if let Some ( value) = indexable. as_value ( ) {
655702 let Value { value : SpannedMirValue { value, .. } , .. } = value. deref ( ) ;
656703
657704 let _param_size = match value {
@@ -675,9 +722,13 @@ fn unpack_evaluator_arguments(args: &[Link<Op>]) -> Vec<Link<Op>> {
675722 for child in vector. children ( ) . borrow ( ) . iter ( ) {
676723 args_unpacked. push ( child. clone ( ) ) ;
677724 }
725+ } else if let Some ( _inner_accessor) = indexable. as_accessor ( ) {
726+ // Handle nested accessors by pushing the indexable itself
727+ // This preserves the existing node structure
728+ args_unpacked. push ( indexable. clone ( ) ) ;
678729 } else {
679730 unreachable ! (
680- "expected value, parameter, or vector (or accessor on one), got {:?}" ,
731+ "expected value, parameter, vector, or nested accessor (or accessor on one), got {:?}" ,
681732 arg
682733 ) ;
683734 }
0 commit comments