@@ -33,7 +33,7 @@ pub fn run(
33
33
sema : * Sema ,
34
34
file : * File ,
35
35
file_index : Zcu.File.Index ,
36
- res_ty : InternPool.Index ,
36
+ res_ty_interned : InternPool.Index ,
37
37
import_loc : LazySrcLoc ,
38
38
block : * Sema.Block ,
39
39
) CompileError ! InternPool.Index {
@@ -53,13 +53,63 @@ pub fn run(
53
53
.base_node_inst = tracked_inst ,
54
54
};
55
55
56
- try lower_zon .checkType (.fromInterned (res_ty ));
56
+ if (res_ty_interned == .none ) {
57
+ return lower_zon .lowerExprAnonResTy (.root );
58
+ } else {
59
+ const res_ty : Type = .fromInterned (res_ty_interned );
60
+ try lower_zon .checkType (res_ty );
61
+ return lower_zon .lowerExprKnownResTy (.root , res_ty );
62
+ }
63
+ }
57
64
58
- return lower_zon .lowerExpr (.root , .fromInterned (res_ty ));
65
+ fn lowerExprAnonResTy (self : * LowerZon , node : Zoir.Node.Index ) CompileError ! InternPool.Index {
66
+ const gpa = self .sema .gpa ;
67
+ const ip = & self .sema .pt .zcu .intern_pool ;
68
+ switch (node .get (self .file .zoir .? )) {
69
+ .true = > return .bool_true ,
70
+ .false = > return .bool_false ,
71
+ .null = > return .null_value ,
72
+ .pos_inf = > return self .fail (node , "infinity requires a known result type" , .{}),
73
+ .neg_inf = > return self .fail (node , "negative infinity requires a known result type" , .{}),
74
+ .nan = > return self .fail (node , "nan requires a known result type" , .{}),
75
+ .int_literal = > | int | switch (int ) {
76
+ .small = > | val | return self .sema .pt .intern (.{ .int = .{
77
+ .ty = .comptime_int_type ,
78
+ .storage = .{ .i64 = val },
79
+ } }),
80
+ .big = > | val | return self .sema .pt .intern (.{ .int = .{
81
+ .ty = .comptime_int_type ,
82
+ .storage = .{ .big_int = val },
83
+ } }),
84
+ },
85
+ .float_literal = > | val | {
86
+ const result = try self .sema .pt .floatValue (.fromInterned (.comptime_float_type ), val );
87
+ return result .toIntern ();
88
+ },
89
+ .char_literal = > | val | return self .sema .pt .intern (.{ .int = .{
90
+ .ty = .comptime_int_type ,
91
+ .storage = .{ .i64 = val },
92
+ } }),
93
+ .enum_literal = > | val | return self .sema .pt .intern (.{
94
+ .enum_literal = try ip .getOrPutString (
95
+ self .sema .gpa ,
96
+ self .sema .pt .tid ,
97
+ val .get (self .file .zoir .? ),
98
+ .no_embedded_nulls ,
99
+ ),
100
+ }),
101
+ .string_literal = > | val | {
102
+ const ip_str = try ip .getOrPutString (gpa , self .sema .pt .tid , val , .maybe_embedded_nulls );
103
+ const result = try self .sema .addStrLit (ip_str , val .len );
104
+ return result .toInterned ().? ;
105
+ },
106
+ .empty_literal , .array_literal , .struct_literal = > @panic ("unimplemented" ),
107
+ }
59
108
}
60
109
61
- /// Validate that `ty` is a valid ZON type. If not, emit a compile error.
62
- /// i.e. no nested optionals, no error sets, etc.
110
+ /// Validate that `ty` is a valid ZON type, or is `.none`. If it is not, emit a compile error.
111
+ ///
112
+ /// Rules out nested optionals, error sets, etc.
63
113
fn checkType (self : * LowerZon , ty : Type ) ! void {
64
114
var visited : std .AutoHashMapUnmanaged (InternPool.Index , void ) = .empty ;
65
115
try self .checkTypeInner (ty , null , & visited );
@@ -201,9 +251,9 @@ fn fail(
201
251
return self .sema .failWithOwnedErrorMsg (self .block , err_msg );
202
252
}
203
253
204
- fn lowerExpr (self : * LowerZon , node : Zoir.Node.Index , res_ty : Type ) CompileError ! InternPool.Index {
254
+ fn lowerExprKnownResTy (self : * LowerZon , node : Zoir.Node.Index , res_ty : Type ) CompileError ! InternPool.Index {
205
255
const pt = self .sema .pt ;
206
- return self .lowerExprInner (node , res_ty ) catch | err | switch (err ) {
256
+ return self .lowerExprKnownResTyInner (node , res_ty ) catch | err | switch (err ) {
207
257
error .WrongType = > return self .fail (
208
258
node ,
209
259
"expected type '{}'" ,
@@ -213,7 +263,7 @@ fn lowerExpr(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!
213
263
};
214
264
}
215
265
216
- fn lowerExprInner (
266
+ fn lowerExprKnownResTyInner (
217
267
self : * LowerZon ,
218
268
node : Zoir.Node.Index ,
219
269
res_ty : Type ,
@@ -227,7 +277,7 @@ fn lowerExprInner(
227
277
break :b .none ;
228
278
} else b : {
229
279
const child_type = res_ty .optionalChild (pt .zcu );
230
- break :b try self .lowerExprInner (node , child_type );
280
+ break :b try self .lowerExprKnownResTyInner (node , child_type );
231
281
},
232
282
},
233
283
}),
@@ -239,7 +289,7 @@ fn lowerExprInner(
239
289
.base_addr = .{
240
290
.uav = .{
241
291
.orig_ty = res_ty .toIntern (),
242
- .val = try self .lowerExprInner (node , .fromInterned (ptr_info .child )),
292
+ .val = try self .lowerExprKnownResTyInner (node , .fromInterned (ptr_info .child )),
243
293
},
244
294
},
245
295
.byte_offset = 0 ,
@@ -486,7 +536,7 @@ fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
486
536
);
487
537
488
538
for (0.. nodes .len ) | i | {
489
- elems [i ] = try self .lowerExpr (nodes .at (@intCast (i )), array_info .elem_type );
539
+ elems [i ] = try self .lowerExprKnownResTy (nodes .at (@intCast (i )), array_info .elem_type );
490
540
}
491
541
492
542
if (array_info .sentinel ) | sentinel | {
@@ -587,7 +637,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
587
637
);
588
638
}
589
639
590
- const val = try self .lowerExpr (elem_nodes .at (@intCast (i )), .fromInterned (field_types [i ]));
640
+ const val = try self .lowerExprKnownResTy (elem_nodes .at (@intCast (i )), .fromInterned (field_types [i ]));
591
641
592
642
if (elems [i ] != .none and val != elems [i ]) {
593
643
const elem_node = elem_nodes .at (@intCast (i ));
@@ -650,7 +700,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
650
700
};
651
701
652
702
const field_type : Type = .fromInterned (struct_info .field_types .get (ip )[name_index ]);
653
- field_values [name_index ] = try self .lowerExpr (field_node , field_type );
703
+ field_values [name_index ] = try self .lowerExprKnownResTy (field_node , field_type );
654
704
655
705
if (struct_info .comptime_bits .getBit (ip , name_index )) {
656
706
const val = ip .indexToKey (field_values [name_index ]);
@@ -715,7 +765,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
715
765
const elems = try self .sema .arena .alloc (InternPool .Index , elem_nodes .len + @intFromBool (ptr_info .sentinel != .none ));
716
766
717
767
for (elems , 0.. ) | * elem , i | {
718
- elem .* = try self .lowerExpr (elem_nodes .at (@intCast (i )), .fromInterned (ptr_info .child ));
768
+ elem .* = try self .lowerExprKnownResTy (elem_nodes .at (@intCast (i )), .fromInterned (ptr_info .child ));
719
769
}
720
770
721
771
if (ptr_info .sentinel != .none ) {
@@ -810,7 +860,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
810
860
if (field_type .toIntern () == .void_type ) {
811
861
return self .fail (field_node , "expected type 'void'" , .{});
812
862
}
813
- break :b try self .lowerExpr (field_node , field_type );
863
+ break :b try self .lowerExprKnownResTy (field_node , field_type );
814
864
} else b : {
815
865
if (field_type .toIntern () != .void_type ) {
816
866
return error .WrongType ;
@@ -846,7 +896,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
846
896
}
847
897
848
898
for (elems , 0.. ) | * elem , i | {
849
- elem .* = try self .lowerExpr (elem_nodes .at (@intCast (i )), .fromInterned (vector_info .child ));
899
+ elem .* = try self .lowerExprKnownResTy (elem_nodes .at (@intCast (i )), .fromInterned (vector_info .child ));
850
900
}
851
901
852
902
return self .sema .pt .intern (.{ .aggregate = .{
0 commit comments