@@ -1732,29 +1732,44 @@ impl<'a> Context<'a> {
1732
1732
) -> Result < Vec < SsaReport > , RuntimeError > {
1733
1733
let ( return_values, call_stack) = match terminator {
1734
1734
TerminatorInstruction :: Return { return_values, call_stack } => {
1735
- ( return_values, call_stack)
1735
+ ( return_values, call_stack. clone ( ) )
1736
1736
}
1737
1737
// TODO(https://github.com/noir-lang/noir/issues/4616): Enable recursion on foldable/non-inlined ACIR functions
1738
1738
_ => unreachable ! ( "ICE: Program must have a singular return" ) ,
1739
1739
} ;
1740
1740
1741
- // The return value may or may not be an array reference. Calling `flatten_value_list`
1742
- // will expand the array if there is one.
1743
- let return_acir_vars = self . flatten_value_list ( return_values, dfg) ?;
1744
- let mut warnings = Vec :: new ( ) ;
1745
- for ( acir_var, is_databus) in return_acir_vars {
1746
- if self . acir_context . is_constant ( & acir_var) {
1747
- warnings. push ( SsaReport :: Warning ( InternalWarning :: ReturnConstant {
1748
- call_stack : call_stack. clone ( ) ,
1749
- } ) ) ;
1750
- }
1751
- if !is_databus {
1752
- // We do not return value for the data bus.
1753
- self . acir_context . return_var ( acir_var) ?;
1754
- } else {
1755
- self . check_array_is_initialized ( self . data_bus . return_data . unwrap ( ) , dfg) ?;
1741
+ let mut has_constant_return = false ;
1742
+ for value_id in return_values {
1743
+ let is_databus = self
1744
+ . data_bus
1745
+ . return_data
1746
+ . map_or ( false , |return_databus| dfg[ * value_id] == dfg[ return_databus] ) ;
1747
+ let value = self . convert_value ( * value_id, dfg) ;
1748
+
1749
+ // `value` may or may not be an array reference. Calling `flatten` will expand the array if there is one.
1750
+ let acir_vars = self . acir_context . flatten ( value) ?;
1751
+ for ( acir_var, _) in acir_vars {
1752
+ has_constant_return |= self . acir_context . is_constant ( & acir_var) ;
1753
+ if is_databus {
1754
+ // We do not return value for the data bus.
1755
+ self . check_array_is_initialized (
1756
+ self . data_bus . return_data . expect (
1757
+ "`is_databus == true` implies `data_bus.return_data` is `Some`" ,
1758
+ ) ,
1759
+ dfg,
1760
+ ) ?;
1761
+ } else {
1762
+ self . acir_context . return_var ( acir_var) ?;
1763
+ }
1756
1764
}
1757
1765
}
1766
+
1767
+ let warnings = if has_constant_return {
1768
+ vec ! [ SsaReport :: Warning ( InternalWarning :: ReturnConstant { call_stack } ) ]
1769
+ } else {
1770
+ Vec :: new ( )
1771
+ } ;
1772
+
1758
1773
Ok ( warnings)
1759
1774
}
1760
1775
@@ -2679,34 +2694,6 @@ impl<'a> Context<'a> {
2679
2694
}
2680
2695
}
2681
2696
2682
- /// Maps an ssa value list, for which some values may be references to arrays, by inlining
2683
- /// the `AcirVar`s corresponding to the contents of each array into the list of `AcirVar`s
2684
- /// that correspond to other values.
2685
- fn flatten_value_list (
2686
- & mut self ,
2687
- arguments : & [ ValueId ] ,
2688
- dfg : & DataFlowGraph ,
2689
- ) -> Result < Vec < ( AcirVar , bool ) > , InternalError > {
2690
- let mut acir_vars = Vec :: with_capacity ( arguments. len ( ) ) ;
2691
- for value_id in arguments {
2692
- let is_databus = if let Some ( return_databus) = self . data_bus . return_data {
2693
- dfg[ * value_id] == dfg[ return_databus]
2694
- } else {
2695
- false
2696
- } ;
2697
- let value = self . convert_value ( * value_id, dfg) ;
2698
- acir_vars. append (
2699
- & mut self
2700
- . acir_context
2701
- . flatten ( value) ?
2702
- . iter ( )
2703
- . map ( |( var, _) | ( * var, is_databus) )
2704
- . collect ( ) ,
2705
- ) ;
2706
- }
2707
- Ok ( acir_vars)
2708
- }
2709
-
2710
2697
/// Convert a Vec<AcirVar> into a Vec<AcirValue> using the given result ids.
2711
2698
/// If the type of a result id is an array, several acir vars are collected into
2712
2699
/// a single AcirValue::Array of the same length.
0 commit comments