authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-31 17:24:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-31 17:25:42-07:00
log982acc22fd8674a9efbe1e65e037c464ba610882
tree46593d2090d8d3c3524499cc9eddb06be9401c32
parent79a93914142e33636c37957fd513d42f4ac46060

stage2: compile error for invalid `var` type


6 files changed, 117 insertions(+), 50 deletions(-)

BRANCH_TODO deleted-2
...@@ -1,2 +0,0 @@
1 * compile error for "variable of type '{}' must be const or comptime" after resolving types
2 * test with branches
src/Module.zig+6
...@@ -3421,3 +3421,9 @@ pub fn getTarget(self: Module) Target {...@@ -3421,3 +3421,9 @@ pub fn getTarget(self: Module) Target {
3421pub fn optimizeMode(self: Module) std.builtin.Mode {3421pub fn optimizeMode(self: Module) std.builtin.Mode {
3422 return self.comp.bin_file.options.optimize_mode;3422 return self.comp.bin_file.options.optimize_mode;
3423}3423}
3424
3425pub fn validateVarType(mod: *Module, scope: *Scope, src: usize, ty: Type) !void {
3426 if (!ty.isValidVarType(false)) {
3427 return mod.fail(scope, src, "variable of type '{}' must be const or comptime", .{ty});
3428 }
3429}
src/astgen.zig+1-1
...@@ -625,7 +625,7 @@ fn varDecl(...@@ -625,7 +625,7 @@ fn varDecl(
625 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);625 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
626 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };626 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
627 } else a: {627 } else a: {
628 const alloc = try addZIRNoOpT(mod, scope, name_src, .alloc_inferred);628 const alloc = try addZIRNoOpT(mod, scope, name_src, .alloc_inferred_mut);
629 resolve_inferred_alloc = &alloc.base;629 resolve_inferred_alloc = &alloc.base;
630 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };630 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
631 };631 };
src/type.zig+68-34
...@@ -78,7 +78,8 @@ pub const Type = extern union {...@@ -78,7 +78,8 @@ pub const Type = extern union {
78 .const_slice,78 .const_slice,
79 .mut_slice,79 .mut_slice,
80 .pointer,80 .pointer,
81 .inferred_alloc,81 .inferred_alloc_const,
82 .inferred_alloc_mut,
82 => return .Pointer,83 => return .Pointer,
8384
84 .optional,85 .optional,
...@@ -159,7 +160,8 @@ pub const Type = extern union {...@@ -159,7 +160,8 @@ pub const Type = extern union {
159 .optional_single_mut_pointer,160 .optional_single_mut_pointer,
160 => self.cast(Payload.ElemType),161 => self.cast(Payload.ElemType),
161162
162 .inferred_alloc => unreachable,163 .inferred_alloc_const => unreachable,
164 .inferred_alloc_mut => unreachable,
163165
164 else => null,166 else => null,
165 };167 };
...@@ -387,7 +389,8 @@ pub const Type = extern union {...@@ -387,7 +389,8 @@ pub const Type = extern union {
387 .enum_literal,389 .enum_literal,
388 .anyerror_void_error_union,390 .anyerror_void_error_union,
389 .@"anyframe",391 .@"anyframe",
390 .inferred_alloc,392 .inferred_alloc_const,
393 .inferred_alloc_mut,
391 => unreachable,394 => unreachable,
392395
393 .array_u8,396 .array_u8,
...@@ -690,7 +693,8 @@ pub const Type = extern union {...@@ -690,7 +693,8 @@ pub const Type = extern union {
690 const name = ty.castTag(.error_set_single).?.data;693 const name = ty.castTag(.error_set_single).?.data;
691 return out_stream.print("error{{{s}}}", .{name});694 return out_stream.print("error{{{s}}}", .{name});
692 },695 },
693 .inferred_alloc => return out_stream.writeAll("(inferred allocation type)"),696 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),
697 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),
694 }698 }
695 unreachable;699 unreachable;
696 }700 }
...@@ -738,7 +742,8 @@ pub const Type = extern union {...@@ -738,7 +742,8 @@ pub const Type = extern union {
738 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),742 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
739 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),743 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
740 .enum_literal => return Value.initTag(.enum_literal_type),744 .enum_literal => return Value.initTag(.enum_literal_type),
741 .inferred_alloc => unreachable,745 .inferred_alloc_const => unreachable,
746 .inferred_alloc_mut => unreachable,
742 else => return Value.Tag.ty.create(allocator, self),747 else => return Value.Tag.ty.create(allocator, self),
743 }748 }
744 }749 }
...@@ -810,7 +815,8 @@ pub const Type = extern union {...@@ -810,7 +815,8 @@ pub const Type = extern union {
810 .empty_struct,815 .empty_struct,
811 => false,816 => false,
812817
813 .inferred_alloc => unreachable,818 .inferred_alloc_const => unreachable,
819 .inferred_alloc_mut => unreachable,
814 };820 };
815 }821 }
816822
...@@ -928,7 +934,8 @@ pub const Type = extern union {...@@ -928,7 +934,8 @@ pub const Type = extern union {
928 .@"undefined",934 .@"undefined",
929 .enum_literal,935 .enum_literal,
930 .empty_struct,936 .empty_struct,
931 .inferred_alloc,937 .inferred_alloc_const,
938 .inferred_alloc_mut,
932 => unreachable,939 => unreachable,
933 };940 };
934 }941 }
...@@ -952,7 +959,8 @@ pub const Type = extern union {...@@ -952,7 +959,8 @@ pub const Type = extern union {
952 .enum_literal => unreachable,959 .enum_literal => unreachable,
953 .single_const_pointer_to_comptime_int => unreachable,960 .single_const_pointer_to_comptime_int => unreachable,
954 .empty_struct => unreachable,961 .empty_struct => unreachable,
955 .inferred_alloc => unreachable,962 .inferred_alloc_const => unreachable,
963 .inferred_alloc_mut => unreachable,
956964
957 .u8,965 .u8,
958 .i8,966 .i8,
...@@ -1131,7 +1139,8 @@ pub const Type = extern union {...@@ -1131,7 +1139,8 @@ pub const Type = extern union {
1131 .single_const_pointer,1139 .single_const_pointer,
1132 .single_mut_pointer,1140 .single_mut_pointer,
1133 .single_const_pointer_to_comptime_int,1141 .single_const_pointer_to_comptime_int,
1134 .inferred_alloc,1142 .inferred_alloc_const,
1143 .inferred_alloc_mut,
1135 => true,1144 => true,
11361145
1137 .pointer => self.castTag(.pointer).?.data.size == .One,1146 .pointer => self.castTag(.pointer).?.data.size == .One,
...@@ -1214,7 +1223,8 @@ pub const Type = extern union {...@@ -1214,7 +1223,8 @@ pub const Type = extern union {
1214 .single_const_pointer,1223 .single_const_pointer,
1215 .single_mut_pointer,1224 .single_mut_pointer,
1216 .single_const_pointer_to_comptime_int,1225 .single_const_pointer_to_comptime_int,
1217 .inferred_alloc,1226 .inferred_alloc_const,
1227 .inferred_alloc_mut,
1218 => .One,1228 => .One,
12191229
1220 .pointer => self.castTag(.pointer).?.data.size,1230 .pointer => self.castTag(.pointer).?.data.size,
...@@ -1285,7 +1295,8 @@ pub const Type = extern union {...@@ -1285,7 +1295,8 @@ pub const Type = extern union {
1285 .error_set,1295 .error_set,
1286 .error_set_single,1296 .error_set_single,
1287 .empty_struct,1297 .empty_struct,
1288 .inferred_alloc,1298 .inferred_alloc_const,
1299 .inferred_alloc_mut,
1289 => false,1300 => false,
12901301
1291 .const_slice,1302 .const_slice,
...@@ -1358,7 +1369,8 @@ pub const Type = extern union {...@@ -1358,7 +1369,8 @@ pub const Type = extern union {
1358 .error_set,1369 .error_set,
1359 .error_set_single,1370 .error_set_single,
1360 .empty_struct,1371 .empty_struct,
1361 .inferred_alloc,1372 .inferred_alloc_const,
1373 .inferred_alloc_mut,
1362 => false,1374 => false,
13631375
1364 .single_const_pointer,1376 .single_const_pointer,
...@@ -1440,7 +1452,8 @@ pub const Type = extern union {...@@ -1440,7 +1452,8 @@ pub const Type = extern union {
1440 .error_set,1452 .error_set,
1441 .error_set_single,1453 .error_set_single,
1442 .empty_struct,1454 .empty_struct,
1443 .inferred_alloc,1455 .inferred_alloc_const,
1456 .inferred_alloc_mut,
1444 => false,1457 => false,
14451458
1446 .pointer => {1459 .pointer => {
...@@ -1517,7 +1530,8 @@ pub const Type = extern union {...@@ -1517,7 +1530,8 @@ pub const Type = extern union {
1517 .error_set,1530 .error_set,
1518 .error_set_single,1531 .error_set_single,
1519 .empty_struct,1532 .empty_struct,
1520 .inferred_alloc,1533 .inferred_alloc_const,
1534 .inferred_alloc_mut,
1521 => false,1535 => false,
15221536
1523 .pointer => {1537 .pointer => {
...@@ -1636,7 +1650,8 @@ pub const Type = extern union {...@@ -1636,7 +1650,8 @@ pub const Type = extern union {
1636 .error_set => unreachable,1650 .error_set => unreachable,
1637 .error_set_single => unreachable,1651 .error_set_single => unreachable,
1638 .empty_struct => unreachable,1652 .empty_struct => unreachable,
1639 .inferred_alloc => unreachable,1653 .inferred_alloc_const => unreachable,
1654 .inferred_alloc_mut => unreachable,
16401655
1641 .array => self.castTag(.array).?.data.elem_type,1656 .array => self.castTag(.array).?.data.elem_type,
1642 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,1657 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
...@@ -1758,7 +1773,8 @@ pub const Type = extern union {...@@ -1758,7 +1773,8 @@ pub const Type = extern union {
1758 .error_set,1773 .error_set,
1759 .error_set_single,1774 .error_set_single,
1760 .empty_struct,1775 .empty_struct,
1761 .inferred_alloc,1776 .inferred_alloc_const,
1777 .inferred_alloc_mut,
1762 => unreachable,1778 => unreachable,
17631779
1764 .array => self.castTag(.array).?.data.len,1780 .array => self.castTag(.array).?.data.len,
...@@ -1825,7 +1841,8 @@ pub const Type = extern union {...@@ -1825,7 +1841,8 @@ pub const Type = extern union {
1825 .error_set,1841 .error_set,
1826 .error_set_single,1842 .error_set_single,
1827 .empty_struct,1843 .empty_struct,
1828 .inferred_alloc,1844 .inferred_alloc_const,
1845 .inferred_alloc_mut,
1829 => unreachable,1846 => unreachable,
18301847
1831 .single_const_pointer,1848 .single_const_pointer,
...@@ -1909,7 +1926,8 @@ pub const Type = extern union {...@@ -1909,7 +1926,8 @@ pub const Type = extern union {
1909 .error_set,1926 .error_set,
1910 .error_set_single,1927 .error_set_single,
1911 .empty_struct,1928 .empty_struct,
1912 .inferred_alloc,1929 .inferred_alloc_const,
1930 .inferred_alloc_mut,
1913 => false,1931 => false,
19141932
1915 .int_signed,1933 .int_signed,
...@@ -1985,7 +2003,8 @@ pub const Type = extern union {...@@ -1985,7 +2003,8 @@ pub const Type = extern union {
1985 .error_set,2003 .error_set,
1986 .error_set_single,2004 .error_set_single,
1987 .empty_struct,2005 .empty_struct,
1988 .inferred_alloc,2006 .inferred_alloc_const,
2007 .inferred_alloc_mut,
1989 => false,2008 => false,
19902009
1991 .int_unsigned,2010 .int_unsigned,
...@@ -2051,7 +2070,8 @@ pub const Type = extern union {...@@ -2051,7 +2070,8 @@ pub const Type = extern union {
2051 .error_set,2070 .error_set,
2052 .error_set_single,2071 .error_set_single,
2053 .empty_struct,2072 .empty_struct,
2054 .inferred_alloc,2073 .inferred_alloc_const,
2074 .inferred_alloc_mut,
2055 => unreachable,2075 => unreachable,
20562076
2057 .int_unsigned => .{2077 .int_unsigned => .{
...@@ -2141,7 +2161,8 @@ pub const Type = extern union {...@@ -2141,7 +2161,8 @@ pub const Type = extern union {
2141 .error_set,2161 .error_set,
2142 .error_set_single,2162 .error_set_single,
2143 .empty_struct,2163 .empty_struct,
2144 .inferred_alloc,2164 .inferred_alloc_const,
2165 .inferred_alloc_mut,
2145 => false,2166 => false,
21462167
2147 .usize,2168 .usize,
...@@ -2254,7 +2275,8 @@ pub const Type = extern union {...@@ -2254,7 +2275,8 @@ pub const Type = extern union {
2254 .error_set,2275 .error_set,
2255 .error_set_single,2276 .error_set_single,
2256 .empty_struct,2277 .empty_struct,
2257 .inferred_alloc,2278 .inferred_alloc_const,
2279 .inferred_alloc_mut,
2258 => unreachable,2280 => unreachable,
2259 };2281 };
2260 }2282 }
...@@ -2333,7 +2355,8 @@ pub const Type = extern union {...@@ -2333,7 +2355,8 @@ pub const Type = extern union {
2333 .error_set,2355 .error_set,
2334 .error_set_single,2356 .error_set_single,
2335 .empty_struct,2357 .empty_struct,
2336 .inferred_alloc,2358 .inferred_alloc_const,
2359 .inferred_alloc_mut,
2337 => unreachable,2360 => unreachable,
2338 }2361 }
2339 }2362 }
...@@ -2411,7 +2434,8 @@ pub const Type = extern union {...@@ -2411,7 +2434,8 @@ pub const Type = extern union {
2411 .error_set,2434 .error_set,
2412 .error_set_single,2435 .error_set_single,
2413 .empty_struct,2436 .empty_struct,
2414 .inferred_alloc,2437 .inferred_alloc_const,
2438 .inferred_alloc_mut,
2415 => unreachable,2439 => unreachable,
2416 }2440 }
2417 }2441 }
...@@ -2489,7 +2513,8 @@ pub const Type = extern union {...@@ -2489,7 +2513,8 @@ pub const Type = extern union {
2489 .error_set,2513 .error_set,
2490 .error_set_single,2514 .error_set_single,
2491 .empty_struct,2515 .empty_struct,
2492 .inferred_alloc,2516 .inferred_alloc_const,
2517 .inferred_alloc_mut,
2493 => unreachable,2518 => unreachable,
2494 };2519 };
2495 }2520 }
...@@ -2564,7 +2589,8 @@ pub const Type = extern union {...@@ -2564,7 +2589,8 @@ pub const Type = extern union {
2564 .error_set,2589 .error_set,
2565 .error_set_single,2590 .error_set_single,
2566 .empty_struct,2591 .empty_struct,
2567 .inferred_alloc,2592 .inferred_alloc_const,
2593 .inferred_alloc_mut,
2568 => unreachable,2594 => unreachable,
2569 };2595 };
2570 }2596 }
...@@ -2639,7 +2665,8 @@ pub const Type = extern union {...@@ -2639,7 +2665,8 @@ pub const Type = extern union {
2639 .error_set,2665 .error_set,
2640 .error_set_single,2666 .error_set_single,
2641 .empty_struct,2667 .empty_struct,
2642 .inferred_alloc,2668 .inferred_alloc_const,
2669 .inferred_alloc_mut,
2643 => unreachable,2670 => unreachable,
2644 };2671 };
2645 }2672 }
...@@ -2714,7 +2741,8 @@ pub const Type = extern union {...@@ -2714,7 +2741,8 @@ pub const Type = extern union {
2714 .error_set,2741 .error_set,
2715 .error_set_single,2742 .error_set_single,
2716 .empty_struct,2743 .empty_struct,
2717 .inferred_alloc,2744 .inferred_alloc_const,
2745 .inferred_alloc_mut,
2718 => false,2746 => false,
2719 };2747 };
2720 }2748 }
...@@ -2807,7 +2835,8 @@ pub const Type = extern union {...@@ -2807,7 +2835,8 @@ pub const Type = extern union {
2807 ty = ty.castTag(.pointer).?.data.pointee_type;2835 ty = ty.castTag(.pointer).?.data.pointee_type;
2808 continue;2836 continue;
2809 },2837 },
2810 .inferred_alloc => unreachable,2838 .inferred_alloc_const => unreachable,
2839 .inferred_alloc_mut => unreachable,
2811 };2840 };
2812 }2841 }
28132842
...@@ -2876,7 +2905,8 @@ pub const Type = extern union {...@@ -2876,7 +2905,8 @@ pub const Type = extern union {
2876 .error_set,2905 .error_set,
2877 .error_set_single,2906 .error_set_single,
2878 .empty_struct,2907 .empty_struct,
2879 .inferred_alloc,2908 .inferred_alloc_const,
2909 .inferred_alloc_mut,
2880 => return false,2910 => return false,
28812911
2882 .c_const_pointer,2912 .c_const_pointer,
...@@ -2962,7 +2992,8 @@ pub const Type = extern union {...@@ -2962,7 +2992,8 @@ pub const Type = extern union {
2962 .c_const_pointer,2992 .c_const_pointer,
2963 .c_mut_pointer,2993 .c_mut_pointer,
2964 .pointer,2994 .pointer,
2965 .inferred_alloc,2995 .inferred_alloc_const,
2996 .inferred_alloc_mut,
2966 => unreachable,2997 => unreachable,
29672998
2968 .empty_struct => self.castTag(.empty_struct).?.data,2999 .empty_struct => self.castTag(.empty_struct).?.data,
...@@ -3077,7 +3108,9 @@ pub const Type = extern union {...@@ -3077,7 +3108,9 @@ pub const Type = extern union {
3077 /// This is a special value that tracks a set of types that have been stored3108 /// This is a special value that tracks a set of types that have been stored
3078 /// to an inferred allocation. It does not support most of the normal type queries.3109 /// to an inferred allocation. It does not support most of the normal type queries.
3079 /// However it does respond to `isConstPtr`, `ptrSize`, `zigTypeTag`, etc.3110 /// However it does respond to `isConstPtr`, `ptrSize`, `zigTypeTag`, etc.
3080 inferred_alloc, // See last_no_payload_tag below.3111 inferred_alloc_mut,
3112 /// Same as `inferred_alloc_mut` but the local is `var` not `const`.
3113 inferred_alloc_const, // See last_no_payload_tag below.
3081 // After this, the tag requires a payload.3114 // After this, the tag requires a payload.
30823115
3083 array_u8,3116 array_u8,
...@@ -3105,7 +3138,7 @@ pub const Type = extern union {...@@ -3105,7 +3138,7 @@ pub const Type = extern union {
3105 error_set_single,3138 error_set_single,
3106 empty_struct,3139 empty_struct,
31073140
3108 pub const last_no_payload_tag = Tag.inferred_alloc;3141 pub const last_no_payload_tag = Tag.inferred_alloc_const;
3109 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;3142 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
31103143
3111 pub fn Type(comptime t: Tag) type {3144 pub fn Type(comptime t: Tag) type {
...@@ -3152,7 +3185,8 @@ pub const Type = extern union {...@@ -3152,7 +3185,8 @@ pub const Type = extern union {
3152 .anyerror_void_error_union,3185 .anyerror_void_error_union,
3153 .@"anyframe",3186 .@"anyframe",
3154 .const_slice_u8,3187 .const_slice_u8,
3155 .inferred_alloc,3188 .inferred_alloc_const,
3189 .inferred_alloc_mut,
3156 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),3190 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
31573191
3158 .array_u8,3192 .array_u8,
src/zir_sema.zig+33-13
...@@ -30,8 +30,18 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!...@@ -30,8 +30,18 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
30 switch (old_inst.tag) {30 switch (old_inst.tag) {
31 .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?),31 .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?),
32 .alloc_mut => return analyzeInstAllocMut(mod, scope, old_inst.castTag(.alloc_mut).?),32 .alloc_mut => return analyzeInstAllocMut(mod, scope, old_inst.castTag(.alloc_mut).?),
33 .alloc_inferred => return analyzeInstAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred).?),33 .alloc_inferred => return analyzeInstAllocInferred(
34 .alloc_inferred_mut => return analyzeInstAllocInferredMut(mod, scope, old_inst.castTag(.alloc_inferred_mut).?),34 mod,
35 scope,
36 old_inst.castTag(.alloc_inferred).?,
37 .inferred_alloc_const,
38 ),
39 .alloc_inferred_mut => return analyzeInstAllocInferred(
40 mod,
41 scope,
42 old_inst.castTag(.alloc_inferred_mut).?,
43 .inferred_alloc_mut,
44 ),
35 .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?),45 .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?),
36 .bitcast_ref => return analyzeInstBitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),46 .bitcast_ref => return analyzeInstBitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),
37 .bitcast_result_ptr => return analyzeInstBitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),47 .bitcast_result_ptr => return analyzeInstBitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),
...@@ -423,15 +433,18 @@ fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErro...@@ -423,15 +433,18 @@ fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErro
423433
424fn analyzeInstAllocMut(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {434fn analyzeInstAllocMut(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
425 const var_type = try resolveType(mod, scope, inst.positionals.operand);435 const var_type = try resolveType(mod, scope, inst.positionals.operand);
426 if (!var_type.isValidVarType(false)) {436 try mod.validateVarType(scope, inst.base.src, var_type);
427 return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type});
428 }
429 const ptr_type = try mod.simplePtrType(scope, inst.base.src, var_type, true, .One);437 const ptr_type = try mod.simplePtrType(scope, inst.base.src, var_type, true, .One);
430 const b = try mod.requireRuntimeBlock(scope, inst.base.src);438 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
431 return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);439 return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);
432}440}
433441
434fn analyzeInstAllocInferred(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {442fn analyzeInstAllocInferred(
443 mod: *Module,
444 scope: *Scope,
445 inst: *zir.Inst.NoOp,
446 mut_tag: Type.Tag,
447) InnerError!*Inst {
435 const val_payload = try scope.arena().create(Value.Payload.InferredAlloc);448 const val_payload = try scope.arena().create(Value.Payload.InferredAlloc);
436 val_payload.* = .{449 val_payload.* = .{
437 .data = .{},450 .data = .{},
...@@ -441,7 +454,11 @@ fn analyzeInstAllocInferred(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) I...@@ -441,7 +454,11 @@ fn analyzeInstAllocInferred(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) I
441 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append454 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append
442 // to the block even though it is currently a `.constant`.455 // to the block even though it is currently a `.constant`.
443 const result = try mod.constInst(scope, inst.base.src, .{456 const result = try mod.constInst(scope, inst.base.src, .{
444 .ty = Type.initTag(.inferred_alloc),457 .ty = switch (mut_tag) {
458 .inferred_alloc_const => Type.initTag(.inferred_alloc_const),
459 .inferred_alloc_mut => Type.initTag(.inferred_alloc_mut),
460 else => unreachable,
461 },
445 .val = Value.initPayload(&val_payload.base),462 .val = Value.initPayload(&val_payload.base),
446 });463 });
447 const block = try mod.requireFunctionBlock(scope, inst.base.src);464 const block = try mod.requireFunctionBlock(scope, inst.base.src);
...@@ -449,10 +466,6 @@ fn analyzeInstAllocInferred(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) I...@@ -449,10 +466,6 @@ fn analyzeInstAllocInferred(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) I
449 return result;466 return result;
450}467}
451468
452fn analyzeInstAllocInferredMut(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
453 return mod.fail(scope, inst.base.src, "TODO implement analyzeInstAllocInferredMut", .{});
454}
455
456fn analyzeInstResolveInferredAlloc(469fn analyzeInstResolveInferredAlloc(
457 mod: *Module,470 mod: *Module,
458 scope: *Scope,471 scope: *Scope,
...@@ -463,8 +476,15 @@ fn analyzeInstResolveInferredAlloc(...@@ -463,8 +476,15 @@ fn analyzeInstResolveInferredAlloc(
463 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;476 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;
464 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;477 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;
465 const final_elem_ty = try mod.resolvePeerTypes(scope, peer_inst_list);478 const final_elem_ty = try mod.resolvePeerTypes(scope, peer_inst_list);
466 const is_mut = true;479 const var_is_mut = switch (ptr.ty.tag()) {
467 const final_ptr_ty = try mod.simplePtrType(scope, inst.base.src, final_elem_ty, is_mut, .One);480 .inferred_alloc_const => false,
481 .inferred_alloc_mut => true,
482 else => unreachable,
483 };
484 if (var_is_mut) {
485 try mod.validateVarType(scope, inst.base.src, final_elem_ty);
486 }
487 const final_ptr_ty = try mod.simplePtrType(scope, inst.base.src, final_elem_ty, true, .One);
468488
469 // Change it to a normal alloc.489 // Change it to a normal alloc.
470 ptr.ty = final_ptr_ty;490 ptr.ty = final_ptr_ty;
test/stage2/test.zig+9
...@@ -1322,4 +1322,13 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1322,4 +1322,13 @@ pub fn addCases(ctx: *TestContext) !void {
1322 \\}1322 \\}
1323 , &[_][]const u8{":2:5: error: unused for label"});1323 , &[_][]const u8{":2:5: error: unused for label"});
1324 }1324 }
1325
1326 {
1327 var case = ctx.exe("bad inferred variable type", linux_x64);
1328 case.addError(
1329 \\export fn foo() void {
1330 \\ var x = null;
1331 \\}
1332 , &[_][]const u8{":2:9: error: variable of type '@Type(.Null)' must be const or comptime"});
1333 }
1325}1334}