@@ -6298,6 +6298,35 @@ pub const ReferencedType = struct {
6298
6298
};
6299
6299
};
6300
6300
6301
+ const ArrayLike = struct {
6302
+ len : u64 ,
6303
+ /// `noreturn` indicates that this type is `struct{}` so can coerce to anything
6304
+ elem_ty : Type ,
6305
+ };
6306
+ fn arrayLikeFromStruct (analyser : * Analyser , ty : Type ) ? ArrayLike {
6307
+ std .debug .assert (ty .is_type_val );
6308
+ return switch (ty .zigTypeTag (analyser ).? ) {
6309
+ .@"struct" = > {
6310
+ if (ty .isNamespace ()) return .{
6311
+ .len = 0 ,
6312
+ .elem_ty = Type .fromIP (analyser , .type_type , .noreturn_type ),
6313
+ };
6314
+ if (ty .data != .tuple ) return null ;
6315
+ const elem_ty = ty .data .tuple [0 ];
6316
+ for (ty .data .tuple [1.. ]) | field_ty | {
6317
+ if (! field_ty .eql (elem_ty )) {
6318
+ return null ;
6319
+ }
6320
+ }
6321
+ return .{
6322
+ .len = ty .data .tuple .len ,
6323
+ .elem_ty = elem_ty ,
6324
+ };
6325
+ },
6326
+ else = > null ,
6327
+ };
6328
+ }
6329
+
6301
6330
// Based on src/Sema.zig from the zig codebase
6302
6331
// https://github.com/ziglang/zig/blob/master/src/Sema.zig
6303
6332
fn resolvePeerTypesInner (analyser : * Analyser , peer_tys : []? Type ) ! ? Type {
@@ -6423,7 +6452,78 @@ fn resolvePeerTypesInner(analyser: *Analyser, peer_tys: []?Type) !?Type {
6423
6452
};
6424
6453
},
6425
6454
6426
- .array = > return null , // TODO
6455
+ .array = > {
6456
+ var len : ? u64 = null ;
6457
+ var sentinel : InternPool.Index = .none ;
6458
+ var elem_ty : ? Type = null ;
6459
+
6460
+ for (peer_tys ) | * ty_ptr | {
6461
+ const ty = ty_ptr .* orelse continue ;
6462
+
6463
+ if (ty .data != .array ) {
6464
+ const arr_like = analyser .arrayLikeFromStruct (ty ) orelse {
6465
+ return null ;
6466
+ };
6467
+
6468
+ if (len ) | cur_len | {
6469
+ if (arr_like .len != cur_len ) return null ;
6470
+ } else {
6471
+ len = arr_like .len ;
6472
+ }
6473
+
6474
+ sentinel = .none ;
6475
+
6476
+ continue ;
6477
+ }
6478
+
6479
+ const arr_info = ty .data .array ;
6480
+ const arr_len = arr_info .elem_count orelse {
6481
+ return null ;
6482
+ };
6483
+
6484
+ const cur_elem_ty = elem_ty orelse {
6485
+ if (len ) | cur_len | {
6486
+ if (arr_len != cur_len ) return null ;
6487
+ } else {
6488
+ len = arr_len ;
6489
+ sentinel = arr_info .sentinel ;
6490
+ }
6491
+ elem_ty = arr_info .elem_ty .* ;
6492
+ continue ;
6493
+ };
6494
+
6495
+ if (arr_info .elem_count != len ) {
6496
+ return null ;
6497
+ }
6498
+
6499
+ const peer_elem_ty = arr_info .elem_ty .* ;
6500
+ if (! peer_elem_ty .eql (cur_elem_ty )) {
6501
+ // TODO: check if coercible
6502
+ return null ;
6503
+ }
6504
+
6505
+ if (sentinel != .none ) {
6506
+ if (arr_info .sentinel != .none ) {
6507
+ if (arr_info .sentinel != sentinel ) sentinel = .none ;
6508
+ } else {
6509
+ sentinel = .none ;
6510
+ }
6511
+ }
6512
+ }
6513
+
6514
+ std .debug .assert (elem_ty != null );
6515
+
6516
+ return .{
6517
+ .data = .{
6518
+ .array = .{
6519
+ .elem_count = len ,
6520
+ .sentinel = sentinel ,
6521
+ .elem_ty = try analyser .allocType (elem_ty .? ),
6522
+ },
6523
+ },
6524
+ .is_type_val = true ,
6525
+ };
6526
+ },
6427
6527
6428
6528
.vector = > return null , // TODO
6429
6529
0 commit comments