| ... | @@ -1820,12 +1820,7 @@ fn analyzeAsType( | ... | @@ -1820,12 +1820,7 @@ fn analyzeAsType( |
| 1820 | } | 1820 | } |
| 1821 | | 1821 | |
| 1822 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { | 1822 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { |
| 1823 | const backend_supports_error_return_tracing = | 1823 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 1824 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 1825 | if (!backend_supports_error_return_tracing) { | | |
| 1826 | // TODO implement this feature in all the backends and then delete this branch | | |
| 1827 | return; | | |
| 1828 | } | | |
| 1829 | | 1824 | |
| 1830 | assert(!block.is_comptime); | 1825 | assert(!block.is_comptime); |
| 1831 | var err_trace_block = block.makeSubBlock(); | 1826 | var err_trace_block = block.makeSubBlock(); |
| ... | @@ -2099,16 +2094,12 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS | ... | @@ -2099,16 +2094,12 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS |
| 2099 | const msg = try sema.errMsg(block, init_src, "value stored in comptime field does not match the default value of the field", .{}); | 2094 | const msg = try sema.errMsg(block, init_src, "value stored in comptime field does not match the default value of the field", .{}); |
| 2100 | errdefer msg.destroy(sema.gpa); | 2095 | errdefer msg.destroy(sema.gpa); |
| 2101 | | 2096 | |
| 2102 | const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg; | 2097 | const struct_ty = container_ty.castTag(.@"struct") orelse break :msg msg; |
| 2103 | const decl = sema.mod.declPtr(decl_index); | 2098 | const default_value_src = struct_ty.data.fieldSrcLoc(sema.mod, .{ |
| 2104 | const tree = decl.getFileScope().getTree(sema.gpa) catch |err| { | 2099 | .index = field_index, |
| 2105 | log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); | 2100 | .range = .value, |
| 2106 | return error.AnalysisFail; | 2101 | }); |
| 2107 | }; | 2102 | try sema.mod.errNoteNonLazy(default_value_src, msg, "default value set here", .{}); |
| 2108 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index); | | |
| 2109 | const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x }; | | |
| 2110 | | | |
| 2111 | try sema.mod.errNoteNonLazy(default_value_src.toSrcLoc(decl), msg, "default value set here", .{}); | | |
| 2112 | break :msg msg; | 2103 | break :msg msg; |
| 2113 | }; | 2104 | }; |
| 2114 | return sema.failWithOwnedErrorMsg(msg); | 2105 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -2146,15 +2137,61 @@ fn addFieldErrNote( | ... | @@ -2146,15 +2137,61 @@ fn addFieldErrNote( |
| 2146 | comptime format: []const u8, | 2137 | comptime format: []const u8, |
| 2147 | args: anytype, | 2138 | args: anytype, |
| 2148 | ) !void { | 2139 | ) !void { |
| | 2140 | @setCold(true); |
| 2149 | const mod = sema.mod; | 2141 | const mod = sema.mod; |
| 2150 | const decl_index = container_ty.getOwnerDecl(); | 2142 | const decl_index = container_ty.getOwnerDecl(); |
| 2151 | const decl = mod.declPtr(decl_index); | 2143 | const decl = mod.declPtr(decl_index); |
| 2152 | const tree = decl.getFileScope().getTree(sema.gpa) catch |err| { | 2144 | |
| 2153 | log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); | 2145 | const field_src = blk: { |
| 2154 | return error.AnalysisFail; | 2146 | const tree = decl.getFileScope().getTree(sema.gpa) catch |err| { |
| | 2147 | log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); |
| | 2148 | break :blk decl.srcLoc(); |
| | 2149 | }; |
| | 2150 | |
| | 2151 | const container_node = decl.relativeToNodeIndex(0); |
| | 2152 | const node_tags = tree.nodes.items(.tag); |
| | 2153 | var buffer: [2]std.zig.Ast.Node.Index = undefined; |
| | 2154 | const container_decl = switch (node_tags[container_node]) { |
| | 2155 | .root => tree.containerDeclRoot(), |
| | 2156 | .container_decl, |
| | 2157 | .container_decl_trailing, |
| | 2158 | => tree.containerDecl(container_node), |
| | 2159 | .container_decl_two, |
| | 2160 | .container_decl_two_trailing, |
| | 2161 | => tree.containerDeclTwo(&buffer, container_node), |
| | 2162 | .container_decl_arg, |
| | 2163 | .container_decl_arg_trailing, |
| | 2164 | => tree.containerDeclArg(container_node), |
| | 2165 | .tagged_union, |
| | 2166 | .tagged_union_trailing, |
| | 2167 | => tree.taggedUnion(container_node), |
| | 2168 | .tagged_union_two, |
| | 2169 | .tagged_union_two_trailing, |
| | 2170 | => tree.taggedUnionTwo(&buffer, container_node), |
| | 2171 | .tagged_union_enum_tag, |
| | 2172 | .tagged_union_enum_tag_trailing, |
| | 2173 | => tree.taggedUnionEnumTag(container_node), |
| | 2174 | else => break :blk decl.srcLoc(), |
| | 2175 | }; |
| | 2176 | |
| | 2177 | var it_index: usize = 0; |
| | 2178 | for (container_decl.ast.members) |member_node| { |
| | 2179 | switch (node_tags[member_node]) { |
| | 2180 | .container_field_init, |
| | 2181 | .container_field_align, |
| | 2182 | .container_field, |
| | 2183 | => { |
| | 2184 | if (it_index == field_index) { |
| | 2185 | break :blk decl.nodeOffsetSrcLoc(decl.nodeIndexToRelative(member_node)); |
| | 2186 | } |
| | 2187 | it_index += 1; |
| | 2188 | }, |
| | 2189 | else => continue, |
| | 2190 | } |
| | 2191 | } |
| | 2192 | unreachable; |
| 2155 | }; | 2193 | }; |
| 2156 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index); | 2194 | try mod.errNoteNonLazy(field_src, parent, format, args); |
| 2157 | try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args); | | |
| 2158 | } | 2195 | } |
| 2159 | | 2196 | |
| 2160 | fn errMsg( | 2197 | fn errMsg( |
| ... | @@ -2868,7 +2905,7 @@ fn zirEnumDecl( | ... | @@ -2868,7 +2905,7 @@ fn zirEnumDecl( |
| 2868 | .inlining = null, | 2905 | .inlining = null, |
| 2869 | .is_comptime = true, | 2906 | .is_comptime = true, |
| 2870 | }; | 2907 | }; |
| 2871 | defer assert(enum_block.instructions.items.len == 0); // should all be comptime instructions | 2908 | defer enum_block.instructions.deinit(sema.gpa); |
| 2872 | | 2909 | |
| 2873 | if (body.len != 0) { | 2910 | if (body.len != 0) { |
| 2874 | try sema.analyzeBody(&enum_block, body); | 2911 | try sema.analyzeBody(&enum_block, body); |
| ... | @@ -2934,13 +2971,12 @@ fn zirEnumDecl( | ... | @@ -2934,13 +2971,12 @@ fn zirEnumDecl( |
| 2934 | | 2971 | |
| 2935 | const gop_field = enum_obj.fields.getOrPutAssumeCapacity(field_name); | 2972 | const gop_field = enum_obj.fields.getOrPutAssumeCapacity(field_name); |
| 2936 | if (gop_field.found_existing) { | 2973 | if (gop_field.found_existing) { |
| 2937 | const tree = try sema.getAstTree(block); | 2974 | const field_src = enum_obj.fieldSrcLoc(sema.mod, .{ .index = field_i }).lazy; |
| 2938 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); | 2975 | const other_field_src = enum_obj.fieldSrcLoc(sema.mod, .{ .index = gop_field.index }).lazy; |
| 2939 | const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop_field.index); | | |
| 2940 | const msg = msg: { | 2976 | const msg = msg: { |
| 2941 | const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name}); | 2977 | const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name}); |
| 2942 | errdefer msg.destroy(gpa); | 2978 | errdefer msg.destroy(gpa); |
| 2943 | try sema.errNote(block, other_tag_src, msg, "other field here", .{}); | 2979 | try sema.errNote(block, other_field_src, msg, "other field here", .{}); |
| 2944 | break :msg msg; | 2980 | break :msg msg; |
| 2945 | }; | 2981 | }; |
| 2946 | return sema.failWithOwnedErrorMsg(msg); | 2982 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -2949,10 +2985,18 @@ fn zirEnumDecl( | ... | @@ -2949,10 +2985,18 @@ fn zirEnumDecl( |
| 2949 | if (has_tag_value) { | 2985 | if (has_tag_value) { |
| 2950 | const tag_val_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 2986 | const tag_val_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 2951 | extra_index += 1; | 2987 | extra_index += 1; |
| 2952 | // TODO: if we need to report an error here, use a source location | 2988 | const tag_inst = try sema.resolveInst(tag_val_ref); |
| 2953 | // that points to this default value expression rather than the struct. | 2989 | const tag_val = sema.resolveConstValue(block, .unneeded, tag_inst, "") catch |err| switch (err) { |
| 2954 | // But only resolve the source location if we need to emit a compile error. | 2990 | error.NeededSourceLocation => { |
| 2955 | const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref, "enum tag value must be comptime-known")).val; | 2991 | const value_src = enum_obj.fieldSrcLoc(sema.mod, .{ |
| | 2992 | .index = field_i, |
| | 2993 | .range = .value, |
| | 2994 | }).lazy; |
| | 2995 | _ = try sema.resolveConstValue(block, value_src, tag_inst, "enum tag value must be comptime-known"); |
| | 2996 | unreachable; |
| | 2997 | }, |
| | 2998 | else => |e| return e, |
| | 2999 | }; |
| 2956 | last_tag_val = tag_val; | 3000 | last_tag_val = tag_val; |
| 2957 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); | 3001 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); |
| 2958 | const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{ | 3002 | const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{ |
| ... | @@ -2960,11 +3004,13 @@ fn zirEnumDecl( | ... | @@ -2960,11 +3004,13 @@ fn zirEnumDecl( |
| 2960 | .mod = mod, | 3004 | .mod = mod, |
| 2961 | }); | 3005 | }); |
| 2962 | if (gop_val.found_existing) { | 3006 | if (gop_val.found_existing) { |
| 2963 | const tree = try sema.getAstTree(block); | 3007 | const value_src = enum_obj.fieldSrcLoc(sema.mod, .{ |
| 2964 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); | 3008 | .index = field_i, |
| 2965 | const other_field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop_val.index); | 3009 | .range = .value, |
| | 3010 | }).lazy; |
| | 3011 | const other_field_src = enum_obj.fieldSrcLoc(sema.mod, .{ .index = gop_val.index }).lazy; |
| 2966 | const msg = msg: { | 3012 | const msg = msg: { |
| 2967 | const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{tag_val.fmtValue(enum_obj.tag_ty, sema.mod)}); | 3013 | const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{tag_val.fmtValue(enum_obj.tag_ty, sema.mod)}); |
| 2968 | errdefer msg.destroy(gpa); | 3014 | errdefer msg.destroy(gpa); |
| 2969 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); | 3015 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); |
| 2970 | break :msg msg; | 3016 | break :msg msg; |
| ... | @@ -2983,9 +3029,8 @@ fn zirEnumDecl( | ... | @@ -2983,9 +3029,8 @@ fn zirEnumDecl( |
| 2983 | .mod = mod, | 3029 | .mod = mod, |
| 2984 | }); | 3030 | }); |
| 2985 | if (gop_val.found_existing) { | 3031 | if (gop_val.found_existing) { |
| 2986 | const tree = try sema.getAstTree(block); | 3032 | const field_src = enum_obj.fieldSrcLoc(sema.mod, .{ .index = field_i }).lazy; |
| 2987 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); | 3033 | const other_field_src = enum_obj.fieldSrcLoc(sema.mod, .{ .index = gop_val.index }).lazy; |
| 2988 | const other_field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop_val.index); | | |
| 2989 | const msg = msg: { | 3034 | const msg = msg: { |
| 2990 | const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{tag_val.fmtValue(enum_obj.tag_ty, sema.mod)}); | 3035 | const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{tag_val.fmtValue(enum_obj.tag_ty, sema.mod)}); |
| 2991 | errdefer msg.destroy(gpa); | 3036 | errdefer msg.destroy(gpa); |
| ... | @@ -3003,9 +3048,11 @@ fn zirEnumDecl( | ... | @@ -3003,9 +3048,11 @@ fn zirEnumDecl( |
| 3003 | } | 3048 | } |
| 3004 | | 3049 | |
| 3005 | if (!(try sema.intFitsInType(last_tag_val.?, enum_obj.tag_ty, null))) { | 3050 | if (!(try sema.intFitsInType(last_tag_val.?, enum_obj.tag_ty, null))) { |
| 3006 | const tree = try sema.getAstTree(block); | 3051 | const value_src = enum_obj.fieldSrcLoc(sema.mod, .{ |
| 3007 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i); | 3052 | .index = field_i, |
| 3008 | const msg = try sema.errMsg(block, field_src, "enumeration value '{}' too large for type '{}'", .{ | 3053 | .range = if (has_tag_value) .value else .name, |
| | 3054 | }).lazy; |
| | 3055 | const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{ |
| 3009 | last_tag_val.?.fmtValue(enum_obj.tag_ty, mod), enum_obj.tag_ty.fmt(mod), | 3056 | last_tag_val.?.fmtValue(enum_obj.tag_ty, mod), enum_obj.tag_ty.fmt(mod), |
| 3010 | }); | 3057 | }); |
| 3011 | return sema.failWithOwnedErrorMsg(msg); | 3058 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -3319,8 +3366,6 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index | ... | @@ -3319,8 +3366,6 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index |
| 3319 | operand_ty.childType() | 3366 | operand_ty.childType() |
| 3320 | else | 3367 | else |
| 3321 | operand_ty; | 3368 | operand_ty; |
| 3322 | // TODO this should be validated in a more generic instruction that is | | |
| 3323 | // emitted for all ifs and whiles with an error union condition. | | |
| 3324 | if (err_union_ty.zigTypeTag() != .ErrorUnion) return; | 3369 | if (err_union_ty.zigTypeTag() != .ErrorUnion) return; |
| 3325 | const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(); | 3370 | const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(); |
| 3326 | if (payload_ty != .Void and payload_ty != .NoReturn) { | 3371 | if (payload_ty != .Void and payload_ty != .NoReturn) { |
| ... | @@ -5908,9 +5953,8 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | ... | @@ -5908,9 +5953,8 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { |
| 5908 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { | 5953 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { |
| 5909 | const src = sema.src; | 5954 | const src = sema.src; |
| 5910 | | 5955 | |
| 5911 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 5956 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return .none; |
| 5912 | if (!backend_supports_error_return_tracing or !sema.mod.comp.bin_file.options.error_return_tracing) | 5957 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return .none; |
| 5913 | return .none; | | |
| 5914 | | 5958 | |
| 5915 | if (block.is_comptime) | 5959 | if (block.is_comptime) |
| 5916 | return .none; | 5960 | return .none; |
| ... | @@ -6148,8 +6192,7 @@ fn zirCall( | ... | @@ -6148,8 +6192,7 @@ fn zirCall( |
| 6148 | if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn) | 6192 | if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn) |
| 6149 | input_is_error = false; // input was an error type, but no errorable fn's were actually called | 6193 | input_is_error = false; // input was an error type, but no errorable fn's were actually called |
| 6150 | | 6194 | |
| 6151 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 6195 | if (sema.mod.backendSupportsFeature(.error_return_trace) and sema.mod.comp.bin_file.options.error_return_tracing and |
| 6152 | if (backend_supports_error_return_tracing and sema.mod.comp.bin_file.options.error_return_tracing and | | |
| 6153 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) | 6196 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) |
| 6154 | { | 6197 | { |
| 6155 | const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: { | 6198 | const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: { |
| ... | @@ -7183,6 +7226,7 @@ fn instantiateGenericCall( | ... | @@ -7183,6 +7226,7 @@ fn instantiateGenericCall( |
| 7183 | return err; | 7226 | return err; |
| 7184 | }, | 7227 | }, |
| 7185 | else => { | 7228 | else => { |
| | 7229 | assert(mod.monomorphed_funcs.remove(new_module_func)); |
| 7186 | { | 7230 | { |
| 7187 | errdefer new_decl_arena.deinit(); | 7231 | errdefer new_decl_arena.deinit(); |
| 7188 | try new_decl.finalizeNewArena(&new_decl_arena); | 7232 | try new_decl.finalizeNewArena(&new_decl_arena); |
| ... | @@ -7936,11 +7980,8 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -7936,11 +7980,8 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7936 | | 7980 | |
| 7937 | try sema.requireRuntimeBlock(block, src, operand_src); | 7981 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 7938 | const result = try block.addTyOp(.intcast, dest_ty, operand); | 7982 | const result = try block.addTyOp(.intcast, dest_ty, operand); |
| 7939 | if (block.wantSafety() and | 7983 | if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum() and |
| 7940 | !dest_ty.isNonexhaustiveEnum() and | 7984 | sema.mod.backendSupportsFeature(.is_named_enum_value)) |
| 7941 | // TODO instead of "use_llvm", check a different condition so that backends | | |
| 7942 | // can advertise themselves as supporting these extra AIR instructions for safety. | | |
| 7943 | sema.mod.comp.bin_file.options.use_llvm) | | |
| 7944 | { | 7985 | { |
| 7945 | const ok = try block.addUnOp(.is_named_enum_value, result); | 7986 | const ok = try block.addUnOp(.is_named_enum_value, result); |
| 7946 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); | 7987 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); |
| ... | @@ -10658,8 +10699,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10658,8 +10699,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10658 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 10699 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 10659 | } | 10700 | } |
| 10660 | | 10701 | |
| 10661 | const backend_supports_is_named_enum = sema.mod.comp.bin_file.options.use_llvm; | | |
| 10662 | | | |
| 10663 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { | 10702 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { |
| 10664 | if (empty_enum) { | 10703 | if (empty_enum) { |
| 10665 | return Air.Inst.Ref.void_value; | 10704 | return Air.Inst.Ref.void_value; |
| ... | @@ -10670,7 +10709,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10670,7 +10709,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10670 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) { | 10709 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) { |
| 10671 | return Air.Inst.Ref.unreachable_value; | 10710 | return Air.Inst.Ref.unreachable_value; |
| 10672 | } | 10711 | } |
| 10673 | if (backend_supports_is_named_enum and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and | 10712 | if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and |
| 10674 | (!operand_ty.isNonexhaustiveEnum() or union_originally)) | 10713 | (!operand_ty.isNonexhaustiveEnum() or union_originally)) |
| 10675 | { | 10714 | { |
| 10676 | try sema.zirDbgStmt(block, cond_dbg_node_index); | 10715 | try sema.zirDbgStmt(block, cond_dbg_node_index); |
| ... | @@ -11140,7 +11179,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11140,7 +11179,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11140 | case_block.wip_capture_scope = wip_captures.scope; | 11179 | case_block.wip_capture_scope = wip_captures.scope; |
| 11141 | case_block.inline_case_capture = .none; | 11180 | case_block.inline_case_capture = .none; |
| 11142 | | 11181 | |
| 11143 | if (backend_supports_is_named_enum and special.body.len != 0 and block.wantSafety() and | 11182 | if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and |
| 11144 | operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally)) | 11183 | operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally)) |
| 11145 | { | 11184 | { |
| 11146 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); | 11185 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); |
| ... | @@ -11453,10 +11492,7 @@ fn validateSwitchNoRange( | ... | @@ -11453,10 +11492,7 @@ fn validateSwitchNoRange( |
| 11453 | } | 11492 | } |
| 11454 | | 11493 | |
| 11455 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { | 11494 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { |
| 11456 | const this_feature_is_implemented_in_the_backend = | 11495 | if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) return false; |
| 11457 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 11458 | | | |
| 11459 | if (!this_feature_is_implemented_in_the_backend) return false; | | |
| 11460 | | 11496 | |
| 11461 | const tags = sema.code.instructions.items(.tag); | 11497 | const tags = sema.code.instructions.items(.tag); |
| 11462 | for (body) |inst| { | 11498 | for (body) |inst| { |
| ... | @@ -16970,20 +17006,17 @@ fn retWithErrTracing( | ... | @@ -16970,20 +17006,17 @@ fn retWithErrTracing( |
| 16970 | } | 17006 | } |
| 16971 | | 17007 | |
| 16972 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { | 17008 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 16973 | // TODO implement this feature in all the backends and then delete this check. | 17009 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return false; |
| 16974 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | | |
| 16975 | | 17010 | |
| 16976 | return fn_ret_ty.isError() and | 17011 | return fn_ret_ty.isError() and |
| 16977 | sema.mod.comp.bin_file.options.error_return_tracing and | 17012 | sema.mod.comp.bin_file.options.error_return_tracing; |
| 16978 | backend_supports_error_return_tracing; | | |
| 16979 | } | 17013 | } |
| 16980 | | 17014 | |
| 16981 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 17015 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 16982 | const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index; | 17016 | const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index; |
| 16983 | | 17017 | |
| 16984 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 17018 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 16985 | const ok = backend_supports_error_return_tracing and sema.mod.comp.bin_file.options.error_return_tracing; | 17019 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return; |
| 16986 | if (!ok) return; | | |
| 16987 | | 17020 | |
| 16988 | // This is only relevant at runtime. | 17021 | // This is only relevant at runtime. |
| 16989 | if (block.is_comptime or block.is_typeof) return; | 17022 | if (block.is_comptime or block.is_typeof) return; |
| ... | @@ -17005,11 +17038,9 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) | ... | @@ -17005,11 +17038,9 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) |
| 17005 | // This is only relevant at runtime. | 17038 | // This is only relevant at runtime. |
| 17006 | if (start_block.is_comptime or start_block.is_typeof) return; | 17039 | if (start_block.is_comptime or start_block.is_typeof) return; |
| 17007 | | 17040 | |
| 17008 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 17041 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 17009 | const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and | 17042 | if (!sema.owner_func.?.calls_or_awaits_errorable_fn) return; |
| 17010 | sema.mod.comp.bin_file.options.error_return_tracing and | 17043 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return; |
| 17011 | backend_supports_error_return_tracing; | | |
| 17012 | if (!ok) return; | | |
| 17013 | | 17044 | |
| 17014 | const tracy = trace(@src()); | 17045 | const tracy = trace(@src()); |
| 17015 | defer tracy.end(); | 17046 | defer tracy.end(); |
| ... | @@ -17988,14 +18019,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -17988,14 +18019,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 17988 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); | 18019 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 17989 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); | 18020 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); |
| 17990 | | 18021 | |
| 17991 | // TODO implement this feature in all the backends and then delete this check. | | |
| 17992 | const backend_supports_error_return_tracing = | | |
| 17993 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 17994 | | | |
| 17995 | if (sema.owner_func != null and | 18022 | if (sema.owner_func != null and |
| 17996 | sema.owner_func.?.calls_or_awaits_errorable_fn and | 18023 | sema.owner_func.?.calls_or_awaits_errorable_fn and |
| 17997 | sema.mod.comp.bin_file.options.error_return_tracing and | 18024 | sema.mod.comp.bin_file.options.error_return_tracing and |
| 17998 | backend_supports_error_return_tracing) | 18025 | sema.mod.backendSupportsFeature(.error_return_trace)) |
| 17999 | { | 18026 | { |
| 18000 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); | 18027 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 18001 | } | 18028 | } |
| ... | @@ -18175,7 +18202,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18175,7 +18202,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18175 | return sema.addStrLit(block, field_name); | 18202 | return sema.addStrLit(block, field_name); |
| 18176 | } | 18203 | } |
| 18177 | try sema.requireRuntimeBlock(block, src, operand_src); | 18204 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 18178 | if (block.wantSafety() and sema.mod.comp.bin_file.options.use_llvm) { | 18205 | if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) { |
| 18179 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); | 18206 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); |
| 18180 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); | 18207 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); |
| 18181 | } | 18208 | } |
| ... | @@ -19469,7 +19496,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -19469,7 +19496,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 19469 | } | 19496 | } |
| 19470 | | 19497 | |
| 19471 | try sema.requireRuntimeBlock(block, src, operand_src); | 19498 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 19472 | if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.comp.bin_file.options.use_llvm) { | 19499 | if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.backendSupportsFeature(.error_set_has_value)) { |
| 19473 | const err_int_inst = try block.addBitCast(Type.err_int, operand); | 19500 | const err_int_inst = try block.addBitCast(Type.err_int, operand); |
| 19474 | const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst); | 19501 | const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst); |
| 19475 | try sema.addSafetyCheck(block, ok, .invalid_error_code); | 19502 | try sema.addSafetyCheck(block, ok, .invalid_error_code); |
| ... | @@ -21596,7 +21623,7 @@ fn zirVarExtended( | ... | @@ -21596,7 +21623,7 @@ fn zirVarExtended( |
| 21596 | .owner_decl = sema.owner_decl_index, | 21623 | .owner_decl = sema.owner_decl_index, |
| 21597 | .init = init_val, | 21624 | .init = init_val, |
| 21598 | .is_extern = small.is_extern, | 21625 | .is_extern = small.is_extern, |
| 21599 | .is_mutable = true, // TODO get rid of this unused field | 21626 | .is_mutable = true, |
| 21600 | .is_threadlocal = small.is_threadlocal, | 21627 | .is_threadlocal = small.is_threadlocal, |
| 21601 | .is_weak_linkage = false, | 21628 | .is_weak_linkage = false, |
| 21602 | .lib_name = null, | 21629 | .lib_name = null, |
| ... | @@ -22075,7 +22102,7 @@ fn zirBuiltinExtern( | ... | @@ -22075,7 +22102,7 @@ fn zirBuiltinExtern( |
| 22075 | .owner_decl = sema.owner_decl_index, | 22102 | .owner_decl = sema.owner_decl_index, |
| 22076 | .init = Value.initTag(.unreachable_value), | 22103 | .init = Value.initTag(.unreachable_value), |
| 22077 | .is_extern = true, | 22104 | .is_extern = true, |
| 22078 | .is_mutable = false, // TODO get rid of this unused field | 22105 | .is_mutable = false, |
| 22079 | .is_threadlocal = options.is_thread_local, | 22106 | .is_threadlocal = options.is_thread_local, |
| 22080 | .is_weak_linkage = options.linkage == .Weak, | 22107 | .is_weak_linkage = options.linkage == .Weak, |
| 22081 | .lib_name = null, | 22108 | .lib_name = null, |
| ... | @@ -22658,11 +22685,7 @@ fn panicWithMsg( | ... | @@ -22658,11 +22685,7 @@ fn panicWithMsg( |
| 22658 | const mod = sema.mod; | 22685 | const mod = sema.mod; |
| 22659 | const arena = sema.arena; | 22686 | const arena = sema.arena; |
| 22660 | | 22687 | |
| 22661 | const this_feature_is_implemented_in_the_backend = | 22688 | if (!mod.backendSupportsFeature(.panic_fn)) { |
| 22662 | mod.comp.bin_file.options.target.ofmt == .c or | | |
| 22663 | mod.comp.bin_file.options.use_llvm; | | |
| 22664 | if (!this_feature_is_implemented_in_the_backend) { | | |
| 22665 | // TODO implement this feature in all the backends and then delete this branch | | |
| 22666 | _ = try block.addNoOp(.breakpoint); | 22689 | _ = try block.addNoOp(.breakpoint); |
| 22667 | _ = try block.addNoOp(.unreach); | 22690 | _ = try block.addNoOp(.unreach); |
| 22668 | return; | 22691 | return; |
| ... | @@ -22711,11 +22734,7 @@ fn panicUnwrapError( | ... | @@ -22711,11 +22734,7 @@ fn panicUnwrapError( |
| 22711 | defer fail_block.instructions.deinit(gpa); | 22734 | defer fail_block.instructions.deinit(gpa); |
| 22712 | | 22735 | |
| 22713 | { | 22736 | { |
| 22714 | const this_feature_is_implemented_in_the_backend = | 22737 | if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) { |
| 22715 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 22716 | | | |
| 22717 | if (!this_feature_is_implemented_in_the_backend) { | | |
| 22718 | // TODO implement this feature in all the backends and then delete this branch | | |
| 22719 | _ = try fail_block.addNoOp(.breakpoint); | 22738 | _ = try fail_block.addNoOp(.breakpoint); |
| 22720 | _ = try fail_block.addNoOp(.unreach); | 22739 | _ = try fail_block.addNoOp(.unreach); |
| 22721 | } else { | 22740 | } else { |
| ... | @@ -22841,18 +22860,12 @@ fn safetyCheckFormatted( | ... | @@ -22841,18 +22860,12 @@ fn safetyCheckFormatted( |
| 22841 | | 22860 | |
| 22842 | defer fail_block.instructions.deinit(gpa); | 22861 | defer fail_block.instructions.deinit(gpa); |
| 22843 | | 22862 | |
| 22844 | { | 22863 | if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) { |
| 22845 | const this_feature_is_implemented_in_the_backend = | 22864 | _ = try fail_block.addNoOp(.breakpoint); |
| 22846 | sema.mod.comp.bin_file.options.use_llvm; | 22865 | _ = try fail_block.addNoOp(.unreach); |
| 22847 | | 22866 | } else { |
| 22848 | if (!this_feature_is_implemented_in_the_backend) { | 22867 | const panic_fn = try sema.getBuiltin(func); |
| 22849 | // TODO implement this feature in all the backends and then delete this branch | 22868 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); |
| 22850 | _ = try fail_block.addNoOp(.breakpoint); | | |
| 22851 | _ = try fail_block.addNoOp(.unreach); | | |
| 22852 | } else { | | |
| 22853 | const panic_fn = try sema.getBuiltin(func); | | |
| 22854 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); | | |
| 22855 | } | | |
| 22856 | } | 22869 | } |
| 22857 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22870 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22858 | } | 22871 | } |
| ... | @@ -24517,7 +24530,7 @@ fn coerceExtra( | ... | @@ -24517,7 +24530,7 @@ fn coerceExtra( |
| 24517 | return block.addBitCast(dest_ty, inst); | 24530 | return block.addBitCast(dest_ty, inst); |
| 24518 | } | 24531 | } |
| 24519 | | 24532 | |
| 24520 | const is_undef = if (maybe_inst_val) |val| val.isUndef() else false; | 24533 | const is_undef = inst_ty.zigTypeTag() == .Undefined; |
| 24521 | | 24534 | |
| 24522 | switch (dest_ty.zigTypeTag()) { | 24535 | switch (dest_ty.zigTypeTag()) { |
| 24523 | .Optional => optional: { | 24536 | .Optional => optional: { |
| ... | @@ -30662,14 +30675,13 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30662,14 +30675,13 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30662 | const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); | 30675 | const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); |
| 30663 | if (gop.found_existing) { | 30676 | if (gop.found_existing) { |
| 30664 | const msg = msg: { | 30677 | const msg = msg: { |
| 30665 | const tree = try sema.getAstTree(&block_scope); | 30678 | const field_src = struct_obj.fieldSrcLoc(sema.mod, .{ .index = field_i }).lazy; |
| 30666 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | | |
| 30667 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name}); | 30679 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name}); |
| 30668 | errdefer msg.destroy(gpa); | 30680 | errdefer msg.destroy(gpa); |
| 30669 | | 30681 | |
| 30670 | const prev_field_index = struct_obj.fields.getIndex(field_name).?; | 30682 | const prev_field_index = struct_obj.fields.getIndex(field_name).?; |
| 30671 | const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index); | 30683 | const prev_field_src = struct_obj.fieldSrcLoc(sema.mod, .{ .index = prev_field_index }); |
| 30672 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); | 30684 | try sema.mod.errNoteNonLazy(prev_field_src, msg, "other field here", .{}); |
| 30673 | try sema.errNote(&block_scope, src, msg, "struct declared here", .{}); | 30685 | try sema.errNote(&block_scope, src, msg, "struct declared here", .{}); |
| 30674 | break :msg msg; | 30686 | break :msg msg; |
| 30675 | }; | 30687 | }; |
| ... | @@ -30699,34 +30711,51 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30699,34 +30711,51 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30699 | // so that init values may depend on type layout. | 30711 | // so that init values may depend on type layout. |
| 30700 | const bodies_index = extra_index; | 30712 | const bodies_index = extra_index; |
| 30701 | | 30713 | |
| 30702 | for (fields) |zir_field, i| { | 30714 | for (fields) |zir_field, field_i| { |
| 30703 | // TODO emit compile errors for invalid field types | | |
| 30704 | // such as arrays and pointers inside packed structs. | | |
| 30705 | const field_ty: Type = ty: { | 30715 | const field_ty: Type = ty: { |
| 30706 | if (zir_field.type_ref != .none) { | 30716 | if (zir_field.type_ref != .none) { |
| 30707 | // TODO: if we need to report an error here, use a source location | 30717 | break :ty sema.resolveType(&block_scope, .unneeded, zir_field.type_ref) catch |err| switch (err) { |
| 30708 | // that points to this type expression rather than the struct. | 30718 | error.NeededSourceLocation => { |
| 30709 | // But only resolve the source location if we need to emit a compile error. | 30719 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30710 | break :ty try sema.resolveType(&block_scope, src, zir_field.type_ref); | 30720 | .index = field_i, |
| | 30721 | .range = .type, |
| | 30722 | }).lazy; |
| | 30723 | _ = try sema.resolveType(&block_scope, ty_src, zir_field.type_ref); |
| | 30724 | unreachable; |
| | 30725 | }, |
| | 30726 | else => |e| return e, |
| | 30727 | }; |
| 30711 | } | 30728 | } |
| 30712 | assert(zir_field.type_body_len != 0); | 30729 | assert(zir_field.type_body_len != 0); |
| 30713 | const body = zir.extra[extra_index..][0..zir_field.type_body_len]; | 30730 | const body = zir.extra[extra_index..][0..zir_field.type_body_len]; |
| 30714 | extra_index += body.len; | 30731 | extra_index += body.len; |
| 30715 | const ty_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); | 30732 | const ty_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); |
| 30716 | break :ty try sema.analyzeAsType(&block_scope, src, ty_ref); | 30733 | break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) { |
| | 30734 | error.NeededSourceLocation => { |
| | 30735 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| | 30736 | .index = field_i, |
| | 30737 | .range = .type, |
| | 30738 | }).lazy; |
| | 30739 | _ = try sema.analyzeAsType(&block_scope, ty_src, ty_ref); |
| | 30740 | unreachable; |
| | 30741 | }, |
| | 30742 | else => |e| return e, |
| | 30743 | }; |
| 30717 | }; | 30744 | }; |
| 30718 | if (field_ty.tag() == .generic_poison) { | 30745 | if (field_ty.tag() == .generic_poison) { |
| 30719 | return error.GenericPoison; | 30746 | return error.GenericPoison; |
| 30720 | } | 30747 | } |
| 30721 | | 30748 | |
| 30722 | const field = &struct_obj.fields.values()[i]; | 30749 | const field = &struct_obj.fields.values()[field_i]; |
| 30723 | field.ty = try field_ty.copy(decl_arena_allocator); | 30750 | field.ty = try field_ty.copy(decl_arena_allocator); |
| 30724 | | 30751 | |
| 30725 | if (field_ty.zigTypeTag() == .Opaque) { | 30752 | if (field_ty.zigTypeTag() == .Opaque) { |
| 30726 | const msg = msg: { | 30753 | const msg = msg: { |
| 30727 | const tree = try sema.getAstTree(&block_scope); | 30754 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30728 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30755 | .index = field_i, |
| 30729 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 30756 | .range = .type, |
| | 30757 | }).lazy; |
| | 30758 | const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 30730 | errdefer msg.destroy(sema.gpa); | 30759 | errdefer msg.destroy(sema.gpa); |
| 30731 | | 30760 | |
| 30732 | try sema.addDeclaredHereNote(msg, field_ty); | 30761 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -30736,9 +30765,11 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30736,9 +30765,11 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30736 | } | 30765 | } |
| 30737 | if (field_ty.zigTypeTag() == .NoReturn) { | 30766 | if (field_ty.zigTypeTag() == .NoReturn) { |
| 30738 | const msg = msg: { | 30767 | const msg = msg: { |
| 30739 | const tree = try sema.getAstTree(&block_scope); | 30768 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30740 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30769 | .index = field_i, |
| 30741 | const msg = try sema.errMsg(&block_scope, field_src, "struct fields cannot be 'noreturn'", .{}); | 30770 | .range = .type, |
| | 30771 | }).lazy; |
| | 30772 | const msg = try sema.errMsg(&block_scope, ty_src, "struct fields cannot be 'noreturn'", .{}); |
| 30742 | errdefer msg.destroy(sema.gpa); | 30773 | errdefer msg.destroy(sema.gpa); |
| 30743 | | 30774 | |
| 30744 | try sema.addDeclaredHereNote(msg, field_ty); | 30775 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -30748,12 +30779,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30748,12 +30779,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30748 | } | 30779 | } |
| 30749 | if (struct_obj.layout == .Extern and !try sema.validateExternType(field.ty, .struct_field)) { | 30780 | if (struct_obj.layout == .Extern and !try sema.validateExternType(field.ty, .struct_field)) { |
| 30750 | const msg = msg: { | 30781 | const msg = msg: { |
| 30751 | const tree = try sema.getAstTree(&block_scope); | 30782 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30752 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30783 | .index = field_i, |
| 30753 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 30784 | .range = .type, |
| | 30785 | }); |
| | 30786 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 30754 | errdefer msg.destroy(sema.gpa); | 30787 | errdefer msg.destroy(sema.gpa); |
| 30755 | | 30788 | |
| 30756 | try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .struct_field); | 30789 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field.ty, .struct_field); |
| 30757 | | 30790 | |
| 30758 | try sema.addDeclaredHereNote(msg, field.ty); | 30791 | try sema.addDeclaredHereNote(msg, field.ty); |
| 30759 | break :msg msg; | 30792 | break :msg msg; |
| ... | @@ -30761,12 +30794,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30761,12 +30794,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30761 | return sema.failWithOwnedErrorMsg(msg); | 30794 | return sema.failWithOwnedErrorMsg(msg); |
| 30762 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) { | 30795 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) { |
| 30763 | const msg = msg: { | 30796 | const msg = msg: { |
| 30764 | const tree = try sema.getAstTree(&block_scope); | 30797 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30765 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30798 | .index = field_i, |
| 30766 | const msg = try sema.errMsg(&block_scope, fields_src, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 30799 | .range = .type, |
| | 30800 | }); |
| | 30801 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 30767 | errdefer msg.destroy(sema.gpa); | 30802 | errdefer msg.destroy(sema.gpa); |
| 30768 | | 30803 | |
| 30769 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field.ty); | 30804 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field.ty); |
| 30770 | | 30805 | |
| 30771 | try sema.addDeclaredHereNote(msg, field.ty); | 30806 | try sema.addDeclaredHereNote(msg, field.ty); |
| 30772 | break :msg msg; | 30807 | break :msg msg; |
| ... | @@ -30778,7 +30813,17 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30778,7 +30813,17 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30778 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; | 30813 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; |
| 30779 | extra_index += body.len; | 30814 | extra_index += body.len; |
| 30780 | const align_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); | 30815 | const align_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); |
| 30781 | field.abi_align = try sema.analyzeAsAlign(&block_scope, src, align_ref); | 30816 | field.abi_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| | 30817 | error.NeededSourceLocation => { |
| | 30818 | const align_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| | 30819 | .index = field_i, |
| | 30820 | .range = .alignment, |
| | 30821 | }).lazy; |
| | 30822 | _ = try sema.analyzeAsAlign(&block_scope, align_src, align_ref); |
| | 30823 | unreachable; |
| | 30824 | }, |
| | 30825 | else => |e| return e, |
| | 30826 | }; |
| 30782 | } | 30827 | } |
| 30783 | | 30828 | |
| 30784 | extra_index += zir_field.init_body_len; | 30829 | extra_index += zir_field.init_body_len; |
| ... | @@ -30788,26 +30833,30 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30788,26 +30833,30 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30788 | | 30833 | |
| 30789 | if (any_inits) { | 30834 | if (any_inits) { |
| 30790 | extra_index = bodies_index; | 30835 | extra_index = bodies_index; |
| 30791 | for (fields) |zir_field, i| { | 30836 | for (fields) |zir_field, field_i| { |
| 30792 | extra_index += zir_field.type_body_len; | 30837 | extra_index += zir_field.type_body_len; |
| 30793 | extra_index += zir_field.align_body_len; | 30838 | extra_index += zir_field.align_body_len; |
| 30794 | if (zir_field.init_body_len > 0) { | 30839 | if (zir_field.init_body_len > 0) { |
| 30795 | const body = zir.extra[extra_index..][0..zir_field.init_body_len]; | 30840 | const body = zir.extra[extra_index..][0..zir_field.init_body_len]; |
| 30796 | extra_index += body.len; | 30841 | extra_index += body.len; |
| 30797 | const init = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); | 30842 | const init = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); |
| 30798 | const field = &struct_obj.fields.values()[i]; | 30843 | const field = &struct_obj.fields.values()[field_i]; |
| 30799 | const coerced = sema.coerce(&block_scope, field.ty, init, .unneeded) catch |err| switch (err) { | 30844 | const coerced = sema.coerce(&block_scope, field.ty, init, .unneeded) catch |err| switch (err) { |
| 30800 | error.NeededSourceLocation => { | 30845 | error.NeededSourceLocation => { |
| 30801 | const tree = try sema.getAstTree(&block_scope); | 30846 | const init_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30802 | const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i); | 30847 | .index = field_i, |
| | 30848 | .range = .value, |
| | 30849 | }).lazy; |
| 30803 | _ = try sema.coerce(&block_scope, field.ty, init, init_src); | 30850 | _ = try sema.coerce(&block_scope, field.ty, init, init_src); |
| 30804 | unreachable; | 30851 | unreachable; |
| 30805 | }, | 30852 | }, |
| 30806 | else => |e| return e, | 30853 | else => |e| return e, |
| 30807 | }; | 30854 | }; |
| 30808 | const default_val = (try sema.resolveMaybeUndefVal(coerced)) orelse { | 30855 | const default_val = (try sema.resolveMaybeUndefVal(coerced)) orelse { |
| 30809 | const tree = try sema.getAstTree(&block_scope); | 30856 | const init_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30810 | const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i); | 30857 | .index = field_i, |
| | 30858 | .range = .value, |
| | 30859 | }).lazy; |
| 30811 | return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known"); | 30860 | return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known"); |
| 30812 | }; | 30861 | }; |
| 30813 | field.default_val = try default_val.copy(decl_arena_allocator); | 30862 | field.default_val = try default_val.copy(decl_arena_allocator); |
| ... | @@ -31023,9 +31072,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31023,9 +31072,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31023 | | 31072 | |
| 31024 | if (enum_value_map) |map| { | 31073 | if (enum_value_map) |map| { |
| 31025 | const copied_val = if (tag_ref != .none) blk: { | 31074 | const copied_val = if (tag_ref != .none) blk: { |
| 31026 | const tag_src = src; // TODO better source location | 31075 | const val = sema.semaUnionFieldVal(&block_scope, .unneeded, int_tag_ty, tag_ref) catch |err| switch (err) { |
| 31027 | const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); | 31076 | error.NeededSourceLocation => { |
| 31028 | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime-known"); | 31077 | const val_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| | 31078 | .index = field_i, |
| | 31079 | .range = .value, |
| | 31080 | }).lazy; |
| | 31081 | _ = try sema.semaUnionFieldVal(&block_scope, val_src, int_tag_ty, tag_ref); |
| | 31082 | unreachable; |
| | 31083 | }, |
| | 31084 | else => |e| return e, |
| | 31085 | }; |
| 31029 | last_tag_val = val; | 31086 | last_tag_val = val; |
| 31030 | | 31087 | |
| 31031 | // This puts the memory into the union arena, not the enum arena, but | 31088 | // This puts the memory into the union arena, not the enum arena, but |
| ... | @@ -31045,9 +31102,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31045,9 +31102,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31045 | .mod = mod, | 31102 | .mod = mod, |
| 31046 | }); | 31103 | }); |
| 31047 | if (gop.found_existing) { | 31104 | if (gop.found_existing) { |
| 31048 | const tree = try sema.getAstTree(&block_scope); | 31105 | const field_src = union_obj.fieldSrcLoc(sema.mod, .{ .index = field_i }).lazy; |
| 31049 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, field_i); | 31106 | const other_field_src = union_obj.fieldSrcLoc(sema.mod, .{ .index = gop.index }).lazy; |
| 31050 | const other_field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, gop.index); | | |
| 31051 | const msg = msg: { | 31107 | const msg = msg: { |
| 31052 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, sema.mod)}); | 31108 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, sema.mod)}); |
| 31053 | errdefer msg.destroy(gpa); | 31109 | errdefer msg.destroy(gpa); |
| ... | @@ -31069,10 +31125,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31069,10 +31125,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31069 | else if (field_type_ref == .none) | 31125 | else if (field_type_ref == .none) |
| 31070 | Type.initTag(.noreturn) | 31126 | Type.initTag(.noreturn) |
| 31071 | else | 31127 | else |
| 31072 | // TODO: if we need to report an error here, use a source location | 31128 | sema.resolveType(&block_scope, .unneeded, field_type_ref) catch |err| switch (err) { |
| 31073 | // that points to this type expression rather than the union. | 31129 | error.NeededSourceLocation => { |
| 31074 | // But only resolve the source location if we need to emit a compile error. | 31130 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31075 | try sema.resolveType(&block_scope, src, field_type_ref); | 31131 | .index = field_i, |
| | 31132 | .range = .type, |
| | 31133 | }).lazy; |
| | 31134 | _ = try sema.resolveType(&block_scope, ty_src, field_type_ref); |
| | 31135 | unreachable; |
| | 31136 | }, |
| | 31137 | else => |e| return e, |
| | 31138 | }; |
| 31076 | | 31139 | |
| 31077 | if (field_ty.tag() == .generic_poison) { | 31140 | if (field_ty.tag() == .generic_poison) { |
| 31078 | return error.GenericPoison; | 31141 | return error.GenericPoison; |
| ... | @@ -31081,13 +31144,12 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31081,13 +31144,12 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31081 | const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); | 31144 | const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); |
| 31082 | if (gop.found_existing) { | 31145 | if (gop.found_existing) { |
| 31083 | const msg = msg: { | 31146 | const msg = msg: { |
| 31084 | const tree = try sema.getAstTree(&block_scope); | 31147 | const field_src = union_obj.fieldSrcLoc(sema.mod, .{ .index = field_i }).lazy; |
| 31085 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | | |
| 31086 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name}); | 31148 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name}); |
| 31087 | errdefer msg.destroy(gpa); | 31149 | errdefer msg.destroy(gpa); |
| 31088 | | 31150 | |
| 31089 | const prev_field_index = union_obj.fields.getIndex(field_name).?; | 31151 | const prev_field_index = union_obj.fields.getIndex(field_name).?; |
| 31090 | const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index); | 31152 | const prev_field_src = union_obj.fieldSrcLoc(sema.mod, .{ .index = prev_field_index }).lazy; |
| 31091 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); | 31153 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); |
| 31092 | try sema.errNote(&block_scope, src, msg, "union declared here", .{}); | 31154 | try sema.errNote(&block_scope, src, msg, "union declared here", .{}); |
| 31093 | break :msg msg; | 31155 | break :msg msg; |
| ... | @@ -31099,9 +31161,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31099,9 +31161,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31099 | const enum_has_field = names.orderedRemove(field_name); | 31161 | const enum_has_field = names.orderedRemove(field_name); |
| 31100 | if (!enum_has_field) { | 31162 | if (!enum_has_field) { |
| 31101 | const msg = msg: { | 31163 | const msg = msg: { |
| 31102 | const tree = try sema.getAstTree(&block_scope); | 31164 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31103 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31165 | .index = field_i, |
| 31104 | const msg = try sema.errMsg(&block_scope, field_src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) }); | 31166 | .range = .type, |
| | 31167 | }).lazy; |
| | 31168 | const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) }); |
| 31105 | errdefer msg.destroy(sema.gpa); | 31169 | errdefer msg.destroy(sema.gpa); |
| 31106 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); | 31170 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); |
| 31107 | break :msg msg; | 31171 | break :msg msg; |
| ... | @@ -31112,9 +31176,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31112,9 +31176,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31112 | | 31176 | |
| 31113 | if (field_ty.zigTypeTag() == .Opaque) { | 31177 | if (field_ty.zigTypeTag() == .Opaque) { |
| 31114 | const msg = msg: { | 31178 | const msg = msg: { |
| 31115 | const tree = try sema.getAstTree(&block_scope); | 31179 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31116 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31180 | .index = field_i, |
| 31117 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); | 31181 | .range = .type, |
| | 31182 | }).lazy; |
| | 31183 | const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| 31118 | errdefer msg.destroy(sema.gpa); | 31184 | errdefer msg.destroy(sema.gpa); |
| 31119 | | 31185 | |
| 31120 | try sema.addDeclaredHereNote(msg, field_ty); | 31186 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -31124,12 +31190,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31124,12 +31190,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31124 | } | 31190 | } |
| 31125 | if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) { | 31191 | if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) { |
| 31126 | const msg = msg: { | 31192 | const msg = msg: { |
| 31127 | const tree = try sema.getAstTree(&block_scope); | 31193 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31128 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31194 | .index = field_i, |
| 31129 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 31195 | .range = .type, |
| | 31196 | }); |
| | 31197 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 31130 | errdefer msg.destroy(sema.gpa); | 31198 | errdefer msg.destroy(sema.gpa); |
| 31131 | | 31199 | |
| 31132 | try sema.explainWhyTypeIsNotExtern(msg, field_src.toSrcLoc(decl), field_ty, .union_field); | 31200 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .union_field); |
| 31133 | | 31201 | |
| 31134 | try sema.addDeclaredHereNote(msg, field_ty); | 31202 | try sema.addDeclaredHereNote(msg, field_ty); |
| 31135 | break :msg msg; | 31203 | break :msg msg; |
| ... | @@ -31137,12 +31205,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31137,12 +31205,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31137 | return sema.failWithOwnedErrorMsg(msg); | 31205 | return sema.failWithOwnedErrorMsg(msg); |
| 31138 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { | 31206 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { |
| 31139 | const msg = msg: { | 31207 | const msg = msg: { |
| 31140 | const tree = try sema.getAstTree(&block_scope); | 31208 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31141 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31209 | .index = field_i, |
| 31142 | const msg = try sema.errMsg(&block_scope, fields_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 31210 | .range = .type, |
| | 31211 | }); |
| | 31212 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 31143 | errdefer msg.destroy(sema.gpa); | 31213 | errdefer msg.destroy(sema.gpa); |
| 31144 | | 31214 | |
| 31145 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field_ty); | 31215 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); |
| 31146 | | 31216 | |
| 31147 | try sema.addDeclaredHereNote(msg, field_ty); | 31217 | try sema.addDeclaredHereNote(msg, field_ty); |
| 31148 | break :msg msg; | 31218 | break :msg msg; |
| ... | @@ -31156,10 +31226,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31156,10 +31226,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31156 | }; | 31226 | }; |
| 31157 | | 31227 | |
| 31158 | if (align_ref != .none) { | 31228 | if (align_ref != .none) { |
| 31159 | // TODO: if we need to report an error here, use a source location | 31229 | gop.value_ptr.abi_align = sema.resolveAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| 31160 | // that points to this alignment expression rather than the struct. | 31230 | error.NeededSourceLocation => { |
| 31161 | // But only resolve the source location if we need to emit a compile error. | 31231 | const align_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31162 | gop.value_ptr.abi_align = try sema.resolveAlign(&block_scope, src, align_ref); | 31232 | .index = field_i, |
| | 31233 | .range = .alignment, |
| | 31234 | }).lazy; |
| | 31235 | _ = try sema.resolveAlign(&block_scope, align_src, align_ref); |
| | 31236 | unreachable; |
| | 31237 | }, |
| | 31238 | else => |e| return e, |
| | 31239 | }; |
| 31163 | } else { | 31240 | } else { |
| 31164 | gop.value_ptr.abi_align = 0; | 31241 | gop.value_ptr.abi_align = 0; |
| 31165 | } | 31242 | } |
| ... | @@ -31184,6 +31261,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31184,6 +31261,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31184 | } | 31261 | } |
| 31185 | } | 31262 | } |
| 31186 | | 31263 | |
| | 31264 | fn semaUnionFieldVal(sema: *Sema, block: *Block, src: LazySrcLoc, int_tag_ty: Type, tag_ref: Air.Inst.Ref) CompileError!Value { |
| | 31265 | const coerced = try sema.coerce(block, int_tag_ty, tag_ref, src); |
| | 31266 | return sema.resolveConstValue(block, src, coerced, "enum tag value must be comptime-known"); |
| | 31267 | } |
| | 31268 | |
| 31187 | fn generateUnionTagTypeNumbered( | 31269 | fn generateUnionTagTypeNumbered( |
| 31188 | sema: *Sema, | 31270 | sema: *Sema, |
| 31189 | block: *Block, | 31271 | block: *Block, |
| ... | @@ -31607,102 +31689,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -31607,102 +31689,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 31607 | } | 31689 | } |
| 31608 | } | 31690 | } |
| 31609 | | 31691 | |
| 31610 | fn getAstTree(sema: *Sema, block: *Block) CompileError!*const std.zig.Ast { | | |
| 31611 | return block.namespace.file_scope.getTree(sema.gpa) catch |err| { | | |
| 31612 | log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); | | |
| 31613 | return error.AnalysisFail; | | |
| 31614 | }; | | |
| 31615 | } | | |
| 31616 | | | |
| 31617 | fn enumFieldSrcLoc( | | |
| 31618 | decl: *Decl, | | |
| 31619 | tree: std.zig.Ast, | | |
| 31620 | node_offset: i32, | | |
| 31621 | field_index: usize, | | |
| 31622 | ) LazySrcLoc { | | |
| 31623 | @setCold(true); | | |
| 31624 | const field_node = containerFieldNode(decl, tree, node_offset, field_index) orelse | | |
| 31625 | return LazySrcLoc.nodeOffset(0); | | |
| 31626 | return decl.nodeSrcLoc(field_node); | | |
| 31627 | } | | |
| 31628 | | | |
| 31629 | fn containerFieldInitSrcLoc( | | |
| 31630 | decl: *Decl, | | |
| 31631 | tree: std.zig.Ast, | | |
| 31632 | node_offset: i32, | | |
| 31633 | field_index: usize, | | |
| 31634 | ) LazySrcLoc { | | |
| 31635 | @setCold(true); | | |
| 31636 | const node_tags = tree.nodes.items(.tag); | | |
| 31637 | const field_node = containerFieldNode(decl, tree, node_offset, field_index) orelse | | |
| 31638 | return LazySrcLoc.nodeOffset(0); | | |
| 31639 | const node_data = tree.nodes.items(.data)[field_node]; | | |
| 31640 | | | |
| 31641 | const init_node = switch (node_tags[field_node]) { | | |
| 31642 | .container_field_init => node_data.rhs, | | |
| 31643 | .container_field => blk: { | | |
| 31644 | const extra_data = tree.extraData(node_data.rhs, std.zig.Ast.Node.ContainerField); | | |
| 31645 | break :blk extra_data.value_expr; | | |
| 31646 | }, | | |
| 31647 | else => unreachable, | | |
| 31648 | }; | | |
| 31649 | | | |
| 31650 | return decl.nodeSrcLoc(init_node); | | |
| 31651 | } | | |
| 31652 | | | |
| 31653 | fn containerFieldNode( | | |
| 31654 | decl: *Decl, | | |
| 31655 | tree: std.zig.Ast, | | |
| 31656 | node_offset: i32, | | |
| 31657 | field_index: usize, | | |
| 31658 | ) ?std.zig.Ast.Node.Index { | | |
| 31659 | @setCold(true); | | |
| 31660 | const enum_node = decl.relativeToNodeIndex(node_offset); | | |
| 31661 | const node_tags = tree.nodes.items(.tag); | | |
| 31662 | var buffer: [2]std.zig.Ast.Node.Index = undefined; | | |
| 31663 | const container_decl = switch (node_tags[enum_node]) { | | |
| 31664 | .root => tree.containerDeclRoot(), | | |
| 31665 | | | |
| 31666 | .container_decl, | | |
| 31667 | .container_decl_trailing, | | |
| 31668 | => tree.containerDecl(enum_node), | | |
| 31669 | | | |
| 31670 | .container_decl_two, | | |
| 31671 | .container_decl_two_trailing, | | |
| 31672 | => tree.containerDeclTwo(&buffer, enum_node), | | |
| 31673 | | | |
| 31674 | .container_decl_arg, | | |
| 31675 | .container_decl_arg_trailing, | | |
| 31676 | => tree.containerDeclArg(enum_node), | | |
| 31677 | | | |
| 31678 | .tagged_union, | | |
| 31679 | .tagged_union_trailing, | | |
| 31680 | => tree.taggedUnion(enum_node), | | |
| 31681 | .tagged_union_two, | | |
| 31682 | .tagged_union_two_trailing, | | |
| 31683 | => tree.taggedUnionTwo(&buffer, enum_node), | | |
| 31684 | .tagged_union_enum_tag, | | |
| 31685 | .tagged_union_enum_tag_trailing, | | |
| 31686 | => tree.taggedUnionEnumTag(enum_node), | | |
| 31687 | | | |
| 31688 | else => return null, | | |
| 31689 | }; | | |
| 31690 | var it_index: usize = 0; | | |
| 31691 | for (container_decl.ast.members) |member_node| { | | |
| 31692 | switch (node_tags[member_node]) { | | |
| 31693 | .container_field_init, | | |
| 31694 | .container_field_align, | | |
| 31695 | .container_field, | | |
| 31696 | => { | | |
| 31697 | if (it_index == field_index) return member_node; | | |
| 31698 | it_index += 1; | | |
| 31699 | }, | | |
| 31700 | | | |
| 31701 | else => continue, | | |
| 31702 | } | | |
| 31703 | } else unreachable; | | |
| 31704 | } | | |
| 31705 | | | |
| 31706 | /// Returns the type of the AIR instruction. | 31692 | /// Returns the type of the AIR instruction. |
| 31707 | fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type { | 31693 | fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type { |
| 31708 | return sema.getTmpAir().typeOf(inst); | 31694 | return sema.getTmpAir().typeOf(inst); |
| ... | @@ -31792,14 +31778,6 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { | ... | @@ -31792,14 +31778,6 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { |
| 31792 | return sema.addConstant(ty, try Value.Tag.int_u64.create(sema.arena, int)); | 31778 | return sema.addConstant(ty, try Value.Tag.int_u64.create(sema.arena, int)); |
| 31793 | } | 31779 | } |
| 31794 | | 31780 | |
| 31795 | fn addBool(sema: *Sema, ty: Type, boolean: bool) CompileError!Air.Inst.Ref { | | |
| 31796 | return switch (ty.zigTypeTag()) { | | |
| 31797 | .Vector => sema.addConstant(ty, try Value.Tag.repeated.create(sema.arena, Value.makeBool(boolean))), | | |
| 31798 | .Bool => try sema.resolveInst(if (boolean) .bool_true else .bool_false), | | |
| 31799 | else => unreachable, | | |
| 31800 | }; | | |
| 31801 | } | | |
| 31802 | | | |
| 31803 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { | 31781 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { |
| 31804 | return sema.addConstant(ty, Value.undef); | 31782 | return sema.addConstant(ty, Value.undef); |
| 31805 | } | 31783 | } |
| ... | @@ -32443,27 +32421,6 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { | ... | @@ -32443,27 +32421,6 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { |
| 32443 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); | 32421 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| 32444 | } | 32422 | } |
| 32445 | | 32423 | |
| 32446 | /// Supports both (vectors of) floats and ints; handles undefined scalars. | | |
| 32447 | fn numberAddWrap( | | |
| 32448 | sema: *Sema, | | |
| 32449 | lhs: Value, | | |
| 32450 | rhs: Value, | | |
| 32451 | ty: Type, | | |
| 32452 | ) !Value { | | |
| 32453 | if (ty.zigTypeTag() == .Vector) { | | |
| 32454 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); | | |
| 32455 | for (result_data) |*scalar, i| { | | |
| 32456 | var lhs_buf: Value.ElemValueBuffer = undefined; | | |
| 32457 | var rhs_buf: Value.ElemValueBuffer = undefined; | | |
| 32458 | const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf); | | |
| 32459 | const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf); | | |
| 32460 | scalar.* = try sema.numberAddWrapScalar(lhs_elem, rhs_elem, ty.scalarType()); | | |
| 32461 | } | | |
| 32462 | return Value.Tag.aggregate.create(sema.arena, result_data); | | |
| 32463 | } | | |
| 32464 | return sema.numberAddWrapScalar(lhs, rhs, ty); | | |
| 32465 | } | | |
| 32466 | | | |
| 32467 | /// Supports both floats and ints; handles undefined. | 32424 | /// Supports both floats and ints; handles undefined. |
| 32468 | fn numberAddWrapScalar( | 32425 | fn numberAddWrapScalar( |
| 32469 | sema: *Sema, | 32426 | sema: *Sema, |
| ... | @@ -32522,27 +32479,6 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { | ... | @@ -32522,27 +32479,6 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { |
| 32522 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); | 32479 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| 32523 | } | 32480 | } |
| 32524 | | 32481 | |
| 32525 | /// Supports both (vectors of) floats and ints; handles undefined scalars. | | |
| 32526 | fn numberSubWrap( | | |
| 32527 | sema: *Sema, | | |
| 32528 | lhs: Value, | | |
| 32529 | rhs: Value, | | |
| 32530 | ty: Type, | | |
| 32531 | ) !Value { | | |
| 32532 | if (ty.zigTypeTag() == .Vector) { | | |
| 32533 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); | | |
| 32534 | for (result_data) |*scalar, i| { | | |
| 32535 | var lhs_buf: Value.ElemValueBuffer = undefined; | | |
| 32536 | var rhs_buf: Value.ElemValueBuffer = undefined; | | |
| 32537 | const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf); | | |
| 32538 | const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf); | | |
| 32539 | scalar.* = try sema.numberSubWrapScalar(lhs_elem, rhs_elem, ty.scalarType()); | | |
| 32540 | } | | |
| 32541 | return Value.Tag.aggregate.create(sema.arena, result_data); | | |
| 32542 | } | | |
| 32543 | return sema.numberSubWrapScalar(lhs, rhs, ty); | | |
| 32544 | } | | |
| 32545 | | | |
| 32546 | /// Supports both floats and ints; handles undefined. | 32482 | /// Supports both floats and ints; handles undefined. |
| 32547 | fn numberSubWrapScalar( | 32483 | fn numberSubWrapScalar( |
| 32548 | sema: *Sema, | 32484 | sema: *Sema, |