| ... | @@ -5105,6 +5105,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -5105,6 +5105,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro |
| 5105 | .is_typeof = parent_block.is_typeof, | 5105 | .is_typeof = parent_block.is_typeof, |
| 5106 | .want_safety = parent_block.want_safety, | 5106 | .want_safety = parent_block.want_safety, |
| 5107 | .float_mode = parent_block.float_mode, | 5107 | .float_mode = parent_block.float_mode, |
| | 5108 | .c_import_buf = parent_block.c_import_buf, |
| 5108 | .runtime_cond = parent_block.runtime_cond, | 5109 | .runtime_cond = parent_block.runtime_cond, |
| 5109 | .runtime_loop = parent_block.runtime_loop, | 5110 | .runtime_loop = parent_block.runtime_loop, |
| 5110 | .runtime_index = parent_block.runtime_index, | 5111 | .runtime_index = parent_block.runtime_index, |
| ... | @@ -7031,16 +7032,21 @@ fn instantiateGenericCall( | ... | @@ -7031,16 +7032,21 @@ fn instantiateGenericCall( |
| 7031 | } | 7032 | } |
| 7032 | const arg = uncasted_args[arg_i]; | 7033 | const arg = uncasted_args[arg_i]; |
| 7033 | if (is_comptime) { | 7034 | if (is_comptime) { |
| 7034 | if (try sema.resolveMaybeUndefVal(arg)) |arg_val| { | 7035 | const arg_val = (try sema.resolveMaybeUndefVal(arg)).?; |
| 7035 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); | 7036 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 7036 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); | 7037 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 7037 | } else { | | |
| 7038 | return sema.failWithNeededComptime(block, .unneeded, ""); | | |
| 7039 | } | | |
| 7040 | } else if (is_anytype) { | 7038 | } else if (is_anytype) { |
| 7041 | const arg_ty = sema.typeOf(arg); | 7039 | const arg_ty = sema.typeOf(arg); |
| 7042 | if (try sema.typeRequiresComptime(arg_ty)) { | 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 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); | 7050 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); |
| 7045 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); | 7051 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 7046 | } else { | 7052 | } else { |
| ... | @@ -7575,7 +7581,8 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -7575,7 +7581,8 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7575 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) { | 7581 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) { |
| 7576 | .Enum => operand, | 7582 | .Enum => operand, |
| 7577 | .Union => blk: { | 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 | return sema.fail( | 7586 | return sema.fail( |
| 7580 | block, | 7587 | block, |
| 7581 | operand_src, | 7588 | operand_src, |
| ... | @@ -9691,10 +9698,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9691,10 +9698,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9691 | }; | 9698 | }; |
| 9692 | | 9699 | |
| 9693 | const maybe_union_ty = blk: { | 9700 | const maybe_union_ty = blk: { |
| | 9701 | const zir_tags = sema.code.instructions.items(.tag); |
| 9694 | const zir_data = sema.code.instructions.items(.data); | 9702 | const zir_data = sema.code.instructions.items(.data); |
| 9695 | const cond_index = Zir.refToIndex(extra.data.operand).?; | 9703 | const cond_index = Zir.refToIndex(extra.data.operand).?; |
| 9696 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; | 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 | const union_originally = maybe_union_ty.zigTypeTag() == .Union; | 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,6 +10269,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10260 | .comptime_reason = block.comptime_reason, | 10269 | .comptime_reason = block.comptime_reason, |
| 10261 | .is_typeof = block.is_typeof, | 10270 | .is_typeof = block.is_typeof, |
| 10262 | .switch_else_err_ty = else_error_ty, | 10271 | .switch_else_err_ty = else_error_ty, |
| | 10272 | .c_import_buf = block.c_import_buf, |
| 10263 | .runtime_cond = block.runtime_cond, | 10273 | .runtime_cond = block.runtime_cond, |
| 10264 | .runtime_loop = block.runtime_loop, | 10274 | .runtime_loop = block.runtime_loop, |
| 10265 | .runtime_index = block.runtime_index, | 10275 | .runtime_index = block.runtime_index, |
| ... | @@ -13479,7 +13489,6 @@ fn zirOverflowArithmetic( | ... | @@ -13479,7 +13489,6 @@ fn zirOverflowArithmetic( |
| 13479 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); | 13489 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); |
| 13480 | | 13490 | |
| 13481 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); | 13491 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); |
| 13482 | const ov_ty = tuple_ty.tupleFields().types[1]; | | |
| 13483 | // TODO: Remove and use `ov_ty` instead. | 13492 | // TODO: Remove and use `ov_ty` instead. |
| 13484 | // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`. | 13493 | // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`. |
| 13485 | const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool; | 13494 | const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool; |
| ... | @@ -13630,14 +13639,7 @@ fn zirOverflowArithmetic( | ... | @@ -13630,14 +13639,7 @@ fn zirOverflowArithmetic( |
| 13630 | try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store); | 13639 | try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store); |
| 13631 | | 13640 | |
| 13632 | const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty); | 13641 | const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty); |
| 13633 | const zero_ov_val = if (dest_ty.zigTypeTag() == .Vector) try Value.Tag.repeated.create(sema.arena, Value.zero) else Value.zero; | 13642 | return block.addBitCast(overflowed_ty, overflow_bit); |
| 13634 | const zero_ov = try sema.addConstant(ov_ty, zero_ov_val); | | |
| 13635 | | | |
| 13636 | const overflowed_inst = if (dest_ty.zigTypeTag() == .Vector) | | |
| 13637 | block.addCmpVector(overflow_bit, .zero, .neq, try sema.addType(ov_ty)) | | |
| 13638 | else | | |
| 13639 | block.addBinOp(.cmp_neq, overflow_bit, zero_ov); | | |
| 13640 | return overflowed_inst; | | |
| 13641 | }; | 13643 | }; |
| 13642 | | 13644 | |
| 13643 | try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store); | 13645 | try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store); |
| ... | @@ -22675,7 +22677,8 @@ fn fieldPtr( | ... | @@ -22675,7 +22677,8 @@ fn fieldPtr( |
| 22675 | return inst; | 22677 | return inst; |
| 22676 | } | 22678 | } |
| 22677 | } | 22679 | } |
| 22678 | if (child_type.unionTagType()) |enum_ty| { | 22680 | const union_ty = try sema.resolveTypeFields(child_type); |
| | 22681 | if (union_ty.unionTagType()) |enum_ty| { |
| 22679 | if (enum_ty.enumFieldIndex(field_name)) |field_index| { | 22682 | if (enum_ty.enumFieldIndex(field_name)) |field_index| { |
| 22680 | const field_index_u32 = @intCast(u32, field_index); | 22683 | const field_index_u32 = @intCast(u32, field_index); |
| 22681 | var anon_decl = try block.startAnonDecl(); | 22684 | var anon_decl = try block.startAnonDecl(); |
| ... | @@ -29101,20 +29104,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void { | ... | @@ -29101,20 +29104,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void { |
| 29101 | } | 29104 | } |
| 29102 | | 29105 | |
| 29103 | struct_obj.status = .have_layout; | 29106 | struct_obj.status = .have_layout; |
| 29104 | | 29107 | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| 29105 | // In case of querying the ABI alignment of this struct, we will ask | | |
| 29106 | // for hasRuntimeBits() of each field, so we need "requires comptime" | | |
| 29107 | // to be known already before this function returns. | | |
| 29108 | for (struct_obj.fields.values()) |field, i| { | | |
| 29109 | _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) { | | |
| 29110 | error.AnalysisFail => { | | |
| 29111 | const msg = sema.err orelse return err; | | |
| 29112 | try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); | | |
| 29113 | return err; | | |
| 29114 | }, | | |
| 29115 | else => return err, | | |
| 29116 | }; | | |
| 29117 | } | | |
| 29118 | } | 29108 | } |
| 29119 | // otherwise it's a tuple; no need to resolve anything | 29109 | // otherwise it's a tuple; no need to resolve anything |
| 29120 | } | 29110 | } |
| ... | @@ -29278,6 +29268,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { | ... | @@ -29278,6 +29268,198 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { |
| 29278 | }; | 29268 | }; |
| 29279 | } | 29269 | } |
| 29280 | union_obj.status = .have_layout; | 29270 | union_obj.status = .have_layout; |
| | 29271 | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| | 29272 | } |
| | 29273 | |
| | 29274 | // In case of querying the ABI alignment of this struct, we will ask |
| | 29275 | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| | 29276 | // to be known already before this function returns. |
| | 29277 | pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| | 29278 | return switch (ty.tag()) { |
| | 29279 | .u1, |
| | 29280 | .u8, |
| | 29281 | .i8, |
| | 29282 | .u16, |
| | 29283 | .i16, |
| | 29284 | .u29, |
| | 29285 | .u32, |
| | 29286 | .i32, |
| | 29287 | .u64, |
| | 29288 | .i64, |
| | 29289 | .u128, |
| | 29290 | .i128, |
| | 29291 | .usize, |
| | 29292 | .isize, |
| | 29293 | .c_short, |
| | 29294 | .c_ushort, |
| | 29295 | .c_int, |
| | 29296 | .c_uint, |
| | 29297 | .c_long, |
| | 29298 | .c_ulong, |
| | 29299 | .c_longlong, |
| | 29300 | .c_ulonglong, |
| | 29301 | .c_longdouble, |
| | 29302 | .f16, |
| | 29303 | .f32, |
| | 29304 | .f64, |
| | 29305 | .f80, |
| | 29306 | .f128, |
| | 29307 | .anyopaque, |
| | 29308 | .bool, |
| | 29309 | .void, |
| | 29310 | .anyerror, |
| | 29311 | .noreturn, |
| | 29312 | .@"anyframe", |
| | 29313 | .null, |
| | 29314 | .undefined, |
| | 29315 | .atomic_order, |
| | 29316 | .atomic_rmw_op, |
| | 29317 | .calling_convention, |
| | 29318 | .address_space, |
| | 29319 | .float_mode, |
| | 29320 | .reduce_op, |
| | 29321 | .call_options, |
| | 29322 | .prefetch_options, |
| | 29323 | .export_options, |
| | 29324 | .extern_options, |
| | 29325 | .manyptr_u8, |
| | 29326 | .manyptr_const_u8, |
| | 29327 | .manyptr_const_u8_sentinel_0, |
| | 29328 | .const_slice_u8, |
| | 29329 | .const_slice_u8_sentinel_0, |
| | 29330 | .anyerror_void_error_union, |
| | 29331 | .empty_struct_literal, |
| | 29332 | .empty_struct, |
| | 29333 | .error_set, |
| | 29334 | .error_set_single, |
| | 29335 | .error_set_inferred, |
| | 29336 | .error_set_merged, |
| | 29337 | .@"opaque", |
| | 29338 | .generic_poison, |
| | 29339 | .array_u8, |
| | 29340 | .array_u8_sentinel_0, |
| | 29341 | .int_signed, |
| | 29342 | .int_unsigned, |
| | 29343 | .enum_simple, |
| | 29344 | => false, |
| | 29345 | |
| | 29346 | .single_const_pointer_to_comptime_int, |
| | 29347 | .type, |
| | 29348 | .comptime_int, |
| | 29349 | .comptime_float, |
| | 29350 | .enum_literal, |
| | 29351 | .type_info, |
| | 29352 | // These are function bodies, not function pointers. |
| | 29353 | .fn_noreturn_no_args, |
| | 29354 | .fn_void_no_args, |
| | 29355 | .fn_naked_noreturn_no_args, |
| | 29356 | .fn_ccc_void_no_args, |
| | 29357 | .function, |
| | 29358 | => true, |
| | 29359 | |
| | 29360 | .var_args_param => unreachable, |
| | 29361 | .inferred_alloc_mut => unreachable, |
| | 29362 | .inferred_alloc_const => unreachable, |
| | 29363 | .bound_fn => unreachable, |
| | 29364 | |
| | 29365 | .array, |
| | 29366 | .array_sentinel, |
| | 29367 | .vector, |
| | 29368 | => return sema.resolveTypeRequiresComptime(ty.childType()), |
| | 29369 | |
| | 29370 | .pointer, |
| | 29371 | .single_const_pointer, |
| | 29372 | .single_mut_pointer, |
| | 29373 | .many_const_pointer, |
| | 29374 | .many_mut_pointer, |
| | 29375 | .c_const_pointer, |
| | 29376 | .c_mut_pointer, |
| | 29377 | .const_slice, |
| | 29378 | .mut_slice, |
| | 29379 | => { |
| | 29380 | const child_ty = ty.childType(); |
| | 29381 | if (child_ty.zigTypeTag() == .Fn) { |
| | 29382 | return child_ty.fnInfo().is_generic; |
| | 29383 | } else { |
| | 29384 | return sema.resolveTypeRequiresComptime(child_ty); |
| | 29385 | } |
| | 29386 | }, |
| | 29387 | |
| | 29388 | .optional, |
| | 29389 | .optional_single_mut_pointer, |
| | 29390 | .optional_single_const_pointer, |
| | 29391 | => { |
| | 29392 | var buf: Type.Payload.ElemType = undefined; |
| | 29393 | return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf)); |
| | 29394 | }, |
| | 29395 | |
| | 29396 | .tuple, .anon_struct => { |
| | 29397 | const tuple = ty.tupleFields(); |
| | 29398 | for (tuple.types) |field_ty, i| { |
| | 29399 | const have_comptime_val = tuple.values[i].tag() != .unreachable_value; |
| | 29400 | if (!have_comptime_val and try sema.resolveTypeRequiresComptime(field_ty)) { |
| | 29401 | return true; |
| | 29402 | } |
| | 29403 | } |
| | 29404 | return false; |
| | 29405 | }, |
| | 29406 | |
| | 29407 | .@"struct" => { |
| | 29408 | const struct_obj = ty.castTag(.@"struct").?.data; |
| | 29409 | switch (struct_obj.requires_comptime) { |
| | 29410 | .no, .wip => return false, |
| | 29411 | .yes => return true, |
| | 29412 | .unknown => { |
| | 29413 | var requires_comptime = false; |
| | 29414 | struct_obj.requires_comptime = .wip; |
| | 29415 | for (struct_obj.fields.values()) |field| { |
| | 29416 | if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true; |
| | 29417 | } |
| | 29418 | if (requires_comptime) { |
| | 29419 | struct_obj.requires_comptime = .yes; |
| | 29420 | } else { |
| | 29421 | struct_obj.requires_comptime = .no; |
| | 29422 | } |
| | 29423 | return requires_comptime; |
| | 29424 | }, |
| | 29425 | } |
| | 29426 | }, |
| | 29427 | |
| | 29428 | .@"union", .union_safety_tagged, .union_tagged => { |
| | 29429 | const union_obj = ty.cast(Type.Payload.Union).?.data; |
| | 29430 | switch (union_obj.requires_comptime) { |
| | 29431 | .no, .wip => return false, |
| | 29432 | .yes => return true, |
| | 29433 | .unknown => { |
| | 29434 | var requires_comptime = false; |
| | 29435 | union_obj.requires_comptime = .wip; |
| | 29436 | for (union_obj.fields.values()) |field| { |
| | 29437 | if (try sema.resolveTypeRequiresComptime(field.ty)) requires_comptime = true; |
| | 29438 | } |
| | 29439 | if (requires_comptime) { |
| | 29440 | union_obj.requires_comptime = .yes; |
| | 29441 | } else { |
| | 29442 | union_obj.requires_comptime = .no; |
| | 29443 | } |
| | 29444 | return requires_comptime; |
| | 29445 | }, |
| | 29446 | } |
| | 29447 | }, |
| | 29448 | |
| | 29449 | .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), |
| | 29450 | .anyframe_T => { |
| | 29451 | const child_ty = ty.castTag(.anyframe_T).?.data; |
| | 29452 | return sema.resolveTypeRequiresComptime(child_ty); |
| | 29453 | }, |
| | 29454 | .enum_numbered => { |
| | 29455 | const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty; |
| | 29456 | return sema.resolveTypeRequiresComptime(tag_ty); |
| | 29457 | }, |
| | 29458 | .enum_full, .enum_nonexhaustive => { |
| | 29459 | const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty; |
| | 29460 | return sema.resolveTypeRequiresComptime(tag_ty); |
| | 29461 | }, |
| | 29462 | }; |
| 29281 | } | 29463 | } |
| 29282 | | 29464 | |
| 29283 | /// Returns `error.AnalysisFail` if any of the types (recursively) failed to | 29465 | /// Returns `error.AnalysisFail` if any of the types (recursively) failed to |