@@ -1069,8 +1069,7 @@ impl<'a> Context<'a> {
1069
1069
// Ensure that array id is fully resolved.
1070
1070
let array = dfg. resolve ( array) ;
1071
1071
1072
- let array_id = dfg. resolve ( array) ;
1073
- let array_typ = dfg. type_of_value ( array_id) ;
1072
+ let array_typ = dfg. type_of_value ( array) ;
1074
1073
// Compiler sanity checks
1075
1074
assert ! ( !array_typ. is_nested_slice( ) , "ICE: Nested slice type has reached ACIR generation" ) ;
1076
1075
let ( Type :: Array ( _, _) | Type :: Slice ( _) ) = & array_typ else {
@@ -1125,15 +1124,7 @@ impl<'a> Context<'a> {
1125
1124
index : ValueId ,
1126
1125
store_value : Option < ValueId > ,
1127
1126
) -> Result < bool , RuntimeError > {
1128
- let array_id = dfg. resolve ( array) ;
1129
- let array_typ = dfg. type_of_value ( array_id) ;
1130
- // Compiler sanity checks
1131
- assert ! ( !array_typ. is_nested_slice( ) , "ICE: Nested slice type has reached ACIR generation" ) ;
1132
- let ( Type :: Array ( _, _) | Type :: Slice ( _) ) = & array_typ else {
1133
- unreachable ! ( "ICE: expected array or slice type" ) ;
1134
- } ;
1135
-
1136
- match self . convert_value ( array_id, dfg) {
1127
+ match self . convert_value ( array, dfg) {
1137
1128
AcirValue :: Var ( acir_var, _) => {
1138
1129
Err ( RuntimeError :: InternalError ( InternalError :: Unexpected {
1139
1130
expected : "an array value" . to_string ( ) ,
@@ -2231,45 +2222,41 @@ impl<'a> Context<'a> {
2231
2222
Intrinsic :: AsSlice => {
2232
2223
let slice_contents = arguments[ 0 ] ;
2233
2224
let slice_typ = dfg. type_of_value ( slice_contents) ;
2234
- let block_id = self . ensure_array_is_initialized ( slice_contents, dfg) ?;
2235
2225
assert ! ( !slice_typ. is_nested_slice( ) , "ICE: Nested slice used in ACIR generation" ) ;
2236
2226
2237
- let result_block_id = self . block_id ( & result_ids[ 1 ] ) ;
2238
2227
let acir_value = self . convert_value ( slice_contents, dfg) ;
2228
+ let ( slice_length, result) = match acir_value {
2229
+ AcirValue :: Var ( _, _) => {
2230
+ unreachable ! ( "ICE: cannot call `as_slice` on non-array type" )
2231
+ }
2232
+ array @ AcirValue :: Array ( _) => {
2233
+ let array_len = if !slice_typ. contains_slice_element ( ) {
2234
+ slice_typ. flattened_size ( ) as usize
2235
+ } else {
2236
+ self . flattened_slice_size ( slice_contents, dfg)
2237
+ } ;
2238
+ ( array_len, array)
2239
+ }
2240
+ AcirValue :: DynamicArray ( source_array) => {
2241
+ let result_block_id = self . block_id ( & result_ids[ 1 ] ) ;
2242
+ self . copy_dynamic_array (
2243
+ source_array. block_id ,
2244
+ result_block_id,
2245
+ source_array. len ,
2246
+ ) ?;
2239
2247
2240
- let array_len = if !slice_typ. contains_slice_element ( ) {
2241
- slice_typ. flattened_size ( ) as usize
2242
- } else {
2243
- self . flattened_slice_size ( slice_contents, dfg)
2244
- } ;
2245
- let slice_length = self . acir_context . add_constant ( array_len) ;
2246
- self . copy_dynamic_array ( block_id, result_block_id, array_len) ?;
2248
+ let array = AcirValue :: DynamicArray ( AcirDynamicArray {
2249
+ block_id : result_block_id,
2250
+ len : source_array. len ,
2251
+ value_types : source_array. value_types ,
2252
+ element_type_sizes : source_array. element_type_sizes ,
2253
+ } ) ;
2247
2254
2248
- let element_type_sizes = if !can_omit_element_sizes_array ( & slice_typ) {
2249
- Some ( self . init_element_type_sizes_array (
2250
- & slice_typ,
2251
- slice_contents,
2252
- Some ( & acir_value) ,
2253
- dfg,
2254
- ) ?)
2255
- } else {
2256
- None
2255
+ ( source_array. len , array)
2256
+ }
2257
2257
} ;
2258
2258
2259
- let value_types = self . convert_value ( slice_contents, dfg) . flat_numeric_types ( ) ;
2260
- assert ! (
2261
- array_len == value_types. len( ) ,
2262
- "AsSlice: unexpected length difference: {:?} != {:?}" ,
2263
- array_len,
2264
- value_types. len( )
2265
- ) ;
2266
-
2267
- let result = AcirValue :: DynamicArray ( AcirDynamicArray {
2268
- block_id : result_block_id,
2269
- len : value_types. len ( ) ,
2270
- value_types,
2271
- element_type_sizes,
2272
- } ) ;
2259
+ let slice_length = self . acir_context . add_constant ( slice_length) ;
2273
2260
Ok ( vec ! [ AcirValue :: Var ( slice_length, AcirType :: field( ) ) , result] )
2274
2261
}
2275
2262
Intrinsic :: SlicePushBack => {
@@ -3709,4 +3696,35 @@ mod test {
3709
3696
}
3710
3697
}
3711
3698
}
3699
+
3700
+ #[ test]
3701
+ fn does_not_generate_memory_blocks_without_dynamic_accesses ( ) {
3702
+ let src = "
3703
+ acir(inline) fn main f0 {
3704
+ b0(v0: [Field; 2]):
3705
+ v2, v3 = call as_slice(v0) -> (u32, [Field])
3706
+ call f1(u32 2, v3)
3707
+ v7 = array_get v0, index u32 0 -> Field
3708
+ constrain v7 == Field 0
3709
+ return
3710
+ }
3711
+
3712
+ brillig(inline) fn foo f1 {
3713
+ b0(v0: u32, v1: [Field]):
3714
+ return
3715
+ }
3716
+ " ;
3717
+ let ssa = Ssa :: from_str ( src) . unwrap ( ) ;
3718
+ let brillig = ssa. to_brillig ( false ) ;
3719
+
3720
+ let ( acir_functions, _brillig_functions, _, _) = ssa
3721
+ . into_acir ( & brillig, ExpressionWidth :: default ( ) )
3722
+ . expect ( "Should compile manually written SSA into ACIR" ) ;
3723
+
3724
+ assert_eq ! ( acir_functions. len( ) , 1 ) ;
3725
+
3726
+ // Check that no memory opcodes were emitted.
3727
+ let main = & acir_functions[ 0 ] ;
3728
+ assert ! ( !main. opcodes( ) . iter( ) . any( |opcode| matches!( opcode, Opcode :: MemoryOp { .. } ) ) ) ;
3729
+ }
3712
3730
}
0 commit comments