| author | |
| committer | |
| log | 012fac255f35b9cdbe18c14753a195de89d07d28 |
| tree | 6c7a8290ea5cae3da198bc4c9d97b2ce19478a42 |
| parent | c52513e25b69cdd28c5af567b8d3d6a0d9fb979e |
| signature | Commit is signed but in an unrecognized format. |
7 files changed, 199 insertions(+), 115 deletions(-)
src-self-hosted/Module.zig+65-52| ... | @@ -2200,8 +2200,11 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn | ... | @@ -2200,8 +2200,11 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn |
| 2200 | }; | 2200 | }; |
| 2201 | 2201 | ||
| 2202 | const decl_tv = try decl.typedValue(); | 2202 | const decl_tv = try decl.typedValue(); |
| 2203 | const ty_payload = try scope.arena().create(Type.Payload.SingleConstPointer); | 2203 | const ty_payload = try scope.arena().create(Type.Payload.Pointer); |
| 2204 | ty_payload.* = .{ .pointee_type = decl_tv.ty }; | 2204 | ty_payload.* = .{ |
| 2205 | .base = .{ .tag = .single_const_pointer }, | ||
| 2206 | .pointee_type = decl_tv.ty, | ||
| 2207 | }; | ||
| 2205 | const val_payload = try scope.arena().create(Value.Payload.DeclRef); | 2208 | const val_payload = try scope.arena().create(Value.Payload.DeclRef); |
| 2206 | val_payload.* = .{ .decl = decl }; | 2209 | val_payload.* = .{ .decl = decl }; |
| 2207 | 2210 | ||
| ... | @@ -2425,6 +2428,16 @@ pub fn cmpNumeric( | ... | @@ -2425,6 +2428,16 @@ pub fn cmpNumeric( |
| 2425 | return self.addBinOp(b, src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); | 2428 | return self.addBinOp(b, src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); |
| 2426 | } | 2429 | } |
| 2427 | 2430 | ||
| 2431 | fn wrapOptional(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst { | ||
| 2432 | if (inst.value()) |val| { | ||
| 2433 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val }); | ||
| 2434 | } | ||
| 2435 | |||
| 2436 | // TODO how do we get the result location | ||
| 2437 | const b = try self.requireRuntimeBlock(scope, inst.src); | ||
| 2438 | return self.addUnOp(b, inst.src, dest_type, .wrap_optional, inst); | ||
| 2439 | } | ||
| 2440 | |||
| 2428 | fn makeIntType(self: *Module, scope: *Scope, signed: bool, bits: u16) !Type { | 2441 | fn makeIntType(self: *Module, scope: *Scope, signed: bool, bits: u16) !Type { |
| 2429 | if (signed) { | 2442 | if (signed) { |
| 2430 | const int_payload = try scope.arena().create(Type.Payload.IntSigned); | 2443 | const int_payload = try scope.arena().create(Type.Payload.IntSigned); |
| ... | @@ -2502,14 +2515,12 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst | ... | @@ -2502,14 +2515,12 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst |
| 2502 | 2515 | ||
| 2503 | // T to ?T | 2516 | // T to ?T |
| 2504 | if (dest_type.zigTypeTag() == .Optional) { | 2517 | if (dest_type.zigTypeTag() == .Optional) { |
| 2505 | const child_type = dest_type.elemType(); | 2518 | var buf: Type.Payload.Pointer = undefined; |
| 2506 | if (inst.value()) |val| { | 2519 | const child_type = dest_type.optionalChild(&buf); |
| 2507 | if (child_type.eql(inst.ty)) { | 2520 | if (child_type.eql(inst.ty)) { |
| 2508 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val }); | 2521 | return self.wrapOptional(scope, dest_type, inst); |
| 2509 | } | 2522 | } else if (try self.coerceNum(scope, child_type, inst)) |some| { |
| 2510 | return self.fail(scope, inst.src, "TODO optional wrap {} to {}", .{ val, dest_type }); | 2523 | return self.wrapOptional(scope, dest_type, some); |
| 2511 | } else if (child_type.eql(inst.ty)) { | ||
| 2512 | return self.fail(scope, inst.src, "TODO optional wrap {}", .{dest_type}); | ||
| 2513 | } | 2524 | } |
| 2514 | } | 2525 | } |
| 2515 | 2526 | ||
| ... | @@ -2527,39 +2538,8 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst | ... | @@ -2527,39 +2538,8 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst |
| 2527 | } | 2538 | } |
| 2528 | 2539 | ||
| 2529 | // comptime known number to other number | 2540 | // comptime known number to other number |
| 2530 | if (inst.value()) |val| { | 2541 | if (try self.coerceNum(scope, dest_type, inst)) |some| |
| 2531 | const src_zig_tag = inst.ty.zigTypeTag(); | 2542 | return some; |
| 2532 | const dst_zig_tag = dest_type.zigTypeTag(); | ||
| 2533 | |||
| 2534 | if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) { | ||
| 2535 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { | ||
| 2536 | if (val.floatHasFraction()) { | ||
| 2537 | return self.fail(scope, inst.src, "fractional component prevents float value {} from being casted to type '{}'", .{ val, inst.ty }); | ||
| 2538 | } | ||
| 2539 | return self.fail(scope, inst.src, "TODO float to int", .{}); | ||
| 2540 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { | ||
| 2541 | if (!val.intFitsInType(dest_type, self.target())) { | ||
| 2542 | return self.fail(scope, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val }); | ||
| 2543 | } | ||
| 2544 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val }); | ||
| 2545 | } | ||
| 2546 | } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) { | ||
| 2547 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { | ||
| 2548 | const res = val.floatCast(scope.arena(), dest_type, self.target()) catch |err| switch (err) { | ||
| 2549 | error.Overflow => return self.fail( | ||
| 2550 | scope, | ||
| 2551 | inst.src, | ||
| 2552 | "cast of value {} to type '{}' loses information", | ||
| 2553 | .{ val, dest_type }, | ||
| 2554 | ), | ||
| 2555 | error.OutOfMemory => return error.OutOfMemory, | ||
| 2556 | }; | ||
| 2557 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = res }); | ||
| 2558 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { | ||
| 2559 | return self.fail(scope, inst.src, "TODO int to float", .{}); | ||
| 2560 | } | ||
| 2561 | } | ||
| 2562 | } | ||
| 2563 | 2543 | ||
| 2564 | // integer widening | 2544 | // integer widening |
| 2565 | if (inst.ty.zigTypeTag() == .Int and dest_type.zigTypeTag() == .Int) { | 2545 | if (inst.ty.zigTypeTag() == .Int and dest_type.zigTypeTag() == .Int) { |
| ... | @@ -2591,6 +2571,42 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst | ... | @@ -2591,6 +2571,42 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst |
| 2591 | return self.fail(scope, inst.src, "expected {}, found {}", .{ dest_type, inst.ty }); | 2571 | return self.fail(scope, inst.src, "expected {}, found {}", .{ dest_type, inst.ty }); |
| 2592 | } | 2572 | } |
| 2593 | 2573 | ||
| 2574 | pub fn coerceNum(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !?*Inst { | ||
| 2575 | const val = inst.value() orelse return null; | ||
| 2576 | const src_zig_tag = inst.ty.zigTypeTag(); | ||
| 2577 | const dst_zig_tag = dest_type.zigTypeTag(); | ||
| 2578 | |||
| 2579 | if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) { | ||
| 2580 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { | ||
| 2581 | if (val.floatHasFraction()) { | ||
| 2582 | return self.fail(scope, inst.src, "fractional component prevents float value {} from being casted to type '{}'", .{ val, inst.ty }); | ||
| 2583 | } | ||
| 2584 | return self.fail(scope, inst.src, "TODO float to int", .{}); | ||
| 2585 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { | ||
| 2586 | if (!val.intFitsInType(dest_type, self.target())) { | ||
| 2587 | return self.fail(scope, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val }); | ||
| 2588 | } | ||
| 2589 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val }); | ||
| 2590 | } | ||
| 2591 | } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) { | ||
| 2592 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { | ||
| 2593 | const res = val.floatCast(scope.arena(), dest_type, self.target()) catch |err| switch (err) { | ||
| 2594 | error.Overflow => return self.fail( | ||
| 2595 | scope, | ||
| 2596 | inst.src, | ||
| 2597 | "cast of value {} to type '{}' loses information", | ||
| 2598 | .{ val, dest_type }, | ||
| 2599 | ), | ||
| 2600 | error.OutOfMemory => return error.OutOfMemory, | ||
| 2601 | }; | ||
| 2602 | return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = res }); | ||
| 2603 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { | ||
| 2604 | return self.fail(scope, inst.src, "TODO int to float", .{}); | ||
| 2605 | } | ||
| 2606 | } | ||
| 2607 | return null; | ||
| 2608 | } | ||
| 2609 | |||
| 2594 | pub fn storePtr(self: *Module, scope: *Scope, src: usize, ptr: *Inst, uncasted_value: *Inst) !*Inst { | 2610 | pub fn storePtr(self: *Module, scope: *Scope, src: usize, ptr: *Inst, uncasted_value: *Inst) !*Inst { |
| 2595 | if (ptr.ty.isConstPtr()) | 2611 | if (ptr.ty.isConstPtr()) |
| 2596 | return self.fail(scope, src, "cannot assign to constant", .{}); | 2612 | return self.fail(scope, src, "cannot assign to constant", .{}); |
| ... | @@ -2878,15 +2894,12 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: | ... | @@ -2878,15 +2894,12 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: |
| 2878 | return Value.initPayload(val_payload); | 2894 | return Value.initPayload(val_payload); |
| 2879 | } | 2895 | } |
| 2880 | 2896 | ||
| 2881 | pub fn singleMutPtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type) error{OutOfMemory}!Type { | 2897 | pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) error{OutOfMemory}!Type { |
| 2882 | const type_payload = try scope.arena().create(Type.Payload.SingleMutPointer); | 2898 | const type_payload = try scope.arena().create(Type.Payload.Pointer); |
| 2883 | type_payload.* = .{ .pointee_type = elem_ty }; | 2899 | type_payload.* = .{ |
| 2884 | return Type.initPayload(&type_payload.base); | 2900 | .base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer }, |
| 2885 | } | 2901 | .pointee_type = elem_ty, |
| 2886 | 2902 | }; | |
| 2887 | pub fn singleConstPtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type) error{OutOfMemory}!Type { | ||
| 2888 | const type_payload = try scope.arena().create(Type.Payload.SingleConstPointer); | ||
| 2889 | type_payload.* = .{ .pointee_type = elem_ty }; | ||
| 2890 | return Type.initPayload(&type_payload.base); | 2903 | return Type.initPayload(&type_payload.base); |
| 2891 | } | 2904 | } |
| 2892 | 2905 |
src-self-hosted/astgen.zig+1-1| ... | @@ -870,7 +870,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo | ... | @@ -870,7 +870,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 870 | const int_type_payload = try scope.arena().create(Value.Payload.IntType); | 870 | const int_type_payload = try scope.arena().create(Value.Payload.IntType); |
| 871 | int_type_payload.* = .{ .signed = is_signed, .bits = bit_count }; | 871 | int_type_payload.* = .{ .signed = is_signed, .bits = bit_count }; |
| 872 | const result = try addZIRInstConst(mod, scope, src, .{ | 872 | const result = try addZIRInstConst(mod, scope, src, .{ |
| 873 | .ty = Type.initTag(.comptime_int), | 873 | .ty = Type.initTag(.type), |
| 874 | .val = Value.initPayload(&int_type_payload.base), | 874 | .val = Value.initPayload(&int_type_payload.base), |
| 875 | }); | 875 | }); |
| 876 | return rlWrap(mod, scope, rl, result); | 876 | return rlWrap(mod, scope, rl, result); |
src-self-hosted/codegen.zig+34-2| ... | @@ -682,6 +682,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -682,6 +682,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 682 | .sub => return self.genSub(inst.castTag(.sub).?), | 682 | .sub => return self.genSub(inst.castTag(.sub).?), |
| 683 | .unreach => return MCValue{ .unreach = {} }, | 683 | .unreach => return MCValue{ .unreach = {} }, |
| 684 | .unwrap_optional => return self.genUnwrapOptional(inst.castTag(.unwrap_optional).?), | 684 | .unwrap_optional => return self.genUnwrapOptional(inst.castTag(.unwrap_optional).?), |
| 685 | .wrap_optional => return self.genWrapOptional(inst.castTag(.wrap_optional).?), | ||
| 685 | } | 686 | } |
| 686 | } | 687 | } |
| 687 | 688 | ||
| ... | @@ -840,6 +841,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -840,6 +841,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 840 | } | 841 | } |
| 841 | } | 842 | } |
| 842 | 843 | ||
| 844 | fn genWrapOptional(self: *Self, inst: *ir.Inst.UnOp) !MCValue { | ||
| 845 | const optional_ty = inst.base.ty; | ||
| 846 | |||
| 847 | // No side effects, so if it's unreferenced, do nothing. | ||
| 848 | if (inst.base.isUnused()) | ||
| 849 | return MCValue.dead; | ||
| 850 | |||
| 851 | // Optional type is just a boolean true | ||
| 852 | if (optional_ty.abiSize(self.target.*) == 1) | ||
| 853 | return MCValue{ .immediate = 1 }; | ||
| 854 | |||
| 855 | switch (arch) { | ||
| 856 | else => return self.fail(inst.base.src, "TODO implement wrap optional for {}", .{self.target.cpu.arch}), | ||
| 857 | } | ||
| 858 | } | ||
| 859 | |||
| 843 | fn genLoad(self: *Self, inst: *ir.Inst.UnOp) !MCValue { | 860 | fn genLoad(self: *Self, inst: *ir.Inst.UnOp) !MCValue { |
| 844 | const elem_ty = inst.base.ty; | 861 | const elem_ty = inst.base.ty; |
| 845 | if (!elem_ty.hasCodeGenBits()) | 862 | if (!elem_ty.hasCodeGenBits()) |
| ... | @@ -2028,9 +2045,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2028,9 +2045,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2028 | return mcv; | 2045 | return mcv; |
| 2029 | } | 2046 | } |
| 2030 | 2047 | ||
| 2031 | fn genTypedValue(self: *Self, src: usize, typed_value: TypedValue) !MCValue { | 2048 | fn genTypedValue(self: *Self, src: usize, typed_value: TypedValue) error{ CodegenFail, OutOfMemory }!MCValue { |
| 2032 | if (typed_value.val.isUndef()) | 2049 | if (typed_value.val.isUndef()) |
| 2033 | return MCValue.undef; | 2050 | return MCValue{ .undef = {} }; |
| 2034 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); | 2051 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 2035 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 2052 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 2036 | switch (typed_value.ty.zigTypeTag()) { | 2053 | switch (typed_value.ty.zigTypeTag()) { |
| ... | @@ -2055,6 +2072,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2055,6 +2072,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2055 | }, | 2072 | }, |
| 2056 | .ComptimeInt => unreachable, // semantic analysis prevents this | 2073 | .ComptimeInt => unreachable, // semantic analysis prevents this |
| 2057 | .ComptimeFloat => unreachable, // semantic analysis prevents this | 2074 | .ComptimeFloat => unreachable, // semantic analysis prevents this |
| 2075 | .Optional => { | ||
| 2076 | if (typed_value.ty.isPtrLikeOptional()) { | ||
| 2077 | if (typed_value.val.isNull()) | ||
| 2078 | return MCValue{ .immediate = 0 }; | ||
| 2079 | |||
| 2080 | var buf: Type.Payload.Pointer = undefined; | ||
| 2081 | return self.genTypedValue(src, .{ | ||
| 2082 | .ty = typed_value.ty.optionalChild(&buf), | ||
| 2083 | .val = typed_value.val, | ||
| 2084 | }); | ||
| 2085 | } else if (typed_value.ty.abiSize(self.target.*) == 1) { | ||
| 2086 | return MCValue{ .immediate = @boolToInt(typed_value.val.isNull()) }; | ||
| 2087 | } | ||
| 2088 | return self.fail(src, "TODO non pointer optionals", .{}); | ||
| 2089 | }, | ||
| 2058 | else => return self.fail(src, "TODO implement const of type '{}'", .{typed_value.ty}), | 2090 | else => return self.fail(src, "TODO implement const of type '{}'", .{typed_value.ty}), |
| 2059 | } | 2091 | } |
| 2060 | } | 2092 | } |
src-self-hosted/ir.zig+2| ... | @@ -83,6 +83,7 @@ pub const Inst = struct { | ... | @@ -83,6 +83,7 @@ pub const Inst = struct { |
| 83 | floatcast, | 83 | floatcast, |
| 84 | intcast, | 84 | intcast, |
| 85 | unwrap_optional, | 85 | unwrap_optional, |
| 86 | wrap_optional, | ||
| 86 | 87 | ||
| 87 | pub fn Type(tag: Tag) type { | 88 | pub fn Type(tag: Tag) type { |
| 88 | return switch (tag) { | 89 | return switch (tag) { |
| ... | @@ -104,6 +105,7 @@ pub const Inst = struct { | ... | @@ -104,6 +105,7 @@ pub const Inst = struct { |
| 104 | .intcast, | 105 | .intcast, |
| 105 | .load, | 106 | .load, |
| 106 | .unwrap_optional, | 107 | .unwrap_optional, |
| 108 | .wrap_optional, | ||
| 107 | => UnOp, | 109 | => UnOp, |
| 108 | 110 | ||
| 109 | .add, | 111 | .add, |
src-self-hosted/type.zig+78-46| ... | @@ -107,6 +107,17 @@ pub const Type = extern union { | ... | @@ -107,6 +107,17 @@ pub const Type = extern union { |
| 107 | return @fieldParentPtr(T, "base", self.ptr_otherwise); | 107 | return @fieldParentPtr(T, "base", self.ptr_otherwise); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | pub fn castPointer(self: Type) ?*Payload.Pointer { | ||
| 111 | return switch (self.tag()) { | ||
| 112 | .single_const_pointer, | ||
| 113 | .single_mut_pointer, | ||
| 114 | .optional_single_const_pointer, | ||
| 115 | .optional_single_mut_pointer, | ||
| 116 | => @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise), | ||
| 117 | else => null, | ||
| 118 | }; | ||
| 119 | } | ||
| 120 | |||
| 110 | pub fn eql(a: Type, b: Type) bool { | 121 | pub fn eql(a: Type, b: Type) bool { |
| 111 | // As a shortcut, if the small tags / addresses match, we're done. | 122 | // As a shortcut, if the small tags / addresses match, we're done. |
| 112 | if (a.tag_if_small_enough == b.tag_if_small_enough) | 123 | if (a.tag_if_small_enough == b.tag_if_small_enough) |
| ... | @@ -126,8 +137,8 @@ pub const Type = extern union { | ... | @@ -126,8 +137,8 @@ pub const Type = extern union { |
| 126 | .Null => return true, | 137 | .Null => return true, |
| 127 | .Pointer => { | 138 | .Pointer => { |
| 128 | // Hot path for common case: | 139 | // Hot path for common case: |
| 129 | if (a.cast(Payload.SingleConstPointer)) |a_payload| { | 140 | if (a.castPointer()) |a_payload| { |
| 130 | if (b.cast(Payload.SingleConstPointer)) |b_payload| { | 141 | if (b.castPointer()) |b_payload| { |
| 131 | return eql(a_payload.pointee_type, b_payload.pointee_type); | 142 | return eql(a_payload.pointee_type, b_payload.pointee_type); |
| 132 | } | 143 | } |
| 133 | } | 144 | } |
| ... | @@ -185,7 +196,9 @@ pub const Type = extern union { | ... | @@ -185,7 +196,9 @@ pub const Type = extern union { |
| 185 | return true; | 196 | return true; |
| 186 | }, | 197 | }, |
| 187 | .Optional => { | 198 | .Optional => { |
| 188 | return a.elemType().eql(b.elemType()); | 199 | var buf_a: Payload.Pointer = undefined; |
| 200 | var buf_b: Payload.Pointer = undefined; | ||
| 201 | return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b)); | ||
| 189 | }, | 202 | }, |
| 190 | .Float, | 203 | .Float, |
| 191 | .Struct, | 204 | .Struct, |
| ... | @@ -249,7 +262,8 @@ pub const Type = extern union { | ... | @@ -249,7 +262,8 @@ pub const Type = extern union { |
| 249 | } | 262 | } |
| 250 | }, | 263 | }, |
| 251 | .Optional => { | 264 | .Optional => { |
| 252 | std.hash.autoHash(&hasher, self.elemType().hash()); | 265 | var buf: Payload.Pointer = undefined; |
| 266 | std.hash.autoHash(&hasher, self.optionalChild(&buf).hash()); | ||
| 253 | }, | 267 | }, |
| 254 | .Float, | 268 | .Float, |
| 255 | .Struct, | 269 | .Struct, |
| ... | @@ -326,8 +340,6 @@ pub const Type = extern union { | ... | @@ -326,8 +340,6 @@ pub const Type = extern union { |
| 326 | }; | 340 | }; |
| 327 | return Type{ .ptr_otherwise = &new_payload.base }; | 341 | return Type{ .ptr_otherwise = &new_payload.base }; |
| 328 | }, | 342 | }, |
| 329 | .single_const_pointer => return self.copyPayloadSingleField(allocator, Payload.SingleConstPointer, "pointee_type"), | ||
| 330 | .single_mut_pointer => return self.copyPayloadSingleField(allocator, Payload.SingleMutPointer, "pointee_type"), | ||
| 331 | .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned), | 343 | .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned), |
| 332 | .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned), | 344 | .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned), |
| 333 | .function => { | 345 | .function => { |
| ... | @@ -346,8 +358,11 @@ pub const Type = extern union { | ... | @@ -346,8 +358,11 @@ pub const Type = extern union { |
| 346 | return Type{ .ptr_otherwise = &new_payload.base }; | 358 | return Type{ .ptr_otherwise = &new_payload.base }; |
| 347 | }, | 359 | }, |
| 348 | .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"), | 360 | .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"), |
| 349 | .optional_single_mut_pointer => return self.copyPayloadSingleField(allocator, Payload.OptionalSingleMutPointer, "pointee_type"), | 361 | .single_const_pointer, |
| 350 | .optional_single_const_pointer => return self.copyPayloadSingleField(allocator, Payload.OptionalSingleConstPointer, "pointee_type"), | 362 | .single_mut_pointer, |
| 363 | .optional_single_mut_pointer, | ||
| 364 | .optional_single_const_pointer, | ||
| 365 | => return self.copyPayloadSingleField(allocator, Payload.Pointer, "pointee_type"), | ||
| 351 | } | 366 | } |
| 352 | } | 367 | } |
| 353 | 368 | ||
| ... | @@ -441,13 +456,13 @@ pub const Type = extern union { | ... | @@ -441,13 +456,13 @@ pub const Type = extern union { |
| 441 | continue; | 456 | continue; |
| 442 | }, | 457 | }, |
| 443 | .single_const_pointer => { | 458 | .single_const_pointer => { |
| 444 | const payload = @fieldParentPtr(Payload.SingleConstPointer, "base", ty.ptr_otherwise); | 459 | const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); |
| 445 | try out_stream.writeAll("*const "); | 460 | try out_stream.writeAll("*const "); |
| 446 | ty = payload.pointee_type; | 461 | ty = payload.pointee_type; |
| 447 | continue; | 462 | continue; |
| 448 | }, | 463 | }, |
| 449 | .single_mut_pointer => { | 464 | .single_mut_pointer => { |
| 450 | const payload = @fieldParentPtr(Payload.SingleMutPointer, "base", ty.ptr_otherwise); | 465 | const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); |
| 451 | try out_stream.writeAll("*"); | 466 | try out_stream.writeAll("*"); |
| 452 | ty = payload.pointee_type; | 467 | ty = payload.pointee_type; |
| 453 | continue; | 468 | continue; |
| ... | @@ -467,13 +482,13 @@ pub const Type = extern union { | ... | @@ -467,13 +482,13 @@ pub const Type = extern union { |
| 467 | continue; | 482 | continue; |
| 468 | }, | 483 | }, |
| 469 | .optional_single_const_pointer => { | 484 | .optional_single_const_pointer => { |
| 470 | const payload = @fieldParentPtr(Payload.OptionalSingleConstPointer, "base", ty.ptr_otherwise); | 485 | const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); |
| 471 | try out_stream.writeAll("?*const "); | 486 | try out_stream.writeAll("?*const "); |
| 472 | ty = payload.pointee_type; | 487 | ty = payload.pointee_type; |
| 473 | continue; | 488 | continue; |
| 474 | }, | 489 | }, |
| 475 | .optional_single_mut_pointer => { | 490 | .optional_single_mut_pointer => { |
| 476 | const payload = @fieldParentPtr(Payload.OptionalSingleMutPointer, "base", ty.ptr_otherwise); | 491 | const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); |
| 477 | try out_stream.writeAll("?*"); | 492 | try out_stream.writeAll("?*"); |
| 478 | ty = payload.pointee_type; | 493 | ty = payload.pointee_type; |
| 479 | continue; | 494 | continue; |
| ... | @@ -658,7 +673,8 @@ pub const Type = extern union { | ... | @@ -658,7 +673,8 @@ pub const Type = extern union { |
| 658 | }, | 673 | }, |
| 659 | 674 | ||
| 660 | .optional => { | 675 | .optional => { |
| 661 | const child_type = self.cast(Payload.Optional).?.child_type; | 676 | var buf: Payload.Pointer = undefined; |
| 677 | const child_type = self.optionalChild(&buf); | ||
| 662 | if (!child_type.hasCodeGenBits()) return 1; | 678 | if (!child_type.hasCodeGenBits()) return 1; |
| 663 | 679 | ||
| 664 | if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) | 680 | if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) |
| ... | @@ -750,7 +766,8 @@ pub const Type = extern union { | ... | @@ -750,7 +766,8 @@ pub const Type = extern union { |
| 750 | }, | 766 | }, |
| 751 | 767 | ||
| 752 | .optional => { | 768 | .optional => { |
| 753 | const child_type = self.cast(Payload.Optional).?.child_type; | 769 | var buf: Payload.Pointer = undefined; |
| 770 | const child_type = self.optionalChild(&buf); | ||
| 754 | if (!child_type.hasCodeGenBits()) return 1; | 771 | if (!child_type.hasCodeGenBits()) return 1; |
| 755 | 772 | ||
| 756 | if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) | 773 | if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) |
| ... | @@ -990,7 +1007,23 @@ pub const Type = extern union { | ... | @@ -990,7 +1007,23 @@ pub const Type = extern union { |
| 990 | }; | 1007 | }; |
| 991 | } | 1008 | } |
| 992 | 1009 | ||
| 993 | /// Asserts the type is a pointer, optional or array type. | 1010 | /// Asserts that the type is an optional |
| 1011 | pub fn isPtrLikeOptional(self: Type) bool { | ||
| 1012 | switch (self.tag()) { | ||
| 1013 | .optional_single_const_pointer, .optional_single_mut_pointer => return true, | ||
| 1014 | .optional => { | ||
| 1015 | var buf: Payload.Pointer = undefined; | ||
| 1016 | const child_type = self.optionalChild(&buf); | ||
| 1017 | // optionals of zero sized pointers behave like bools | ||
| 1018 | if (!child_type.hasCodeGenBits()) return false; | ||
| 1019 | |||
| 1020 | return child_type.zigTypeTag() == .Pointer and !child_type.isCPtr(); | ||
| 1021 | }, | ||
| 1022 | else => unreachable, | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | /// Asserts the type is a pointer or array type. | ||
| 994 | pub fn elemType(self: Type) Type { | 1027 | pub fn elemType(self: Type) Type { |
| 995 | return switch (self.tag()) { | 1028 | return switch (self.tag()) { |
| 996 | .u8, | 1029 | .u8, |
| ... | @@ -1033,16 +1066,38 @@ pub const Type = extern union { | ... | @@ -1033,16 +1066,38 @@ pub const Type = extern union { |
| 1033 | .function, | 1066 | .function, |
| 1034 | .int_unsigned, | 1067 | .int_unsigned, |
| 1035 | .int_signed, | 1068 | .int_signed, |
| 1069 | .optional, | ||
| 1070 | .optional_single_const_pointer, | ||
| 1071 | .optional_single_mut_pointer, | ||
| 1036 | => unreachable, | 1072 | => unreachable, |
| 1037 | 1073 | ||
| 1038 | .array => self.cast(Payload.Array).?.elem_type, | 1074 | .array => self.cast(Payload.Array).?.elem_type, |
| 1039 | .single_const_pointer => self.cast(Payload.SingleConstPointer).?.pointee_type, | 1075 | .single_const_pointer => self.castPointer().?.pointee_type, |
| 1040 | .single_mut_pointer => self.cast(Payload.SingleMutPointer).?.pointee_type, | 1076 | .single_mut_pointer => self.castPointer().?.pointee_type, |
| 1041 | .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), | 1077 | .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), |
| 1042 | .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), | 1078 | .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), |
| 1079 | }; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | /// Asserts that the type is an optional. | ||
| 1083 | pub fn optionalChild(self: Type, buf: *Payload.Pointer) Type { | ||
| 1084 | return switch (self.tag()) { | ||
| 1043 | .optional => self.cast(Payload.Optional).?.child_type, | 1085 | .optional => self.cast(Payload.Optional).?.child_type, |
| 1044 | .optional_single_mut_pointer => self.cast(Payload.OptionalSingleMutPointer).?.pointee_type, | 1086 | .optional_single_mut_pointer => { |
| 1045 | .optional_single_const_pointer => self.cast(Payload.OptionalSingleConstPointer).?.pointee_type, | 1087 | buf.* = .{ |
| 1088 | .base = .{ .tag = .single_mut_pointer }, | ||
| 1089 | .pointee_type = self.castPointer().?.pointee_type | ||
| 1090 | }; | ||
| 1091 | return Type.initPayload(&buf.base); | ||
| 1092 | }, | ||
| 1093 | .optional_single_const_pointer => { | ||
| 1094 | buf.* = .{ | ||
| 1095 | .base = .{ .tag = .single_const_pointer }, | ||
| 1096 | .pointee_type = self.castPointer().?.pointee_type | ||
| 1097 | }; | ||
| 1098 | return Type.initPayload(&buf.base); | ||
| 1099 | }, | ||
| 1100 | else => unreachable, | ||
| 1046 | }; | 1101 | }; |
| 1047 | } | 1102 | } |
| 1048 | 1103 | ||
| ... | @@ -1901,13 +1956,8 @@ pub const Type = extern union { | ... | @@ -1901,13 +1956,8 @@ pub const Type = extern union { |
| 1901 | ty = array.elem_type; | 1956 | ty = array.elem_type; |
| 1902 | continue; | 1957 | continue; |
| 1903 | }, | 1958 | }, |
| 1904 | .single_const_pointer => { | 1959 | .single_const_pointer, .single_mut_pointer => { |
| 1905 | const ptr = ty.cast(Payload.SingleConstPointer).?; | 1960 | const ptr = ty.castPointer().?; |
| 1906 | ty = ptr.pointee_type; | ||
| 1907 | continue; | ||
| 1908 | }, | ||
| 1909 | .single_mut_pointer => { | ||
| 1910 | const ptr = ty.cast(Payload.SingleMutPointer).?; | ||
| 1911 | ty = ptr.pointee_type; | 1961 | ty = ptr.pointee_type; |
| 1912 | continue; | 1962 | continue; |
| 1913 | }, | 1963 | }, |
| ... | @@ -2049,14 +2099,8 @@ pub const Type = extern union { | ... | @@ -2049,14 +2099,8 @@ pub const Type = extern union { |
| 2049 | len: u64, | 2099 | len: u64, |
| 2050 | }; | 2100 | }; |
| 2051 | 2101 | ||
| 2052 | pub const SingleConstPointer = struct { | 2102 | pub const Pointer = struct { |
| 2053 | base: Payload = Payload{ .tag = .single_const_pointer }, | 2103 | base: Payload, |
| 2054 | |||
| 2055 | pointee_type: Type, | ||
| 2056 | }; | ||
| 2057 | |||
| 2058 | pub const SingleMutPointer = struct { | ||
| 2059 | base: Payload = Payload{ .tag = .single_mut_pointer }, | ||
| 2060 | 2104 | ||
| 2061 | pointee_type: Type, | 2105 | pointee_type: Type, |
| 2062 | }; | 2106 | }; |
| ... | @@ -2086,18 +2130,6 @@ pub const Type = extern union { | ... | @@ -2086,18 +2130,6 @@ pub const Type = extern union { |
| 2086 | 2130 | ||
| 2087 | child_type: Type, | 2131 | child_type: Type, |
| 2088 | }; | 2132 | }; |
| 2089 | |||
| 2090 | pub const OptionalSingleConstPointer = struct { | ||
| 2091 | base: Payload = Payload{ .tag = .optional_single_const_pointer }, | ||
| 2092 | |||
| 2093 | pointee_type: Type, | ||
| 2094 | }; | ||
| 2095 | |||
| 2096 | pub const OptionalSingleMutPointer = struct { | ||
| 2097 | base: Payload = Payload{ .tag = .optional_single_mut_pointer }, | ||
| 2098 | |||
| 2099 | pointee_type: Type, | ||
| 2100 | }; | ||
| 2101 | }; | 2133 | }; |
| 2102 | }; | 2134 | }; |
| 2103 | 2135 |
src-self-hosted/zir.zig+3-1| ... | @@ -2017,6 +2017,7 @@ const EmitZIR = struct { | ... | @@ -2017,6 +2017,7 @@ const EmitZIR = struct { |
| 2017 | .load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref), | 2017 | .load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref), |
| 2018 | .ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref), | 2018 | .ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref), |
| 2019 | .unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe), | 2019 | .unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe), |
| 2020 | .wrap_optional => try self.emitCast(inst.src, new_body, inst.castTag(.wrap_optional).?, .as), | ||
| 2020 | 2021 | ||
| 2021 | .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, .add), | 2022 | .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, .add), |
| 2022 | .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, .sub), | 2023 | .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, .sub), |
| ... | @@ -2360,6 +2361,7 @@ const EmitZIR = struct { | ... | @@ -2360,6 +2361,7 @@ const EmitZIR = struct { |
| 2360 | } | 2361 | } |
| 2361 | }, | 2362 | }, |
| 2362 | .Optional => { | 2363 | .Optional => { |
| 2364 | var buf: Type.Payload.Pointer = undefined; | ||
| 2363 | const inst = try self.arena.allocator.create(Inst.UnOp); | 2365 | const inst = try self.arena.allocator.create(Inst.UnOp); |
| 2364 | inst.* = .{ | 2366 | inst.* = .{ |
| 2365 | .base = .{ | 2367 | .base = .{ |
| ... | @@ -2367,7 +2369,7 @@ const EmitZIR = struct { | ... | @@ -2367,7 +2369,7 @@ const EmitZIR = struct { |
| 2367 | .tag = .optional_type, | 2369 | .tag = .optional_type, |
| 2368 | }, | 2370 | }, |
| 2369 | .positionals = .{ | 2371 | .positionals = .{ |
| 2370 | .operand = (try self.emitType(src, ty.elemType())).inst, | 2372 | .operand = (try self.emitType(src, ty.optionalChild(&buf))).inst, |
| 2371 | }, | 2373 | }, |
| 2372 | .kw_args = .{}, | 2374 | .kw_args = .{}, |
| 2373 | }; | 2375 | }; |
src-self-hosted/zir_sema.zig+16-13| ... | @@ -317,7 +317,7 @@ fn analyzeInstRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerErr | ... | @@ -317,7 +317,7 @@ fn analyzeInstRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerErr |
| 317 | 317 | ||
| 318 | fn analyzeInstRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | 318 | fn analyzeInstRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 319 | const operand = try resolveInst(mod, scope, inst.positionals.operand); | 319 | const operand = try resolveInst(mod, scope, inst.positionals.operand); |
| 320 | const ptr_type = try mod.singleConstPtrType(scope, inst.base.src, operand.ty); | 320 | const ptr_type = try mod.singlePtrType(scope, inst.base.src, false, operand.ty); |
| 321 | 321 | ||
| 322 | if (operand.value()) |val| { | 322 | if (operand.value()) |val| { |
| 323 | const ref_payload = try scope.arena().create(Value.Payload.RefVal); | 323 | const ref_payload = try scope.arena().create(Value.Payload.RefVal); |
| ... | @@ -358,7 +358,7 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst. | ... | @@ -358,7 +358,7 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst. |
| 358 | 358 | ||
| 359 | fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | 359 | fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 360 | const var_type = try resolveType(mod, scope, inst.positionals.operand); | 360 | const var_type = try resolveType(mod, scope, inst.positionals.operand); |
| 361 | const ptr_type = try mod.singleMutPtrType(scope, inst.base.src, var_type); | 361 | const ptr_type = try mod.singlePtrType(scope, inst.base.src, true, var_type); |
| 362 | const b = try mod.requireRuntimeBlock(scope, inst.base.src); | 362 | const b = try mod.requireRuntimeBlock(scope, inst.base.src); |
| 363 | return mod.addNoOp(b, inst.base.src, ptr_type, .alloc); | 363 | return mod.addNoOp(b, inst.base.src, ptr_type, .alloc); |
| 364 | } | 364 | } |
| ... | @@ -674,15 +674,17 @@ fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp | ... | @@ -674,15 +674,17 @@ fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp |
| 674 | 674 | ||
| 675 | return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) { | 675 | return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) { |
| 676 | .single_const_pointer => blk: { | 676 | .single_const_pointer => blk: { |
| 677 | const payload = try scope.arena().create(Type.Payload.OptionalSingleConstPointer); | 677 | const payload = try scope.arena().create(Type.Payload.Pointer); |
| 678 | payload.* = .{ | 678 | payload.* = .{ |
| 679 | .base = .{ .tag = .optional_single_const_pointer }, | ||
| 679 | .pointee_type = child_type.elemType(), | 680 | .pointee_type = child_type.elemType(), |
| 680 | }; | 681 | }; |
| 681 | break :blk &payload.base; | 682 | break :blk &payload.base; |
| 682 | }, | 683 | }, |
| 683 | .single_mut_pointer => blk: { | 684 | .single_mut_pointer => blk: { |
| 684 | const payload = try scope.arena().create(Type.Payload.OptionalSingleMutPointer); | 685 | const payload = try scope.arena().create(Type.Payload.Pointer); |
| 685 | payload.* = .{ | 686 | payload.* = .{ |
| 687 | .base = .{ .tag = .optional_single_mut_pointer }, | ||
| 686 | .pointee_type = child_type.elemType(), | 688 | .pointee_type = child_type.elemType(), |
| 687 | }; | 689 | }; |
| 688 | break :blk &payload.base; | 690 | break :blk &payload.base; |
| ... | @@ -705,11 +707,9 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp | ... | @@ -705,11 +707,9 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp |
| 705 | return mod.fail(scope, unwrap.base.src, "expected optional type, found {}", .{operand.ty.elemType()}); | 707 | return mod.fail(scope, unwrap.base.src, "expected optional type, found {}", .{operand.ty.elemType()}); |
| 706 | } | 708 | } |
| 707 | 709 | ||
| 708 | const child_type = operand.ty.elemType().elemType(); | 710 | var buf: Type.Payload.Pointer = undefined; |
| 709 | const child_pointer = if (operand.ty.isConstPtr()) | 711 | const child_type = try operand.ty.elemType().optionalChild(&buf).copy(scope.arena()); |
| 710 | try mod.singleConstPtrType(scope, unwrap.base.src, child_type) | 712 | const child_pointer = try mod.singlePtrType(scope, unwrap.base.src, operand.ty.isConstPtr(), child_type); |
| 711 | else | ||
| 712 | try mod.singleMutPtrType(scope, unwrap.base.src, child_type); | ||
| 713 | 713 | ||
| 714 | if (operand.value()) |val| { | 714 | if (operand.value()) |val| { |
| 715 | if (val.isNull()) { | 715 | if (val.isNull()) { |
| ... | @@ -913,8 +913,11 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne | ... | @@ -913,8 +913,11 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne |
| 913 | // required a larger index. | 913 | // required a larger index. |
| 914 | const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64)); | 914 | const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64)); |
| 915 | 915 | ||
| 916 | const type_payload = try scope.arena().create(Type.Payload.SingleConstPointer); | 916 | const type_payload = try scope.arena().create(Type.Payload.Pointer); |
| 917 | type_payload.* = .{ .pointee_type = array_ptr.ty.elemType().elemType() }; | 917 | type_payload.* = .{ |
| 918 | .base = .{ .tag = .single_const_pointer }, | ||
| 919 | .pointee_type = array_ptr.ty.elemType().elemType(), | ||
| 920 | }; | ||
| 918 | 921 | ||
| 919 | return mod.constInst(scope, inst.base.src, .{ | 922 | return mod.constInst(scope, inst.base.src, .{ |
| 920 | .ty = Type.initPayload(&type_payload.base), | 923 | .ty = Type.initPayload(&type_payload.base), |
| ... | @@ -1279,13 +1282,13 @@ fn analyzeDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerErr | ... | @@ -1279,13 +1282,13 @@ fn analyzeDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerErr |
| 1279 | 1282 | ||
| 1280 | fn analyzeInstSingleConstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | 1283 | fn analyzeInstSingleConstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 1281 | const elem_type = try resolveType(mod, scope, inst.positionals.operand); | 1284 | const elem_type = try resolveType(mod, scope, inst.positionals.operand); |
| 1282 | const ty = try mod.singleConstPtrType(scope, inst.base.src, elem_type); | 1285 | const ty = try mod.singlePtrType(scope, inst.base.src, false, elem_type); |
| 1283 | return mod.constType(scope, inst.base.src, ty); | 1286 | return mod.constType(scope, inst.base.src, ty); |
| 1284 | } | 1287 | } |
| 1285 | 1288 | ||
| 1286 | fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | 1289 | fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 1287 | const elem_type = try resolveType(mod, scope, inst.positionals.operand); | 1290 | const elem_type = try resolveType(mod, scope, inst.positionals.operand); |
| 1288 | const ty = try mod.singleMutPtrType(scope, inst.base.src, elem_type); | 1291 | const ty = try mod.singlePtrType(scope, inst.base.src, true, elem_type); |
| 1289 | return mod.constType(scope, inst.base.src, ty); | 1292 | return mod.constType(scope, inst.base.src, ty); |
| 1290 | } | 1293 | } |
| 1291 | 1294 |