@@ -1221,6 +1221,75 @@ let test_tail_call_cross_program_type_restriction _ =
12211221 true (contains_substr msg "incompatible program type")
12221222 | _ -> failwith "Expected TypeError for cross-program-type tail call")
12231223
1224+ (** Test map index type resolution bug fix - structs, enums, and type aliases as map keys *)
1225+ let test_map_index_type_resolution_bug_fix _ =
1226+ let source_code = {|
1227+ // Type alias
1228+ type IpAddress = u32
1229+ type Counter = u64
1230+
1231+ // Enum type
1232+ enum Protocol {
1233+ TCP = 6,
1234+ UDP = 17,
1235+ ICMP = 1
1236+ }
1237+
1238+ // Struct type
1239+ struct PacketInfo {
1240+ src_ip: IpAddress,
1241+ dst_ip: IpAddress,
1242+ protocol: u8
1243+ }
1244+
1245+ // Maps using different key types
1246+ map<IpAddress, Counter> connection_count : HashMap(1024) // Type alias key
1247+ map<Protocol, Counter> protocol_stats : PercpuArray(32) // Enum key
1248+ map<PacketInfo, u32> packet_filter : LruHash(512) // Struct key
1249+
1250+ @helper
1251+ fn test_indexing() -> u32 {
1252+ // Create test values
1253+ var ip: IpAddress = 0xC0A80001
1254+ var proto = TCP
1255+ var info = PacketInfo { src_ip: ip, dst_ip: ip, protocol: 6 }
1256+
1257+ // These should all work without "Array index must be integer type" error
1258+ var count1 = connection_count[ip] // Type alias as key
1259+ var count2 = protocol_stats[proto] // Enum as key
1260+ var result = packet_filter[info] // Struct as key
1261+
1262+ if (count1 != none && count2 != none && result != none) {
1263+ return count1 + count2 + result
1264+ } else {
1265+ return 0
1266+ }
1267+ }
1268+
1269+ @xdp fn packet_handler(ctx: *xdp_md) -> xdp_action {
1270+ return XDP_PASS
1271+ }
1272+ |} in
1273+
1274+ try
1275+ let ast = parse_string source_code in
1276+ let symbol_table = Test_utils.Helpers.create_test_symbol_table ast in
1277+ let _typed_ast = type_check_and_annotate_ast ~symbol_table:(Some symbol_table) ast in
1278+
1279+ (* If we reach here, type checking succeeded *)
1280+ check bool "map index type resolution works for structs, enums, and type aliases" true true
1281+ with
1282+ | Type_error (msg, _) when String.contains msg 'A' && String.contains msg 'r' && String.contains msg 'i' ->
1283+ (* If we get "Array index must be integer type" error, the test fails *)
1284+ fail ("Bug regression - map indexing should work with user types: " ^ msg)
1285+ | Type_error (msg, _) ->
1286+ (* Other type errors might be valid (e.g., map key type mismatches) *)
1287+ fail ("Unexpected type error: " ^ msg)
1288+ | Parse_error (msg, _) ->
1289+ fail ("Parse error: " ^ msg)
1290+ | e ->
1291+ fail ("Unexpected error: " ^ Printexc.to_string e)
1292+
12241293let type_checker_tests = [
12251294 "type_unification", `Quick, test_type_unification;
12261295 "basic_type_inference", `Quick, test_basic_type_inference;
@@ -1258,6 +1327,7 @@ let type_checker_tests = [
12581327 "kernel_to_kernel_function_calls", `Quick, test_kernel_to_kernel_function_calls;
12591328 "function_call_user_type_resolution", `Quick, test_function_call_user_type_resolution;
12601329 "tail_call_cross_program_type_restriction", `Quick, test_tail_call_cross_program_type_restriction;
1330+ "map_index_type_resolution_bug_fix", `Quick, test_map_index_type_resolution_bug_fix;
12611331]
12621332
12631333let () =
0 commit comments