authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-23 15:47:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-26 18:05:27+02:00
logd0dd0bda1c8773243f98ac1e073afc32c4ce4cf2
treeb001961e1842919a24d408f6f46438248785a91f
parent72fa8d4880613d88f9f29dd78012b7253729bac7

Sema: resolve requires_comptime as part of resolveTypeLayout

This was already partially done for structs but it needs to be done for Unions too and more thoroughly. Closes #13609

1 files changed, 193 insertions(+), 14 deletions(-)

src/Sema.zig+193-14
...@@ -29126,20 +29126,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29126,20 +29126,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
29126 }29126 }
2912729127
29128 struct_obj.status = .have_layout;29128 struct_obj.status = .have_layout;
2912929129 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29130 // In case of querying the ABI alignment of this struct, we will ask
29131 // for hasRuntimeBits() of each field, so we need "requires comptime"
29132 // to be known already before this function returns.
29133 for (struct_obj.fields.values()) |field, i| {
29134 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
29135 error.AnalysisFail => {
29136 const msg = sema.err orelse return err;
29137 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
29138 return err;
29139 },
29140 else => return err,
29141 };
29142 }
29143 }29130 }
29144 // otherwise it's a tuple; no need to resolve anything29131 // otherwise it's a tuple; no need to resolve anything
29145}29132}
...@@ -29303,6 +29290,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -29303,6 +29290,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
29303 };29290 };
29304 }29291 }
29305 union_obj.status = .have_layout;29292 union_obj.status = .have_layout;
29293 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29294}
29295
29296// In case of querying the ABI alignment of this struct, we will ask
29297// for hasRuntimeBits() of each field, so we need "requires comptime"
29298// to be known already before this function returns.
29299pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
29300 return switch (ty.tag()) {
29301 .u1,
29302 .u8,
29303 .i8,
29304 .u16,
29305 .i16,
29306 .u29,
29307 .u32,
29308 .i32,
29309 .u64,
29310 .i64,
29311 .u128,
29312 .i128,
29313 .usize,
29314 .isize,
29315 .c_short,
29316 .c_ushort,
29317 .c_int,
29318 .c_uint,
29319 .c_long,
29320 .c_ulong,
29321 .c_longlong,
29322 .c_ulonglong,
29323 .c_longdouble,
29324 .f16,
29325 .f32,
29326 .f64,
29327 .f80,
29328 .f128,
29329 .anyopaque,
29330 .bool,
29331 .void,
29332 .anyerror,
29333 .noreturn,
29334 .@"anyframe",
29335 .null,
29336 .undefined,
29337 .atomic_order,
29338 .atomic_rmw_op,
29339 .calling_convention,
29340 .address_space,
29341 .float_mode,
29342 .reduce_op,
29343 .call_options,
29344 .prefetch_options,
29345 .export_options,
29346 .extern_options,
29347 .manyptr_u8,
29348 .manyptr_const_u8,
29349 .manyptr_const_u8_sentinel_0,
29350 .const_slice_u8,
29351 .const_slice_u8_sentinel_0,
29352 .anyerror_void_error_union,
29353 .empty_struct_literal,
29354 .empty_struct,
29355 .error_set,
29356 .error_set_single,
29357 .error_set_inferred,
29358 .error_set_merged,
29359 .@"opaque",
29360 .generic_poison,
29361 .array_u8,
29362 .array_u8_sentinel_0,
29363 .int_signed,
29364 .int_unsigned,
29365 .enum_simple,
29366 => false,
29367
29368 .single_const_pointer_to_comptime_int,
29369 .type,
29370 .comptime_int,
29371 .comptime_float,
29372 .enum_literal,
29373 .type_info,
29374 // These are function bodies, not function pointers.
29375 .fn_noreturn_no_args,
29376 .fn_void_no_args,
29377 .fn_naked_noreturn_no_args,
29378 .fn_ccc_void_no_args,
29379 .function,
29380 => true,
29381
29382 .var_args_param => unreachable,
29383 .inferred_alloc_mut => unreachable,
29384 .inferred_alloc_const => unreachable,
29385 .bound_fn => unreachable,
29386
29387 .array,
29388 .array_sentinel,
29389 .vector,
29390 => return sema.resolveTypeRequiresComptime(ty.childType()),
29391
29392 .pointer,
29393 .single_const_pointer,
29394 .single_mut_pointer,
29395 .many_const_pointer,
29396 .many_mut_pointer,
29397 .c_const_pointer,
29398 .c_mut_pointer,
29399 .const_slice,
29400 .mut_slice,
29401 => {
29402 const child_ty = ty.childType();
29403 if (child_ty.zigTypeTag() == .Fn) {
29404 return child_ty.fnInfo().is_generic;
29405 } else {
29406 return sema.resolveTypeRequiresComptime(child_ty);
29407 }
29408 },
29409
29410 .optional,
29411 .optional_single_mut_pointer,
29412 .optional_single_const_pointer,
29413 => {
29414 var buf: Type.Payload.ElemType = undefined;
29415 return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf));
29416 },
29417
29418 .tuple, .anon_struct => {
29419 const tuple = ty.tupleFields();
29420 for (tuple.types) |field_ty, i| {
29421 const have_comptime_val = tuple.values[i].tag() != .unreachable_value;
29422 if (!have_comptime_val and try sema.resolveTypeRequiresComptime(field_ty)) {
29423 return true;
29424 }
29425 }
29426 return false;
29427 },
29428
29429 .@"struct" => {
29430 const struct_obj = ty.castTag(.@"struct").?.data;
29431 switch (struct_obj.requires_comptime) {
29432 .no, .wip => return false,
29433 .yes => return true,
29434 .unknown => {
29435 var requires_comptime = false;
29436 struct_obj.requires_comptime = .wip;
29437 for (struct_obj.fields.values()) |field| {
29438 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29439 }
29440 if (requires_comptime) {
29441 struct_obj.requires_comptime = .yes;
29442 } else {
29443 struct_obj.requires_comptime = .no;
29444 }
29445 return requires_comptime;
29446 },
29447 }
29448 },
29449
29450 .@"union", .union_safety_tagged, .union_tagged => {
29451 const union_obj = ty.cast(Type.Payload.Union).?.data;
29452 switch (union_obj.requires_comptime) {
29453 .no, .wip => return false,
29454 .yes => return true,
29455 .unknown => {
29456 var requires_comptime = false;
29457 union_obj.requires_comptime = .wip;
29458 for (union_obj.fields.values()) |field| {
29459 if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true;
29460 }
29461 if (requires_comptime) {
29462 union_obj.requires_comptime = .yes;
29463 } else {
29464 union_obj.requires_comptime = .no;
29465 }
29466 return requires_comptime;
29467 },
29468 }
29469 },
29470
29471 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
29472 .anyframe_T => {
29473 const child_ty = ty.castTag(.anyframe_T).?.data;
29474 return sema.resolveTypeRequiresComptime(child_ty);
29475 },
29476 .enum_numbered => {
29477 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;
29478 return sema.resolveTypeRequiresComptime(tag_ty);
29479 },
29480 .enum_full, .enum_nonexhaustive => {
29481 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;
29482 return sema.resolveTypeRequiresComptime(tag_ty);
29483 },
29484 };
29306}29485}
2930729486
29308/// Returns `error.AnalysisFail` if any of the types (recursively) failed to29487/// Returns `error.AnalysisFail` if any of the types (recursively) failed to