| ... | ... | @@ -5105,6 +5105,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro |
| 5105 | 5105 | .is_typeof = parent_block.is_typeof, |
| 5106 | 5106 | .want_safety = parent_block.want_safety, |
| 5107 | 5107 | .float_mode = parent_block.float_mode, |
| 5108 | .c_import_buf = parent_block.c_import_buf, |
| 5108 | 5109 | .runtime_cond = parent_block.runtime_cond, |
| 5109 | 5110 | .runtime_loop = parent_block.runtime_loop, |
| 5110 | 5111 | .runtime_index = parent_block.runtime_index, |
| ... | ... | @@ -7031,16 +7032,21 @@ fn instantiateGenericCall( |
| 7031 | 7032 | } |
| 7032 | 7033 | const arg = uncasted_args[arg_i]; |
| 7033 | 7034 | if (is_comptime) { |
| 7034 | | if (try sema.resolveMaybeUndefVal(arg)) |arg_val| { |
| 7035 | | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 7036 | | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 7037 | | } else { |
| 7038 | | return sema.failWithNeededComptime(block, .unneeded, ""); |
| 7039 | | } |
| 7035 | const arg_val = (try sema.resolveMaybeUndefVal(arg)).?; |
| 7036 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 7037 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 7040 | 7038 | } else if (is_anytype) { |
| 7041 | 7039 | const arg_ty = sema.typeOf(arg); |
| 7042 | 7040 | if (try sema.typeRequiresComptime(arg_ty)) { |
| 7043 | | const arg_val = try sema.resolveConstValue(block, .unneeded, arg, ""); |
| 7041 | const arg_val = sema.resolveConstValue(block, .unneeded, arg, "") catch |err| switch (err) { |
| 7042 | error.NeededSourceLocation => { |
| 7043 | const decl = sema.mod.declPtr(block.src_decl); |
| 7044 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i, bound_arg_src); |
| 7045 | _ = try sema.resolveConstValue(block, arg_src, arg, "argument to parameter with comptime-only type must be comptime-known"); |
| 7046 | return error.AnalysisFail; |
| 7047 | }, |
| 7048 | else => |e| return e, |
| 7049 | }; |
| 7044 | 7050 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); |
| 7045 | 7051 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 7046 | 7052 | } else { |
| ... | ... | @@ -7575,7 +7581,8 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7575 | 7581 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) { |
| 7576 | 7582 | .Enum => operand, |
| 7577 | 7583 | .Union => blk: { |
| 7578 | | const tag_ty = operand_ty.unionTagType() orelse { |
| 7584 | const union_ty = try sema.resolveTypeFields(operand_ty); |
| 7585 | const tag_ty = union_ty.unionTagType() orelse { |
| 7579 | 7586 | return sema.fail( |
| 7580 | 7587 | block, |
| 7581 | 7588 | operand_src, |
| ... | ... | @@ -9691,10 +9698,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9691 | 9698 | }; |
| 9692 | 9699 | |
| 9693 | 9700 | const maybe_union_ty = blk: { |
| 9701 | const zir_tags = sema.code.instructions.items(.tag); |
| 9694 | 9702 | const zir_data = sema.code.instructions.items(.data); |
| 9695 | 9703 | const cond_index = Zir.refToIndex(extra.data.operand).?; |
| 9696 | 9704 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; |
| 9697 | | break :blk sema.typeOf(raw_operand); |
| 9705 | const target_ty = sema.typeOf(raw_operand); |
| 9706 | break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty; |
| 9698 | 9707 | }; |
| 9699 | 9708 | const union_originally = maybe_union_ty.zigTypeTag() == .Union; |
| 9700 | 9709 | |
| ... | ... | @@ -10260,6 +10269,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10260 | 10269 | .comptime_reason = block.comptime_reason, |
| 10261 | 10270 | .is_typeof = block.is_typeof, |
| 10262 | 10271 | .switch_else_err_ty = else_error_ty, |
| 10272 | .c_import_buf = block.c_import_buf, |
| 10263 | 10273 | .runtime_cond = block.runtime_cond, |
| 10264 | 10274 | .runtime_loop = block.runtime_loop, |
| 10265 | 10275 | .runtime_index = block.runtime_index, |
| ... | ... | @@ -13468,7 +13478,6 @@ fn zirOverflowArithmetic( |
| 13468 | 13478 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); |
| 13469 | 13479 | |
| 13470 | 13480 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); |
| 13471 | | const ov_ty = tuple_ty.tupleFields().types[1]; |
| 13472 | 13481 | // TODO: Remove and use `ov_ty` instead. |
| 13473 | 13482 | // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`. |
| 13474 | 13483 | const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.@"bool") else Type.@"bool"; |
| ... | ... | @@ -13619,14 +13628,7 @@ fn zirOverflowArithmetic( |
| 13619 | 13628 | try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store); |
| 13620 | 13629 | |
| 13621 | 13630 | const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty); |
| 13622 | | const zero_ov_val = if (dest_ty.zigTypeTag() == .Vector) try Value.Tag.repeated.create(sema.arena, Value.zero) else Value.zero; |
| 13623 | | const zero_ov = try sema.addConstant(ov_ty, zero_ov_val); |
| 13624 | | |
| 13625 | | const overflowed_inst = if (dest_ty.zigTypeTag() == .Vector) |
| 13626 | | block.addCmpVector(overflow_bit, .zero, .neq, try sema.addType(ov_ty)) |
| 13627 | | else |
| 13628 | | block.addBinOp(.cmp_neq, overflow_bit, zero_ov); |
| 13629 | | return overflowed_inst; |
| 13631 | return block.addBitCast(overflowed_ty, overflow_bit); |
| 13630 | 13632 | }; |
| 13631 | 13633 | |
| 13632 | 13634 | try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store); |
| ... | ... | @@ -22714,7 +22716,8 @@ fn fieldPtr( |
| 22714 | 22716 | return inst; |
| 22715 | 22717 | } |
| 22716 | 22718 | } |
| 22717 | | if (child_type.unionTagType()) |enum_ty| { |
| 22719 | const union_ty = try sema.resolveTypeFields(child_type); |
| 22720 | if (union_ty.unionTagType()) |enum_ty| { |
| 22718 | 22721 | if (enum_ty.enumFieldIndex(field_name)) |field_index| { |
| 22719 | 22722 | const field_index_u32 = @intCast(u32, field_index); |
| 22720 | 22723 | var anon_decl = try block.startAnonDecl(); |
| ... | ... | @@ -29122,20 +29125,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void { |
| 29122 | 29125 | } |
| 29123 | 29126 | |
| 29124 | 29127 | struct_obj.status = .have_layout; |
| 29125 | | |
| 29126 | | // In case of querying the ABI alignment of this struct, we will ask |
| 29127 | | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| 29128 | | // to be known already before this function returns. |
| 29129 | | for (struct_obj.fields.values()) |field, i| { |
| 29130 | | _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) { |
| 29131 | | error.AnalysisFail => { |
| 29132 | | const msg = sema.err orelse return err; |
| 29133 | | try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); |
| 29134 | | return err; |
| 29135 | | }, |
| 29136 | | else => return err, |
| 29137 | | }; |
| 29138 | | } |
| 29128 | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| 29139 | 29129 | } |
| 29140 | 29130 | // otherwise it's a tuple; no need to resolve anything |
| 29141 | 29131 | } |
| ... | ... | @@ -29299,6 +29289,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { |
| 29299 | 29289 | }; |
| 29300 | 29290 | } |
| 29301 | 29291 | union_obj.status = .have_layout; |
| 29292 | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| 29293 | } |
| 29294 | |
| 29295 | // In case of querying the ABI alignment of this struct, we will ask |
| 29296 | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| 29297 | // to be known already before this function returns. |
| 29298 | pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 29299 | return switch (ty.tag()) { |
| 29300 | .u1, |
| 29301 | .u8, |
| 29302 | .i8, |
| 29303 | .u16, |
| 29304 | .i16, |
| 29305 | .u29, |
| 29306 | .u32, |
| 29307 | .i32, |
| 29308 | .u64, |
| 29309 | .i64, |
| 29310 | .u128, |
| 29311 | .i128, |
| 29312 | .usize, |
| 29313 | .isize, |
| 29314 | .c_short, |
| 29315 | .c_ushort, |
| 29316 | .c_int, |
| 29317 | .c_uint, |
| 29318 | .c_long, |
| 29319 | .c_ulong, |
| 29320 | .c_longlong, |
| 29321 | .c_ulonglong, |
| 29322 | .c_longdouble, |
| 29323 | .f16, |
| 29324 | .f32, |
| 29325 | .f64, |
| 29326 | .f80, |
| 29327 | .f128, |
| 29328 | .anyopaque, |
| 29329 | .bool, |
| 29330 | .void, |
| 29331 | .anyerror, |
| 29332 | .noreturn, |
| 29333 | .@"anyframe", |
| 29334 | .null, |
| 29335 | .undefined, |
| 29336 | .atomic_order, |
| 29337 | .atomic_rmw_op, |
| 29338 | .calling_convention, |
| 29339 | .address_space, |
| 29340 | .float_mode, |
| 29341 | .reduce_op, |
| 29342 | .call_options, |
| 29343 | .prefetch_options, |
| 29344 | .export_options, |
| 29345 | .extern_options, |
| 29346 | .manyptr_u8, |
| 29347 | .manyptr_const_u8, |
| 29348 | .manyptr_const_u8_sentinel_0, |
| 29349 | .const_slice_u8, |
| 29350 | .const_slice_u8_sentinel_0, |
| 29351 | .anyerror_void_error_union, |
| 29352 | .empty_struct_literal, |
| 29353 | .empty_struct, |
| 29354 | .error_set, |
| 29355 | .error_set_single, |
| 29356 | .error_set_inferred, |
| 29357 | .error_set_merged, |
| 29358 | .@"opaque", |
| 29359 | .generic_poison, |
| 29360 | .array_u8, |
| 29361 | .array_u8_sentinel_0, |
| 29362 | .int_signed, |
| 29363 | .int_unsigned, |
| 29364 | .enum_simple, |
| 29365 | => false, |
| 29366 | |
| 29367 | .single_const_pointer_to_comptime_int, |
| 29368 | .type, |
| 29369 | .comptime_int, |
| 29370 | .comptime_float, |
| 29371 | .enum_literal, |
| 29372 | .type_info, |
| 29373 | // These are function bodies, not function pointers. |
| 29374 | .fn_noreturn_no_args, |
| 29375 | .fn_void_no_args, |
| 29376 | .fn_naked_noreturn_no_args, |
| 29377 | .fn_ccc_void_no_args, |
| 29378 | .function, |
| 29379 | => true, |
| 29380 | |
| 29381 | .var_args_param => unreachable, |
| 29382 | .inferred_alloc_mut => unreachable, |
| 29383 | .inferred_alloc_const => unreachable, |
| 29384 | .bound_fn => unreachable, |
| 29385 | |
| 29386 | .array, |
| 29387 | .array_sentinel, |
| 29388 | .vector, |
| 29389 | => return sema.resolveTypeRequiresComptime(ty.childType()), |
| 29390 | |
| 29391 | .pointer, |
| 29392 | .single_const_pointer, |
| 29393 | .single_mut_pointer, |
| 29394 | .many_const_pointer, |
| 29395 | .many_mut_pointer, |
| 29396 | .c_const_pointer, |
| 29397 | .c_mut_pointer, |
| 29398 | .const_slice, |
| 29399 | .mut_slice, |
| 29400 | => { |
| 29401 | const child_ty = ty.childType(); |
| 29402 | if (child_ty.zigTypeTag() == .Fn) { |
| 29403 | return child_ty.fnInfo().is_generic; |
| 29404 | } else { |
| 29405 | return sema.resolveTypeRequiresComptime(child_ty); |
| 29406 | } |
| 29407 | }, |
| 29408 | |
| 29409 | .optional, |
| 29410 | .optional_single_mut_pointer, |
| 29411 | .optional_single_const_pointer, |
| 29412 | => { |
| 29413 | var buf: Type.Payload.ElemType = undefined; |
| 29414 | return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf)); |
| 29415 | }, |
| 29416 | |
| 29417 | .tuple, .anon_struct => { |
| 29418 | const tuple = ty.tupleFields(); |
| 29419 | for (tuple.types) |field_ty, i| { |
| 29420 | const have_comptime_val = tuple.values[i].tag() != .unreachable_value; |
| 29421 | if (!have_comptime_val and try sema.resolveTypeRequiresComptime(field_ty)) { |
| 29422 | return true; |
| 29423 | } |
| 29424 | } |
| 29425 | return false; |
| 29426 | }, |
| 29427 | |
| 29428 | .@"struct" => { |
| 29429 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 29430 | switch (struct_obj.requires_comptime) { |
| 29431 | .no, .wip => return false, |
| 29432 | .yes => return true, |
| 29433 | .unknown => { |
| 29434 | var requires_comptime = false; |
| 29435 | struct_obj.requires_comptime = .wip; |
| 29436 | for (struct_obj.fields.values()) |field| { |
| 29437 | if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true; |
| 29438 | } |
| 29439 | if (requires_comptime) { |
| 29440 | struct_obj.requires_comptime = .yes; |
| 29441 | } else { |
| 29442 | struct_obj.requires_comptime = .no; |
| 29443 | } |
| 29444 | return requires_comptime; |
| 29445 | }, |
| 29446 | } |
| 29447 | }, |
| 29448 | |
| 29449 | .@"union", .union_safety_tagged, .union_tagged => { |
| 29450 | const union_obj = ty.cast(Type.Payload.Union).?.data; |
| 29451 | switch (union_obj.requires_comptime) { |
| 29452 | .no, .wip => return false, |
| 29453 | .yes => return true, |
| 29454 | .unknown => { |
| 29455 | var requires_comptime = false; |
| 29456 | union_obj.requires_comptime = .wip; |
| 29457 | for (union_obj.fields.values()) |field| { |
| 29458 | if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true; |
| 29459 | } |
| 29460 | if (requires_comptime) { |
| 29461 | union_obj.requires_comptime = .yes; |
| 29462 | } else { |
| 29463 | union_obj.requires_comptime = .no; |
| 29464 | } |
| 29465 | return requires_comptime; |
| 29466 | }, |
| 29467 | } |
| 29468 | }, |
| 29469 | |
| 29470 | .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), |
| 29471 | .anyframe_T => { |
| 29472 | const child_ty = ty.castTag(.anyframe_T).?.data; |
| 29473 | return sema.resolveTypeRequiresComptime(child_ty); |
| 29474 | }, |
| 29475 | .enum_numbered => { |
| 29476 | const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty; |
| 29477 | return sema.resolveTypeRequiresComptime(tag_ty); |
| 29478 | }, |
| 29479 | .enum_full, .enum_nonexhaustive => { |
| 29480 | const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty; |
| 29481 | return sema.resolveTypeRequiresComptime(tag_ty); |
| 29482 | }, |
| 29483 | }; |
| 29302 | 29484 | } |
| 29303 | 29485 | |
| 29304 | 29486 | /// Returns `error.AnalysisFail` if any of the types (recursively) failed to |