| ... | ... | @@ -1579,6 +1579,8 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1579 | 1579 | const target = sema.mod.getTarget(); |
| 1580 | 1580 | const addr_space = target_util.defaultAddressSpace(target, .local); |
| 1581 | 1581 | |
| 1582 | try sema.resolveTypeLayout(block, src, pointee_ty); |
| 1583 | |
| 1582 | 1584 | if (Air.refToIndex(ptr)) |ptr_inst| { |
| 1583 | 1585 | if (sema.air_instructions.items(.tag)[ptr_inst] == .constant) { |
| 1584 | 1586 | const air_datas = sema.air_instructions.items(.data); |
| ... | ... | @@ -1885,6 +1887,7 @@ fn zirEnumDecl( |
| 1885 | 1887 | enum_obj.* = .{ |
| 1886 | 1888 | .owner_decl = new_decl, |
| 1887 | 1889 | .tag_ty = Type.initTag(.@"null"), |
| 1890 | .tag_ty_inferred = true, |
| 1888 | 1891 | .fields = .{}, |
| 1889 | 1892 | .values = .{}, |
| 1890 | 1893 | .node_offset = src.node_offset, |
| ... | ... | @@ -1907,6 +1910,7 @@ fn zirEnumDecl( |
| 1907 | 1910 | // TODO better source location |
| 1908 | 1911 | const ty = try sema.resolveType(block, src, tag_type_ref); |
| 1909 | 1912 | enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); |
| 1913 | enum_obj.tag_ty_inferred = false; |
| 1910 | 1914 | } |
| 1911 | 1915 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 1912 | 1916 | return sema.analyzeDeclVal(block, src, new_decl); |
| ... | ... | @@ -1956,16 +1960,16 @@ fn zirEnumDecl( |
| 1956 | 1960 | |
| 1957 | 1961 | try wip_captures.finalize(); |
| 1958 | 1962 | |
| 1959 | | const tag_ty = blk: { |
| 1960 | | if (tag_type_ref != .none) { |
| 1961 | | // TODO better source location |
| 1962 | | const ty = try sema.resolveType(block, src, tag_type_ref); |
| 1963 | | break :blk try ty.copy(new_decl_arena_allocator); |
| 1964 | | } |
| 1963 | if (tag_type_ref != .none) { |
| 1964 | // TODO better source location |
| 1965 | const ty = try sema.resolveType(block, src, tag_type_ref); |
| 1966 | enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); |
| 1967 | enum_obj.tag_ty_inferred = false; |
| 1968 | } else { |
| 1965 | 1969 | const bits = std.math.log2_int_ceil(usize, fields_len); |
| 1966 | | break :blk try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits); |
| 1967 | | }; |
| 1968 | | enum_obj.tag_ty = tag_ty; |
| 1970 | enum_obj.tag_ty = try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits); |
| 1971 | enum_obj.tag_ty_inferred = true; |
| 1972 | } |
| 1969 | 1973 | } |
| 1970 | 1974 | |
| 1971 | 1975 | try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len); |
| ... | ... | @@ -2417,13 +2421,13 @@ fn zirAllocExtended( |
| 2417 | 2421 | try sema.validateVarType(block, ty_src, var_ty, false); |
| 2418 | 2422 | } |
| 2419 | 2423 | const target = sema.mod.getTarget(); |
| 2424 | try sema.requireRuntimeBlock(block, src); |
| 2425 | try sema.resolveTypeLayout(block, src, var_ty); |
| 2420 | 2426 | const ptr_type = try Type.ptr(sema.arena, target, .{ |
| 2421 | 2427 | .pointee_type = var_ty, |
| 2422 | 2428 | .@"align" = alignment, |
| 2423 | 2429 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 2424 | 2430 | }); |
| 2425 | | try sema.requireRuntimeBlock(block, src); |
| 2426 | | try sema.resolveTypeLayout(block, src, var_ty); |
| 2427 | 2431 | return block.addTy(.alloc, ptr_type); |
| 2428 | 2432 | } |
| 2429 | 2433 | |
| ... | ... | @@ -21209,6 +21213,182 @@ fn typePtrOrOptionalPtrTy( |
| 21209 | 21213 | } |
| 21210 | 21214 | } |
| 21211 | 21215 | |
| 21216 | fn typeHasWellDefinedLayout(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 21217 | return switch (ty.tag()) { |
| 21218 | .u1, |
| 21219 | .u8, |
| 21220 | .i8, |
| 21221 | .u16, |
| 21222 | .i16, |
| 21223 | .u32, |
| 21224 | .i32, |
| 21225 | .u64, |
| 21226 | .i64, |
| 21227 | .u128, |
| 21228 | .i128, |
| 21229 | .usize, |
| 21230 | .isize, |
| 21231 | .c_short, |
| 21232 | .c_ushort, |
| 21233 | .c_int, |
| 21234 | .c_uint, |
| 21235 | .c_long, |
| 21236 | .c_ulong, |
| 21237 | .c_longlong, |
| 21238 | .c_ulonglong, |
| 21239 | .c_longdouble, |
| 21240 | .f16, |
| 21241 | .f32, |
| 21242 | .f64, |
| 21243 | .f80, |
| 21244 | .f128, |
| 21245 | .bool, |
| 21246 | .void, |
| 21247 | .manyptr_u8, |
| 21248 | .manyptr_const_u8, |
| 21249 | .manyptr_const_u8_sentinel_0, |
| 21250 | .anyerror_void_error_union, |
| 21251 | .empty_struct_literal, |
| 21252 | .empty_struct, |
| 21253 | .array_u8, |
| 21254 | .array_u8_sentinel_0, |
| 21255 | .int_signed, |
| 21256 | .int_unsigned, |
| 21257 | .pointer, |
| 21258 | .single_const_pointer, |
| 21259 | .single_mut_pointer, |
| 21260 | .many_const_pointer, |
| 21261 | .many_mut_pointer, |
| 21262 | .c_const_pointer, |
| 21263 | .c_mut_pointer, |
| 21264 | .single_const_pointer_to_comptime_int, |
| 21265 | .enum_numbered, |
| 21266 | => true, |
| 21267 | |
| 21268 | .anyopaque, |
| 21269 | .anyerror, |
| 21270 | .noreturn, |
| 21271 | .@"null", |
| 21272 | .@"anyframe", |
| 21273 | .@"undefined", |
| 21274 | .atomic_order, |
| 21275 | .atomic_rmw_op, |
| 21276 | .calling_convention, |
| 21277 | .address_space, |
| 21278 | .float_mode, |
| 21279 | .reduce_op, |
| 21280 | .call_options, |
| 21281 | .prefetch_options, |
| 21282 | .export_options, |
| 21283 | .extern_options, |
| 21284 | .error_set, |
| 21285 | .error_set_single, |
| 21286 | .error_set_inferred, |
| 21287 | .error_set_merged, |
| 21288 | .@"opaque", |
| 21289 | .generic_poison, |
| 21290 | .type, |
| 21291 | .comptime_int, |
| 21292 | .comptime_float, |
| 21293 | .enum_literal, |
| 21294 | .type_info, |
| 21295 | // These are function bodies, not function pointers. |
| 21296 | .fn_noreturn_no_args, |
| 21297 | .fn_void_no_args, |
| 21298 | .fn_naked_noreturn_no_args, |
| 21299 | .fn_ccc_void_no_args, |
| 21300 | .function, |
| 21301 | .const_slice_u8, |
| 21302 | .const_slice_u8_sentinel_0, |
| 21303 | .const_slice, |
| 21304 | .mut_slice, |
| 21305 | .enum_simple, |
| 21306 | .error_union, |
| 21307 | .anyframe_T, |
| 21308 | .tuple, |
| 21309 | .anon_struct, |
| 21310 | => false, |
| 21311 | |
| 21312 | .enum_full, |
| 21313 | .enum_nonexhaustive, |
| 21314 | => !ty.cast(Type.Payload.EnumFull).?.data.tag_ty_inferred, |
| 21315 | |
| 21316 | .var_args_param => unreachable, |
| 21317 | .inferred_alloc_mut => unreachable, |
| 21318 | .inferred_alloc_const => unreachable, |
| 21319 | .bound_fn => unreachable, |
| 21320 | |
| 21321 | .array, |
| 21322 | .array_sentinel, |
| 21323 | .vector, |
| 21324 | => sema.typeHasWellDefinedLayout(block, src, ty.childType()), |
| 21325 | |
| 21326 | .optional, |
| 21327 | .optional_single_mut_pointer, |
| 21328 | .optional_single_const_pointer, |
| 21329 | => blk: { |
| 21330 | var buf: Type.Payload.ElemType = undefined; |
| 21331 | break :blk sema.typeHasWellDefinedLayout(block, src, ty.optionalChild(&buf)); |
| 21332 | }, |
| 21333 | |
| 21334 | .@"struct" => { |
| 21335 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 21336 | if (struct_obj.layout == .Auto) { |
| 21337 | struct_obj.has_well_defined_layout = .no; |
| 21338 | return false; |
| 21339 | } |
| 21340 | switch (struct_obj.has_well_defined_layout) { |
| 21341 | .no => return false, |
| 21342 | .yes, .wip => return true, |
| 21343 | .unknown => { |
| 21344 | if (struct_obj.status == .field_types_wip) |
| 21345 | return true; |
| 21346 | |
| 21347 | try sema.resolveTypeFieldsStruct(block, src, ty, struct_obj); |
| 21348 | |
| 21349 | struct_obj.has_well_defined_layout = .wip; |
| 21350 | for (struct_obj.fields.values()) |field| { |
| 21351 | if (!(try sema.typeHasWellDefinedLayout(block, src, field.ty))) { |
| 21352 | struct_obj.has_well_defined_layout = .no; |
| 21353 | return false; |
| 21354 | } |
| 21355 | } |
| 21356 | struct_obj.has_well_defined_layout = .yes; |
| 21357 | return true; |
| 21358 | }, |
| 21359 | } |
| 21360 | }, |
| 21361 | |
| 21362 | .@"union", .union_tagged => { |
| 21363 | const union_obj = ty.cast(Type.Payload.Union).?.data; |
| 21364 | if (union_obj.layout == .Auto) { |
| 21365 | union_obj.has_well_defined_layout = .no; |
| 21366 | return false; |
| 21367 | } |
| 21368 | switch (union_obj.has_well_defined_layout) { |
| 21369 | .no => return false, |
| 21370 | .yes, .wip => return true, |
| 21371 | .unknown => { |
| 21372 | if (union_obj.status == .field_types_wip) |
| 21373 | return true; |
| 21374 | |
| 21375 | try sema.resolveTypeFieldsUnion(block, src, ty, union_obj); |
| 21376 | |
| 21377 | union_obj.has_well_defined_layout = .wip; |
| 21378 | for (union_obj.fields.values()) |field| { |
| 21379 | if (!(try sema.typeHasWellDefinedLayout(block, src, field.ty))) { |
| 21380 | union_obj.has_well_defined_layout = .no; |
| 21381 | return false; |
| 21382 | } |
| 21383 | } |
| 21384 | union_obj.has_well_defined_layout = .yes; |
| 21385 | return true; |
| 21386 | }, |
| 21387 | } |
| 21388 | }, |
| 21389 | }; |
| 21390 | } |
| 21391 | |
| 21212 | 21392 | /// `generic_poison` will return false. |
| 21213 | 21393 | /// This function returns false negatives when structs and unions are having their |
| 21214 | 21394 | /// field types resolved. |
| ... | ... | @@ -21412,6 +21592,12 @@ pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 21412 | 21592 | return true; |
| 21413 | 21593 | } |
| 21414 | 21594 | |
| 21595 | fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 { |
| 21596 | try sema.resolveTypeLayout(block, src, ty); |
| 21597 | const target = sema.mod.getTarget(); |
| 21598 | return ty.abiSize(target); |
| 21599 | } |
| 21600 | |
| 21415 | 21601 | fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 { |
| 21416 | 21602 | try sema.resolveTypeLayout(block, src, ty); |
| 21417 | 21603 | const target = sema.mod.getTarget(); |