From f366d9f8793fc297e581321fbbd6242089f07440 Mon Sep 17 00:00:00 2001 From: mlugg Date: Fri, 15 Sep 2023 00:00:11 +0100 Subject: [PATCH] compiler: start using destructure syntax --- src/AstGen.zig | 74 +++++++++++++-------------------- src/Sema.zig | 108 +++++++++++++++++++++---------------------------- 2 files changed, 74 insertions(+), 108 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index 6d67ffcad5..61476b505a 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1392,14 +1392,8 @@ fn arrayInitExpr( assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init. - const types: struct { - array: Zir.Inst.Ref, - elem: Zir.Inst.Ref, - } = inst: { - if (array_init.ast.type_expr == 0) break :inst .{ - .array = .none, - .elem = .none, - }; + const array_ty: Zir.Inst.Ref, const elem_ty: Zir.Inst.Ref = inst: { + if (array_init.ast.type_expr == 0) break :inst .{ .none, .none }; infer: { const array_type: Ast.full.ArrayType = tree.fullArrayType(array_init.ast.type_expr) orelse break :infer; @@ -1414,10 +1408,7 @@ fn arrayInitExpr( .lhs = len_inst, .rhs = elem_type, }); - break :inst .{ - .array = array_type_inst, - .elem = elem_type, - }; + break :inst .{ array_type_inst, elem_type }; } else { const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel); const array_type_inst = try gz.addPlNode( @@ -1429,10 +1420,7 @@ fn arrayInitExpr( .sentinel = sentinel, }, ); - break :inst .{ - .array = array_type_inst, - .elem = elem_type, - }; + break :inst .{ array_type_inst, elem_type }; } } } @@ -1441,29 +1429,26 @@ fn arrayInitExpr( .ty = array_type_inst, .init_count = @intCast(array_init.ast.elements.len), }); - break :inst .{ - .array = array_type_inst, - .elem = .none, - }; + break :inst .{ array_type_inst, .none }; }; switch (ri.rl) { .discard => { - if (types.elem != .none) { - const elem_ri: ResultInfo = .{ .rl = .{ .ty = types.elem } }; + if (elem_ty != .none) { + const elem_ri: ResultInfo = .{ .rl = .{ .ty = elem_ty } }; for (array_init.ast.elements) |elem_init| { _ = try expr(gz, scope, elem_ri, elem_init); } - } else if (types.array != .none) { + } else if (array_ty != .none) { for (array_init.ast.elements, 0..) |elem_init, i| { - const elem_ty = try gz.add(.{ + const this_elem_ty = try gz.add(.{ .tag = .elem_type_index, .data = .{ .bin = .{ - .lhs = types.array, + .lhs = array_ty, .rhs = @enumFromInt(i), } }, }); - _ = try expr(gz, scope, .{ .rl = .{ .ty = elem_ty } }, elem_init); + _ = try expr(gz, scope, .{ .rl = .{ .ty = this_elem_ty } }, elem_init); } } else { for (array_init.ast.elements) |elem_init| { @@ -1473,15 +1458,15 @@ fn arrayInitExpr( return Zir.Inst.Ref.void_value; }, .ref => { - const tag: Zir.Inst.Tag = if (types.array != .none) .array_init_ref else .array_init_anon_ref; - return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); + const tag: Zir.Inst.Tag = if (array_ty != .none) .array_init_ref else .array_init_anon_ref; + return arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, elem_ty, tag); }, .none => { - const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; - return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); + const tag: Zir.Inst.Tag = if (array_ty != .none) .array_init else .array_init_anon; + return arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, elem_ty, tag); }, .ty, .coerced_ty => |ty_inst| { - const arr_ty = if (types.array != .none) types.array else blk: { + const arr_ty = if (array_ty != .none) array_ty else blk: { const arr_ty = try gz.addUnNode(.opt_eu_base_ty, ty_inst, node); _ = try gz.addPlNode(.validate_array_init_ty, node, Zir.Inst.ArrayInit{ .ty = arr_ty, @@ -1489,29 +1474,29 @@ fn arrayInitExpr( }); break :blk arr_ty; }; - const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, arr_ty, types.elem, .array_init); + const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, arr_ty, elem_ty, .array_init); return rvalue(gz, ri, result, node); }, .ptr => |ptr_res| { - return arrayInitExprRlPtr(gz, scope, node, ptr_res.inst, array_init.ast.elements, types.array); + return arrayInitExprRlPtr(gz, scope, node, ptr_res.inst, array_init.ast.elements, array_ty); }, .inferred_ptr => |ptr_inst| { - if (types.array == .none) { + if (array_ty == .none) { // We treat this case differently so that we don't get a crash when // analyzing array_base_ptr against an alloc_inferred_mut. // See corresponding logic in structInitExpr. const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); return rvalue(gz, ri, result, node); } else { - return arrayInitExprRlPtr(gz, scope, node, ptr_inst, array_init.ast.elements, types.array); + return arrayInitExprRlPtr(gz, scope, node, ptr_inst, array_init.ast.elements, array_ty); } }, .destructure => |destructure| { - if (types.array != .none) { + if (array_ty != .none) { // We have a specific type, so there may be things like default // field values messing with us. Do this as a standard typed // init followed by an rvalue destructure. - const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, .array_init); + const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, array_ty, elem_ty, .array_init); return rvalue(gz, ri, result, node); } // Untyped init - destructure directly into result pointers @@ -3177,10 +3162,7 @@ fn varDecl( .keyword_var => { const is_comptime = var_decl.comptime_token != null or gz.is_comptime; var resolve_inferred_alloc: Zir.Inst.Ref = .none; - const var_data: struct { - result_info: ResultInfo, - alloc: Zir.Inst.Ref, - } = if (var_decl.ast.type_node != 0) a: { + const alloc: Zir.Inst.Ref, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); const alloc = alloc: { if (align_inst == .none) { @@ -3199,7 +3181,7 @@ fn varDecl( }); } }; - break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; + break :a .{ alloc, .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; } else a: { const alloc = alloc: { if (align_inst == .none) { @@ -3219,24 +3201,24 @@ fn varDecl( } }; resolve_inferred_alloc = alloc; - break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .inferred_ptr = alloc } } }; + break :a .{ alloc, .{ .rl = .{ .inferred_ptr = alloc } } }; }; const prev_anon_name_strategy = gz.anon_name_strategy; gz.anon_name_strategy = .dbg_var; - _ = try reachableExprComptime(gz, scope, var_data.result_info, var_decl.ast.init_node, node, is_comptime); + _ = try reachableExprComptime(gz, scope, result_info, var_decl.ast.init_node, node, is_comptime); gz.anon_name_strategy = prev_anon_name_strategy; if (resolve_inferred_alloc != .none) { _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); } - try gz.addDbgVar(.dbg_var_ptr, ident_name, var_data.alloc); + try gz.addDbgVar(.dbg_var_ptr, ident_name, alloc); const sub_scope = try block_arena.create(Scope.LocalPtr); sub_scope.* = .{ .parent = scope, .gen_zir = gz, .name = ident_name, - .ptr = var_data.alloc, + .ptr = alloc, .token_src = name_token, .maybe_comptime = is_comptime, .id_cat = .@"local variable", diff --git a/src/Sema.zig b/src/Sema.zig index 7542b80f37..16bf872419 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -11092,17 +11092,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; const extra = sema.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index); - const raw_operand: struct { val: Air.Inst.Ref, ptr: Air.Inst.Ref } = blk: { + const raw_operand_val: Air.Inst.Ref, const raw_operand_ptr: Air.Inst.Ref = blk: { const maybe_ptr = try sema.resolveInst(extra.data.operand); if (operand_is_ref) { const val = try sema.analyzeLoad(block, src, maybe_ptr, operand_src); - break :blk .{ .val = val, .ptr = maybe_ptr }; + break :blk .{ val, maybe_ptr }; } else { - break :blk .{ .val = maybe_ptr, .ptr = undefined }; + break :blk .{ maybe_ptr, undefined }; } }; - const operand = try sema.switchCond(block, operand_src, raw_operand.val); + const operand = try sema.switchCond(block, operand_src, raw_operand_val); // AstGen guarantees that the instruction immediately preceding // switch_block(_ref) is a dbg_stmt @@ -11160,7 +11160,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r }, }; - const maybe_union_ty = sema.typeOf(raw_operand.val); + const maybe_union_ty = sema.typeOf(raw_operand_val); const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; // Duplicate checking variables later also used for `inline else`. @@ -11711,8 +11711,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r const spa: SwitchProngAnalysis = .{ .sema = sema, .parent_block = block, - .operand = raw_operand.val, - .operand_ptr = raw_operand.ptr, + .operand = raw_operand_val, + .operand_ptr = raw_operand_ptr, .cond = operand, .else_error_ty = else_error_ty, .switch_block_inst = inst, @@ -15500,11 +15500,7 @@ fn analyzeArithmetic( const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs); const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs); - const rs: struct { - src: LazySrcLoc, - air_tag: Air.Inst.Tag, - air_tag_safe: Air.Inst.Tag, - } = rs: { + const runtime_src: LazySrcLoc, const air_tag: Air.Inst.Tag, const air_tag_safe: Air.Inst.Tag = rs: { switch (zir_tag) { .add, .add_unsafe => { // For integers:intAddSat @@ -15551,8 +15547,8 @@ fn analyzeArithmetic( } else { return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); } - } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .add_safe }; - } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .add_safe }; + } else break :rs .{ rhs_src, air_tag, .add_safe }; + } else break :rs .{ lhs_src, air_tag, .add_safe }; }, .addwrap => { // Integers only; floats are checked above. @@ -15572,8 +15568,8 @@ fn analyzeArithmetic( } if (maybe_lhs_val) |lhs_val| { return Air.internedToRef((try sema.numberAddWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); - } else break :rs .{ .src = lhs_src, .air_tag = .add_wrap, .air_tag_safe = .add_wrap }; - } else break :rs .{ .src = rhs_src, .air_tag = .add_wrap, .air_tag_safe = .add_wrap }; + } else break :rs .{ lhs_src, .add_wrap, .add_wrap }; + } else break :rs .{ rhs_src, .add_wrap, .add_wrap }; }, .add_sat => { // Integers only; floats are checked above. @@ -15599,14 +15595,14 @@ fn analyzeArithmetic( return Air.internedToRef(val.toIntern()); } else break :rs .{ - .src = lhs_src, - .air_tag = .add_sat, - .air_tag_safe = .add_sat, + lhs_src, + .add_sat, + .add_sat, }; } else break :rs .{ - .src = rhs_src, - .air_tag = .add_sat, - .air_tag_safe = .add_sat, + rhs_src, + .add_sat, + .add_sat, }; }, .sub => { @@ -15649,8 +15645,8 @@ fn analyzeArithmetic( } else { return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); } - } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .sub_safe }; - } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .sub_safe }; + } else break :rs .{ rhs_src, air_tag, .sub_safe }; + } else break :rs .{ lhs_src, air_tag, .sub_safe }; }, .subwrap => { // Integers only; floats are checked above. @@ -15670,8 +15666,8 @@ fn analyzeArithmetic( } if (maybe_rhs_val) |rhs_val| { return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); - } else break :rs .{ .src = rhs_src, .air_tag = .sub_wrap, .air_tag_safe = .sub_wrap }; - } else break :rs .{ .src = lhs_src, .air_tag = .sub_wrap, .air_tag_safe = .sub_wrap }; + } else break :rs .{ rhs_src, .sub_wrap, .sub_wrap }; + } else break :rs .{ lhs_src, .sub_wrap, .sub_wrap }; }, .sub_sat => { // Integers only; floats are checked above. @@ -15696,8 +15692,8 @@ fn analyzeArithmetic( try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod); return Air.internedToRef(val.toIntern()); - } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat, .air_tag_safe = .sub_sat }; - } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat, .air_tag_safe = .sub_sat }; + } else break :rs .{ rhs_src, .sub_sat, .sub_sat }; + } else break :rs .{ lhs_src, .sub_sat, .sub_sat }; }, .mul => { // For integers: @@ -15789,8 +15785,8 @@ fn analyzeArithmetic( } else { return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern()); } - } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .mul_safe }; - } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .mul_safe }; + } else break :rs .{ lhs_src, air_tag, .mul_safe }; + } else break :rs .{ rhs_src, air_tag, .mul_safe }; }, .mulwrap => { // Integers only; floats are handled above. @@ -15834,8 +15830,8 @@ fn analyzeArithmetic( return mod.undefRef(resolved_type); } return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern()); - } else break :rs .{ .src = lhs_src, .air_tag = .mul_wrap, .air_tag_safe = .mul_wrap }; - } else break :rs .{ .src = rhs_src, .air_tag = .mul_wrap, .air_tag_safe = .mul_wrap }; + } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap }; + } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap }; }, .mul_sat => { // Integers only; floats are checked above. @@ -15885,20 +15881,20 @@ fn analyzeArithmetic( try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod); return Air.internedToRef(val.toIntern()); - } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat, .air_tag_safe = .mul_sat }; - } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat, .air_tag_safe = .mul_sat }; + } else break :rs .{ lhs_src, .mul_sat, .mul_sat }; + } else break :rs .{ rhs_src, .mul_sat, .mul_sat }; }, else => unreachable, } }; - try sema.requireRuntimeBlock(block, src, rs.src); + try sema.requireRuntimeBlock(block, src, runtime_src); if (block.wantSafety() and want_safety and scalar_tag == .Int) { if (mod.backendSupportsFeature(.safety_checked_instructions)) { _ = try sema.preparePanicId(block, .integer_overflow); - return block.addBinOp(rs.air_tag_safe, casted_lhs, casted_rhs); + return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); } else { - const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { + const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { .add => .add_with_overflow, .sub => .sub_with_overflow, .mul => .mul_with_overflow, @@ -15935,7 +15931,7 @@ fn analyzeArithmetic( } } } - return block.addBinOp(rs.air_tag, casted_lhs, casted_rhs); + return block.addBinOp(air_tag, casted_lhs, casted_rhs); } fn analyzePtrArithmetic( @@ -32345,16 +32341,10 @@ fn compareIntsOnlyPossibleResult( // For any other comparison, we need to know if the LHS value is // equal to the maximum or minimum possible value of the RHS type. - const edge: struct { min: bool, max: bool } = edge: { - if (is_zero and rhs_info.signedness == .unsigned) break :edge .{ - .min = true, - .max = false, - }; + const is_min, const is_max = edge: { + if (is_zero and rhs_info.signedness == .unsigned) break :edge .{ true, false }; - if (req_bits != rhs_info.bits) break :edge .{ - .min = false, - .max = false, - }; + if (req_bits != rhs_info.bits) break :edge .{ false, false }; const ty = try mod.intType( if (is_negative) .signed else .unsigned, @@ -32363,24 +32353,18 @@ fn compareIntsOnlyPossibleResult( const pop_count = lhs_val.popCount(ty, mod); if (is_negative) { - break :edge .{ - .min = pop_count == 1, - .max = false, - }; + break :edge .{ pop_count == 1, false }; } else { - break :edge .{ - .min = false, - .max = pop_count == req_bits - sign_adj, - }; + break :edge .{ false, pop_count == req_bits - sign_adj }; } }; assert(fits); return switch (op) { - .lt => if (edge.max) false else null, - .lte => if (edge.min) true else null, - .gt => if (edge.min) false else null, - .gte => if (edge.max) true else null, + .lt => if (is_max) false else null, + .lte => if (is_min) true else null, + .gt => if (is_min) false else null, + .gte => if (is_max) true else null, .eq, .neq => unreachable, }; } @@ -32617,7 +32601,7 @@ const PeerResolveStrategy = enum { either, }; - const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { + const reason_method: ReasonMethod, const strat: PeerResolveStrategy = switch (s0) { .unknown => .{ .all_s1, s1 }, .error_set => switch (s1) { .error_set => .{ .either, .error_set }, @@ -32685,7 +32669,7 @@ const PeerResolveStrategy = enum { .exact => .{ .all_s0, .exact }, }; - switch (res[0]) { + switch (reason_method) { .all_s0 => { if (!s0_is_a) { reason_peer.* = b_peer_idx; @@ -32702,7 +32686,7 @@ const PeerResolveStrategy = enum { }, } - return res[1]; + return strat; } fn select(ty: Type, mod: *Module) PeerResolveStrategy {