| ... | @@ -8180,7 +8180,7 @@ fn analyzeParameter( | ... | @@ -8180,7 +8180,7 @@ fn analyzeParameter( |
| 8180 | if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(cc)) { | 8180 | if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(cc)) { |
| 8181 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | 8181 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); |
| 8182 | } | 8182 | } |
| 8183 | if (this_generic and !Type.fnCallingConventionAllowsZigTypes(cc)) { | 8183 | if (this_generic and !sema.no_partial_func_ty and !Type.fnCallingConventionAllowsZigTypes(cc)) { |
| 8184 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); | 8184 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); |
| 8185 | } | 8185 | } |
| 8186 | if (!param.ty.isValidParamType()) { | 8186 | if (!param.ty.isValidParamType()) { |
| ... | @@ -8196,7 +8196,7 @@ fn analyzeParameter( | ... | @@ -8196,7 +8196,7 @@ fn analyzeParameter( |
| 8196 | }; | 8196 | }; |
| 8197 | return sema.failWithOwnedErrorMsg(msg); | 8197 | return sema.failWithOwnedErrorMsg(msg); |
| 8198 | } | 8198 | } |
| 8199 | if (!Type.fnCallingConventionAllowsZigTypes(cc) and !try sema.validateExternType(block, param_src, param.ty, .param_ty)) { | 8199 | if (!this_generic and !Type.fnCallingConventionAllowsZigTypes(cc) and !try sema.validateExternType(block, param_src, param.ty, .param_ty)) { |
| 8200 | const msg = msg: { | 8200 | const msg = msg: { |
| 8201 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ | 8201 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 8202 | param.ty.fmt(sema.mod), @tagName(cc), | 8202 | param.ty.fmt(sema.mod), @tagName(cc), |
| ... | @@ -8277,8 +8277,21 @@ fn zirParam( | ... | @@ -8277,8 +8277,21 @@ fn zirParam( |
| 8277 | else => |e| return e, | 8277 | else => |e| return e, |
| 8278 | } | 8278 | } |
| 8279 | }; | 8279 | }; |
| 8280 | const is_comptime = comptime_syntax or | 8280 | const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) { |
| 8281 | try sema.typeRequiresComptime(param_ty); | 8281 | error.GenericPoison => { |
| | 8282 | // The type is not available until the generic instantiation. |
| | 8283 | // We result the param instruction with a poison value and |
| | 8284 | // insert an anytype parameter. |
| | 8285 | try block.params.append(sema.gpa, .{ |
| | 8286 | .ty = Type.initTag(.generic_poison), |
| | 8287 | .is_comptime = comptime_syntax, |
| | 8288 | .name = param_name, |
| | 8289 | }); |
| | 8290 | try sema.inst_map.putNoClobber(sema.gpa, inst, .generic_poison); |
| | 8291 | return; |
| | 8292 | }, |
| | 8293 | else => |e| return e, |
| | 8294 | } or comptime_syntax; |
| 8282 | if (sema.inst_map.get(inst)) |arg| { | 8295 | if (sema.inst_map.get(inst)) |arg| { |
| 8283 | if (is_comptime) { | 8296 | if (is_comptime) { |
| 8284 | // We have a comptime value for this parameter so it should be elided from the | 8297 | // We have a comptime value for this parameter so it should be elided from the |
| ... | @@ -15966,8 +15979,8 @@ fn zirStructInit( | ... | @@ -15966,8 +15979,8 @@ fn zirStructInit( |
| 15966 | const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data; | 15979 | const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data; |
| 15967 | const first_field_type_data = zir_datas[first_item.field_type].pl_node; | 15980 | const first_field_type_data = zir_datas[first_item.field_type].pl_node; |
| 15968 | const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data; | 15981 | const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data; |
| 15969 | const unresolved_struct_type = try sema.resolveType(block, src, first_field_type_extra.container_type); | 15982 | const resolved_ty = try sema.resolveType(block, src, first_field_type_extra.container_type); |
| 15970 | const resolved_ty = try sema.resolveTypeFields(block, src, unresolved_struct_type); | 15983 | try sema.resolveTypeLayout(block, src, resolved_ty); |
| 15971 | | 15984 | |
| 15972 | if (resolved_ty.zigTypeTag() == .Struct) { | 15985 | if (resolved_ty.zigTypeTag() == .Struct) { |
| 15973 | // This logic must be synchronized with that in `zirStructInitEmpty`. | 15986 | // This logic must be synchronized with that in `zirStructInitEmpty`. |
| ... | @@ -17017,14 +17030,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -17017,14 +17030,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 17017 | const payload_val = union_val.val.optionalValue() orelse | 17030 | const payload_val = union_val.val.optionalValue() orelse |
| 17018 | return sema.addType(Type.initTag(.anyerror)); | 17031 | return sema.addType(Type.initTag(.anyerror)); |
| 17019 | const slice_val = payload_val.castTag(.slice).?.data; | 17032 | const slice_val = payload_val.castTag(.slice).?.data; |
| 17020 | const decl_index = slice_val.ptr.pointerDecl().?; | | |
| 17021 | try sema.ensureDeclAnalyzed(decl_index); | | |
| 17022 | const decl = mod.declPtr(decl_index); | | |
| 17023 | const array_val: []Value = if (decl.val.castTag(.aggregate)) |some| some.data else &.{}; | | |
| 17024 | | 17033 | |
| | 17034 | const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod.getTarget())); |
| 17025 | var names: Module.ErrorSet.NameMap = .{}; | 17035 | var names: Module.ErrorSet.NameMap = .{}; |
| 17026 | try names.ensureUnusedCapacity(sema.arena, array_val.len); | 17036 | try names.ensureUnusedCapacity(sema.arena, len); |
| 17027 | for (array_val) |elem_val| { | 17037 | var i: usize = 0; |
| | 17038 | while (i < len) : (i += 1) { |
| | 17039 | var buf: Value.ElemValueBuffer = undefined; |
| | 17040 | const elem_val = slice_val.ptr.elemValueBuffer(mod, i, &buf); |
| 17028 | const struct_val = elem_val.castTag(.aggregate).?.data; | 17041 | const struct_val = elem_val.castTag(.aggregate).?.data; |
| 17029 | // TODO use reflection instead of magic numbers here | 17042 | // TODO use reflection instead of magic numbers here |
| 17030 | // error_set: type, | 17043 | // error_set: type, |
| ... | @@ -17416,14 +17429,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -17416,14 +17429,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 17416 | var buf: Value.ToTypeBuffer = undefined; | 17429 | var buf: Value.ToTypeBuffer = undefined; |
| 17417 | | 17430 | |
| 17418 | const args_slice_val = args_val.castTag(.slice).?.data; | 17431 | const args_slice_val = args_val.castTag(.slice).?.data; |
| 17419 | const args_decl_index = args_slice_val.ptr.pointerDecl().?; | 17432 | const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod.getTarget())); |
| 17420 | try sema.ensureDeclAnalyzed(args_decl_index); | 17433 | var param_types = try sema.arena.alloc(Type, args_len); |
| 17421 | const args_decl = mod.declPtr(args_decl_index); | 17434 | var comptime_params = try sema.arena.alloc(bool, args_len); |
| 17422 | const args: []Value = if (args_decl.val.castTag(.aggregate)) |some| some.data else &.{}; | | |
| 17423 | var param_types = try sema.arena.alloc(Type, args.len); | | |
| 17424 | var comptime_params = try sema.arena.alloc(bool, args.len); | | |
| 17425 | var noalias_bits: u32 = 0; | 17435 | var noalias_bits: u32 = 0; |
| 17426 | for (args) |arg, i| { | 17436 | var i: usize = 0; |
| | 17437 | while (i < args_len) : (i += 1) { |
| | 17438 | var arg_buf: Value.ElemValueBuffer = undefined; |
| | 17439 | const arg = args_slice_val.ptr.elemValueBuffer(mod, i, &arg_buf); |
| 17427 | const arg_val = arg.castTag(.aggregate).?.data; | 17440 | const arg_val = arg.castTag(.aggregate).?.data; |
| 17428 | // TODO use reflection instead of magic numbers here | 17441 | // TODO use reflection instead of magic numbers here |
| 17429 | // is_generic: bool, | 17442 | // is_generic: bool, |
| ... | @@ -20841,9 +20854,9 @@ fn validateExternType( | ... | @@ -20841,9 +20854,9 @@ fn validateExternType( |
| 20841 | .Opaque, | 20854 | .Opaque, |
| 20842 | .Bool, | 20855 | .Bool, |
| 20843 | .Float, | 20856 | .Float, |
| 20844 | .Pointer, | | |
| 20845 | .AnyFrame, | 20857 | .AnyFrame, |
| 20846 | => return true, | 20858 | => return true, |
| | 20859 | .Pointer => return !ty.isSlice(), |
| 20847 | .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) { | 20860 | .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) { |
| 20848 | 8, 16, 32, 64, 128 => return true, | 20861 | 8, 16, 32, 64, 128 => return true, |
| 20849 | else => return false, | 20862 | else => return false, |
| ... | @@ -20886,7 +20899,6 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -20886,7 +20899,6 @@ fn explainWhyTypeIsNotExtern( |
| 20886 | .Opaque, | 20899 | .Opaque, |
| 20887 | .Bool, | 20900 | .Bool, |
| 20888 | .Float, | 20901 | .Float, |
| 20889 | .Pointer, | | |
| 20890 | .AnyFrame, | 20902 | .AnyFrame, |
| 20891 | => return, | 20903 | => return, |
| 20892 | | 20904 | |
| ... | @@ -20902,6 +20914,7 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -20902,6 +20914,7 @@ fn explainWhyTypeIsNotExtern( |
| 20902 | .Frame, | 20914 | .Frame, |
| 20903 | => return, | 20915 | => return, |
| 20904 | | 20916 | |
| | 20917 | .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}), |
| 20905 | .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), | 20918 | .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), |
| 20906 | .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}), | 20919 | .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}), |
| 20907 | .Int => if (ty.intInfo(sema.mod.getTarget()).bits > 128) { | 20920 | .Int => if (ty.intInfo(sema.mod.getTarget()).bits > 128) { |
| ... | @@ -20960,11 +20973,11 @@ fn validatePackedType(ty: Type) bool { | ... | @@ -20960,11 +20973,11 @@ fn validatePackedType(ty: Type) bool { |
| 20960 | .Void, | 20973 | .Void, |
| 20961 | .Bool, | 20974 | .Bool, |
| 20962 | .Float, | 20975 | .Float, |
| 20963 | .Pointer, | | |
| 20964 | .Int, | 20976 | .Int, |
| 20965 | .Vector, | 20977 | .Vector, |
| 20966 | .Enum, | 20978 | .Enum, |
| 20967 | => return true, | 20979 | => return true, |
| | 20980 | .Pointer => return !ty.isSlice(), |
| 20968 | .Struct, .Union => return ty.containerLayout() == .Packed, | 20981 | .Struct, .Union => return ty.containerLayout() == .Packed, |
| 20969 | } | 20982 | } |
| 20970 | } | 20983 | } |
| ... | @@ -20980,7 +20993,6 @@ fn explainWhyTypeIsNotPacked( | ... | @@ -20980,7 +20993,6 @@ fn explainWhyTypeIsNotPacked( |
| 20980 | .Void, | 20993 | .Void, |
| 20981 | .Bool, | 20994 | .Bool, |
| 20982 | .Float, | 20995 | .Float, |
| 20983 | .Pointer, | | |
| 20984 | .Int, | 20996 | .Int, |
| 20985 | .Vector, | 20997 | .Vector, |
| 20986 | .Enum, | 20998 | .Enum, |
| ... | @@ -21001,6 +21013,7 @@ fn explainWhyTypeIsNotPacked( | ... | @@ -21001,6 +21013,7 @@ fn explainWhyTypeIsNotPacked( |
| 21001 | .Optional, | 21013 | .Optional, |
| 21002 | .Array, | 21014 | .Array, |
| 21003 | => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}), | 21015 | => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}), |
| | 21016 | .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}), |
| 21004 | .Fn => { | 21017 | .Fn => { |
| 21005 | try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); | 21018 | try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); |
| 21006 | try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); | 21019 | try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); |
| ... | @@ -22027,6 +22040,7 @@ fn structFieldPtrByIndex( | ... | @@ -22027,6 +22040,7 @@ fn structFieldPtrByIndex( |
| 22027 | var ptr_ty_data: Type.Payload.Pointer.Data = .{ | 22040 | var ptr_ty_data: Type.Payload.Pointer.Data = .{ |
| 22028 | .pointee_type = field.ty, | 22041 | .pointee_type = field.ty, |
| 22029 | .mutable = struct_ptr_ty_info.mutable, | 22042 | .mutable = struct_ptr_ty_info.mutable, |
| | 22043 | .@"volatile" = struct_ptr_ty_info.@"volatile", |
| 22030 | .@"addrspace" = struct_ptr_ty_info.@"addrspace", | 22044 | .@"addrspace" = struct_ptr_ty_info.@"addrspace", |
| 22031 | }; | 22045 | }; |
| 22032 | | 22046 | |
| ... | @@ -22246,6 +22260,7 @@ fn unionFieldPtr( | ... | @@ -22246,6 +22260,7 @@ fn unionFieldPtr( |
| 22246 | const ptr_field_ty = try Type.ptr(arena, sema.mod, .{ | 22260 | const ptr_field_ty = try Type.ptr(arena, sema.mod, .{ |
| 22247 | .pointee_type = field.ty, | 22261 | .pointee_type = field.ty, |
| 22248 | .mutable = union_ptr_ty.ptrIsMutable(), | 22262 | .mutable = union_ptr_ty.ptrIsMutable(), |
| | 22263 | .@"volatile" = union_ptr_ty.isVolatilePtr(), |
| 22249 | .@"addrspace" = union_ptr_ty.ptrAddressSpace(), | 22264 | .@"addrspace" = union_ptr_ty.ptrAddressSpace(), |
| 22250 | }); | 22265 | }); |
| 22251 | const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?); | 22266 | const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?); |
| ... | @@ -22568,6 +22583,7 @@ fn tupleFieldPtr( | ... | @@ -22568,6 +22583,7 @@ fn tupleFieldPtr( |
| 22568 | const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ | 22583 | const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 22569 | .pointee_type = field_ty, | 22584 | .pointee_type = field_ty, |
| 22570 | .mutable = tuple_ptr_ty.ptrIsMutable(), | 22585 | .mutable = tuple_ptr_ty.ptrIsMutable(), |
| | 22586 | .@"volatile" = tuple_ptr_ty.isVolatilePtr(), |
| 22571 | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(), | 22587 | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(), |
| 22572 | }); | 22588 | }); |
| 22573 | | 22589 | |
| ... | @@ -23011,9 +23027,37 @@ fn coerceExtra( | ... | @@ -23011,9 +23027,37 @@ fn coerceExtra( |
| 23011 | const dest_is_mut = dest_info.mutable; | 23027 | const dest_is_mut = dest_info.mutable; |
| 23012 | | 23028 | |
| 23013 | const dst_elem_type = dest_info.pointee_type; | 23029 | const dst_elem_type = dest_info.pointee_type; |
| 23014 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src)) { | 23030 | const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src); |
| | 23031 | switch (elem_res) { |
| 23015 | .ok => {}, | 23032 | .ok => {}, |
| 23016 | else => break :src_array_ptr, | 23033 | else => { |
| | 23034 | in_memory_result = .{ .ptr_child = .{ |
| | 23035 | .child = try elem_res.dupe(sema.arena), |
| | 23036 | .actual = array_elem_type, |
| | 23037 | .wanted = dst_elem_type, |
| | 23038 | } }; |
| | 23039 | break :src_array_ptr; |
| | 23040 | }, |
| | 23041 | } |
| | 23042 | |
| | 23043 | if (dest_info.sentinel) |dest_sent| { |
| | 23044 | if (array_ty.sentinel()) |inst_sent| { |
| | 23045 | if (!dest_sent.eql(inst_sent, dst_elem_type, sema.mod)) { |
| | 23046 | in_memory_result = .{ .ptr_sentinel = .{ |
| | 23047 | .actual = inst_sent, |
| | 23048 | .wanted = dest_sent, |
| | 23049 | .ty = dst_elem_type, |
| | 23050 | } }; |
| | 23051 | break :src_array_ptr; |
| | 23052 | } |
| | 23053 | } else { |
| | 23054 | in_memory_result = .{ .ptr_sentinel = .{ |
| | 23055 | .actual = Value.initTag(.unreachable_value), |
| | 23056 | .wanted = dest_sent, |
| | 23057 | .ty = dst_elem_type, |
| | 23058 | } }; |
| | 23059 | break :src_array_ptr; |
| | 23060 | } |
| 23017 | } | 23061 | } |
| 23018 | | 23062 | |
| 23019 | switch (dest_info.size) { | 23063 | switch (dest_info.size) { |
| ... | @@ -23027,17 +23071,7 @@ fn coerceExtra( | ... | @@ -23027,17 +23071,7 @@ fn coerceExtra( |
| 23027 | }, | 23071 | }, |
| 23028 | .Many => { | 23072 | .Many => { |
| 23029 | // *[N]T to [*]T | 23073 | // *[N]T to [*]T |
| 23030 | // *[N:s]T to [*:s]T | 23074 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 23031 | // *[N:s]T to [*]T | | |
| 23032 | if (dest_info.sentinel) |dst_sentinel| { | | |
| 23033 | if (array_ty.sentinel()) |src_sentinel| { | | |
| 23034 | if (src_sentinel.eql(dst_sentinel, dst_elem_type, sema.mod)) { | | |
| 23035 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | | |
| 23036 | } | | |
| 23037 | } | | |
| 23038 | } else { | | |
| 23039 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | | |
| 23040 | } | | |
| 23041 | }, | 23075 | }, |
| 23042 | .One => {}, | 23076 | .One => {}, |
| 23043 | } | 23077 | } |