| ... | ... | @@ -44,14 +44,13 @@ pub const Error = union(enum) { |
| 44 | 44 | pub const Iterator = struct { |
| 45 | 45 | index: usize = 0, |
| 46 | 46 | err: Error, |
| 47 | | status: *const Status, |
| 47 | diag: *const Diagnostics, |
| 48 | 48 | |
| 49 | 49 | pub fn next(self: *@This()) ?Note { |
| 50 | 50 | switch (self.err) { |
| 51 | 51 | .zoir => |err| { |
| 52 | 52 | if (self.index >= err.note_count) return null; |
| 53 | | const zoir = self.status.zoir.?; |
| 54 | | const note = err.getNotes(zoir)[self.index]; |
| 53 | const note = err.getNotes(self.diag.zoir)[self.index]; |
| 55 | 54 | self.index += 1; |
| 56 | 55 | return .{ .zoir = note }; |
| 57 | 56 | }, |
| ... | ... | @@ -80,37 +79,34 @@ pub const Error = union(enum) { |
| 80 | 79 | try writer.writeAll(self); |
| 81 | 80 | } |
| 82 | 81 | |
| 83 | | pub fn fmtMessage(self: Note, status: *const Status) std.fmt.Formatter(Note.formatMessage) { |
| 82 | pub fn fmtMessage(self: Note, diag: *const Diagnostics) std.fmt.Formatter(Note.formatMessage) { |
| 84 | 83 | return .{ .data = switch (self) { |
| 85 | | .zoir => |note| note.msg.get(status.zoir.?), |
| 84 | .zoir => |note| note.msg.get(diag.zoir), |
| 86 | 85 | .type_check => |note| note.msg, |
| 87 | 86 | } }; |
| 88 | 87 | } |
| 89 | 88 | |
| 90 | | pub fn getLocation(self: Note, status: *const Status) Ast.Location { |
| 91 | | const ast = status.ast.?; |
| 89 | pub fn getLocation(self: Note, diag: *const Diagnostics) Ast.Location { |
| 92 | 90 | switch (self) { |
| 93 | | .zoir => |note| return zoirErrorLocation(ast, note.token, note.node_or_offset), |
| 94 | | .type_check => |note| return ast.tokenLocation(note.offset, note.token), |
| 91 | .zoir => |note| return zoirErrorLocation(diag.ast, note.token, note.node_or_offset), |
| 92 | .type_check => |note| return diag.ast.tokenLocation(note.offset, note.token), |
| 95 | 93 | } |
| 96 | 94 | } |
| 97 | 95 | }; |
| 98 | 96 | |
| 99 | 97 | pub const Iterator = struct { |
| 100 | 98 | index: usize = 0, |
| 101 | | status: *const Status, |
| 99 | diag: *const Diagnostics, |
| 102 | 100 | |
| 103 | 101 | pub fn next(self: *@This()) ?Error { |
| 104 | | const zoir = self.status.zoir orelse return null; |
| 105 | | |
| 106 | | if (self.index < zoir.compile_errors.len) { |
| 107 | | const result: Error = .{ .zoir = zoir.compile_errors[self.index] }; |
| 102 | if (self.index < self.diag.zoir.compile_errors.len) { |
| 103 | const result: Error = .{ .zoir = self.diag.zoir.compile_errors[self.index] }; |
| 108 | 104 | self.index += 1; |
| 109 | 105 | return result; |
| 110 | 106 | } |
| 111 | 107 | |
| 112 | | if (self.status.type_check) |err| { |
| 113 | | if (self.index == zoir.compile_errors.len) { |
| 108 | if (self.diag.type_check) |err| { |
| 109 | if (self.index == self.diag.zoir.compile_errors.len) { |
| 114 | 110 | const result: Error = .{ .type_check = err }; |
| 115 | 111 | self.index += 1; |
| 116 | 112 | return result; |
| ... | ... | @@ -156,7 +152,7 @@ pub const Error = union(enum) { |
| 156 | 152 | |
| 157 | 153 | const FormatMessage = struct { |
| 158 | 154 | err: Error, |
| 159 | | status: *const Status, |
| 155 | diag: *const Diagnostics, |
| 160 | 156 | }; |
| 161 | 157 | |
| 162 | 158 | fn formatMessage( |
| ... | ... | @@ -168,32 +164,31 @@ pub const Error = union(enum) { |
| 168 | 164 | _ = f; |
| 169 | 165 | _ = options; |
| 170 | 166 | switch (self.err) { |
| 171 | | .zoir => |err| try writer.writeAll(err.msg.get(self.status.zoir.?)), |
| 167 | .zoir => |err| try writer.writeAll(err.msg.get(self.diag.zoir)), |
| 172 | 168 | .type_check => |tc| try writer.writeAll(tc.message), |
| 173 | 169 | } |
| 174 | 170 | } |
| 175 | 171 | |
| 176 | | pub fn fmtMessage(self: @This(), status: *const Status) std.fmt.Formatter(formatMessage) { |
| 172 | pub fn fmtMessage(self: @This(), diag: *const Diagnostics) std.fmt.Formatter(formatMessage) { |
| 177 | 173 | return .{ .data = .{ |
| 178 | 174 | .err = self, |
| 179 | | .status = status, |
| 175 | .diag = diag, |
| 180 | 176 | } }; |
| 181 | 177 | } |
| 182 | 178 | |
| 183 | | pub fn getLocation(self: @This(), status: *const Status) Ast.Location { |
| 184 | | const ast = status.ast.?; |
| 179 | pub fn getLocation(self: @This(), diag: *const Diagnostics) Ast.Location { |
| 185 | 180 | return switch (self) { |
| 186 | 181 | .zoir => |err| return zoirErrorLocation( |
| 187 | | status.ast.?, |
| 182 | diag.ast, |
| 188 | 183 | err.token, |
| 189 | 184 | err.node_or_offset, |
| 190 | 185 | ), |
| 191 | | .type_check => |err| return ast.tokenLocation(err.offset, err.token), |
| 186 | .type_check => |err| return diag.ast.tokenLocation(err.offset, err.token), |
| 192 | 187 | }; |
| 193 | 188 | } |
| 194 | 189 | |
| 195 | | pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator { |
| 196 | | return .{ .err = self, .status = status }; |
| 190 | pub fn iterateNotes(self: @This(), diag: *const Diagnostics) Note.Iterator { |
| 191 | return .{ .err = self, .diag = diag }; |
| 197 | 192 | } |
| 198 | 193 | |
| 199 | 194 | fn zoirErrorLocation(ast: Ast, maybe_token: Ast.OptionalTokenIndex, node_or_offset: u32) Ast.Location { |
| ... | ... | @@ -210,26 +205,40 @@ pub const Error = union(enum) { |
| 210 | 205 | }; |
| 211 | 206 | |
| 212 | 207 | /// Information about the success or failure of a parse. |
| 213 | | pub const Status = struct { |
| 214 | | ast: ?Ast = null, |
| 215 | | zoir: ?Zoir = null, |
| 208 | pub const Diagnostics = struct { |
| 209 | ast: Ast = .{ |
| 210 | .source = "", |
| 211 | .tokens = .empty, |
| 212 | .nodes = .empty, |
| 213 | .extra_data = &.{}, |
| 214 | .mode = .zon, |
| 215 | .errors = &.{}, |
| 216 | }, |
| 217 | zoir: Zoir = .{ |
| 218 | .nodes = .empty, |
| 219 | .extra = &.{}, |
| 220 | .limbs = &.{}, |
| 221 | .string_bytes = &.{}, |
| 222 | .compile_errors = &.{}, |
| 223 | .error_notes = &.{}, |
| 224 | }, |
| 216 | 225 | type_check: ?Error.TypeCheckFailure = null, |
| 217 | 226 | |
| 218 | | fn assertEmpty(self: Status) void { |
| 219 | | assert(self.ast == null); |
| 220 | | assert(self.zoir == null); |
| 227 | fn assertEmpty(self: Diagnostics) void { |
| 228 | assert(self.ast.tokens.len == 0); |
| 229 | assert(self.zoir.nodes.len == 0); |
| 221 | 230 | assert(self.type_check == null); |
| 222 | 231 | } |
| 223 | 232 | |
| 224 | | pub fn deinit(self: *Status, gpa: Allocator) void { |
| 225 | | if (self.ast) |*ast| ast.deinit(gpa); |
| 226 | | if (self.zoir) |*zoir| zoir.deinit(gpa); |
| 233 | pub fn deinit(self: *Diagnostics, gpa: Allocator) void { |
| 234 | self.ast.deinit(gpa); |
| 235 | self.zoir.deinit(gpa); |
| 227 | 236 | if (self.type_check) |tc| tc.deinit(gpa); |
| 228 | 237 | self.* = undefined; |
| 229 | 238 | } |
| 230 | 239 | |
| 231 | | pub fn iterateErrors(self: *const Status) Error.Iterator { |
| 232 | | return .{ .status = self }; |
| 240 | pub fn iterateErrors(self: *const Diagnostics) Error.Iterator { |
| 241 | return .{ .diag = self }; |
| 233 | 242 | } |
| 234 | 243 | |
| 235 | 244 | pub fn format( |
| ... | ... | @@ -266,7 +275,7 @@ pub const Status = struct { |
| 266 | 275 | /// invalid or can not be deserialized into type `T`. |
| 267 | 276 | /// |
| 268 | 277 | /// When the parser returns `error.ParseZon`, it will also store a human readable explanation in |
| 269 | | /// `status` if non null. If status is not null, it must be initialized to `.{}`. |
| 278 | /// `diag` if non null. If diag is not null, it must be initialized to `.{}`. |
| 270 | 279 | pub fn fromSlice( |
| 271 | 280 | /// The type to deserialize into. May not be or contain any of the following types: |
| 272 | 281 | /// * Any comptime-only type, except in a comptime field |
| ... | ... | @@ -283,22 +292,22 @@ pub fn fromSlice( |
| 283 | 292 | T: type, |
| 284 | 293 | gpa: Allocator, |
| 285 | 294 | source: [:0]const u8, |
| 286 | | status: ?*Status, |
| 295 | diag: ?*Diagnostics, |
| 287 | 296 | options: Options, |
| 288 | 297 | ) error{ OutOfMemory, ParseZon }!T { |
| 289 | | if (status) |s| s.assertEmpty(); |
| 298 | if (diag) |s| s.assertEmpty(); |
| 290 | 299 | |
| 291 | 300 | var ast = try std.zig.Ast.parse(gpa, source, .zon); |
| 292 | | defer if (status == null) ast.deinit(gpa); |
| 293 | | if (status) |s| s.ast = ast; |
| 301 | defer if (diag == null) ast.deinit(gpa); |
| 302 | if (diag) |s| s.ast = ast; |
| 294 | 303 | |
| 295 | | // If there's no status, Zoir exists for the lifetime of this function. If there is a status, |
| 296 | | // ownership is transferred to status. |
| 304 | // If there's no diagnostics, Zoir exists for the lifetime of this function. If there is a |
| 305 | // diagnostics, ownership is transferred to diagnostics. |
| 297 | 306 | var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false }); |
| 298 | | defer if (status == null) zoir.deinit(gpa); |
| 307 | defer if (diag == null) zoir.deinit(gpa); |
| 299 | 308 | |
| 300 | | if (status) |s| s.* = .{}; |
| 301 | | return fromZoir(T, gpa, ast, zoir, status, options); |
| 309 | if (diag) |s| s.* = .{}; |
| 310 | return fromZoir(T, gpa, ast, zoir, diag, options); |
| 302 | 311 | } |
| 303 | 312 | |
| 304 | 313 | /// Like `fromSlice`, but operates on `Zoir` instead of ZON source. |
| ... | ... | @@ -307,10 +316,10 @@ pub fn fromZoir( |
| 307 | 316 | gpa: Allocator, |
| 308 | 317 | ast: Ast, |
| 309 | 318 | zoir: Zoir, |
| 310 | | status: ?*Status, |
| 319 | diag: ?*Diagnostics, |
| 311 | 320 | options: Options, |
| 312 | 321 | ) error{ OutOfMemory, ParseZon }!T { |
| 313 | | return fromZoirNode(T, gpa, ast, zoir, .root, status, options); |
| 322 | return fromZoirNode(T, gpa, ast, zoir, .root, diag, options); |
| 314 | 323 | } |
| 315 | 324 | |
| 316 | 325 | /// Like `fromZoir`, but the parse starts on `node` instead of root. |
| ... | ... | @@ -320,12 +329,12 @@ pub fn fromZoirNode( |
| 320 | 329 | ast: Ast, |
| 321 | 330 | zoir: Zoir, |
| 322 | 331 | node: Zoir.Node.Index, |
| 323 | | status: ?*Status, |
| 332 | diag: ?*Diagnostics, |
| 324 | 333 | options: Options, |
| 325 | 334 | ) error{ OutOfMemory, ParseZon }!T { |
| 326 | 335 | comptime assert(canParseType(T)); |
| 327 | 336 | |
| 328 | | if (status) |s| { |
| 337 | if (diag) |s| { |
| 329 | 338 | s.assertEmpty(); |
| 330 | 339 | s.ast = ast; |
| 331 | 340 | s.zoir = zoir; |
| ... | ... | @@ -340,7 +349,7 @@ pub fn fromZoirNode( |
| 340 | 349 | .ast = ast, |
| 341 | 350 | .zoir = zoir, |
| 342 | 351 | .options = options, |
| 343 | | .status = status, |
| 352 | .diag = diag, |
| 344 | 353 | }; |
| 345 | 354 | |
| 346 | 355 | return parser.parseExpr(T, node); |
| ... | ... | @@ -421,7 +430,7 @@ const Parser = struct { |
| 421 | 430 | gpa: Allocator, |
| 422 | 431 | ast: Ast, |
| 423 | 432 | zoir: Zoir, |
| 424 | | status: ?*Status, |
| 433 | diag: ?*Diagnostics, |
| 425 | 434 | options: Options, |
| 426 | 435 | |
| 427 | 436 | fn parseExpr(self: *@This(), T: type, node: Zoir.Node.Index) error{ ParseZon, OutOfMemory }!T { |
| ... | ... | @@ -436,6 +445,10 @@ const Parser = struct { |
| 436 | 445 | T: type, |
| 437 | 446 | node: Zoir.Node.Index, |
| 438 | 447 | ) error{ ParseZon, OutOfMemory, WrongType }!T { |
| 448 | if (T == Zoir.Node.Index) { |
| 449 | return node; |
| 450 | } |
| 451 | |
| 439 | 452 | switch (@typeInfo(T)) { |
| 440 | 453 | .optional => |optional| if (node.get(self.zoir) == .null) { |
| 441 | 454 | return null; |
| ... | ... | @@ -984,7 +997,7 @@ const Parser = struct { |
| 984 | 997 | ) error{ OutOfMemory, ParseZon } { |
| 985 | 998 | @branchHint(.cold); |
| 986 | 999 | comptime assert(args.len > 0); |
| 987 | | if (self.status) |s| s.type_check = .{ |
| 1000 | if (self.diag) |s| s.type_check = .{ |
| 988 | 1001 | .token = token, |
| 989 | 1002 | .offset = offset, |
| 990 | 1003 | .message = std.fmt.allocPrint(self.gpa, fmt, args) catch |err| { |
| ... | ... | @@ -1013,7 +1026,7 @@ const Parser = struct { |
| 1013 | 1026 | failure: Error.TypeCheckFailure, |
| 1014 | 1027 | ) error{ParseZon} { |
| 1015 | 1028 | @branchHint(.cold); |
| 1016 | | if (self.status) |s| s.type_check = failure; |
| 1029 | if (self.diag) |s| s.type_check = failure; |
| 1017 | 1030 | return error.ParseZon; |
| 1018 | 1031 | } |
| 1019 | 1032 | |
| ... | ... | @@ -1279,13 +1292,13 @@ test "std.zon requiresAllocator" { |
| 1279 | 1292 | |
| 1280 | 1293 | test "std.zon ast errors" { |
| 1281 | 1294 | const gpa = std.testing.allocator; |
| 1282 | | var status: Status = .{}; |
| 1283 | | defer status.deinit(gpa); |
| 1295 | var diag: Diagnostics = .{}; |
| 1296 | defer diag.deinit(gpa); |
| 1284 | 1297 | try std.testing.expectError( |
| 1285 | 1298 | error.ParseZon, |
| 1286 | | fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &status, .{}), |
| 1299 | fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &diag, .{}), |
| 1287 | 1300 | ); |
| 1288 | | try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{}", .{status}); |
| 1301 | try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{}", .{diag}); |
| 1289 | 1302 | } |
| 1290 | 1303 | |
| 1291 | 1304 | test "std.zon comments" { |
| ... | ... | @@ -1298,17 +1311,17 @@ test "std.zon comments" { |
| 1298 | 1311 | , null, .{})); |
| 1299 | 1312 | |
| 1300 | 1313 | { |
| 1301 | | var status: Status = .{}; |
| 1302 | | defer status.deinit(gpa); |
| 1314 | var diag: Diagnostics = .{}; |
| 1315 | defer diag.deinit(gpa); |
| 1303 | 1316 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, |
| 1304 | 1317 | \\//! comment |
| 1305 | 1318 | \\10 // comment |
| 1306 | 1319 | \\// comment |
| 1307 | | , &status, .{})); |
| 1320 | , &diag, .{})); |
| 1308 | 1321 | try std.testing.expectFmt( |
| 1309 | 1322 | "1:1: error: expected expression, found 'a document comment'\n", |
| 1310 | 1323 | "{}", |
| 1311 | | .{status}, |
| 1324 | .{diag}, |
| 1312 | 1325 | ); |
| 1313 | 1326 | } |
| 1314 | 1327 | } |
| ... | ... | @@ -1319,16 +1332,16 @@ test "std.zon failure/oom formatting" { |
| 1319 | 1332 | .fail_index = 0, |
| 1320 | 1333 | .resize_fail_index = 0, |
| 1321 | 1334 | }); |
| 1322 | | var status: Status = .{}; |
| 1323 | | defer status.deinit(gpa); |
| 1335 | var diag: Diagnostics = .{}; |
| 1336 | defer diag.deinit(gpa); |
| 1324 | 1337 | try std.testing.expectError(error.OutOfMemory, fromSlice( |
| 1325 | 1338 | []const u8, |
| 1326 | 1339 | failing_allocator.allocator(), |
| 1327 | 1340 | "\"foo\"", |
| 1328 | | &status, |
| 1341 | &diag, |
| 1329 | 1342 | .{}, |
| 1330 | 1343 | )); |
| 1331 | | try std.testing.expectFmt("", "{}", .{status}); |
| 1344 | try std.testing.expectFmt("", "{}", .{diag}); |
| 1332 | 1345 | } |
| 1333 | 1346 | |
| 1334 | 1347 | test "std.zon fromSlice syntax error" { |
| ... | ... | @@ -1397,11 +1410,11 @@ test "std.zon unions" { |
| 1397 | 1410 | // Unknown field |
| 1398 | 1411 | { |
| 1399 | 1412 | const Union = union { x: f32, y: f32 }; |
| 1400 | | var status: Status = .{}; |
| 1401 | | defer status.deinit(gpa); |
| 1413 | var diag: Diagnostics = .{}; |
| 1414 | defer diag.deinit(gpa); |
| 1402 | 1415 | try std.testing.expectError( |
| 1403 | 1416 | error.ParseZon, |
| 1404 | | fromSlice(Union, gpa, ".{.z=2.5}", &status, .{}), |
| 1417 | fromSlice(Union, gpa, ".{.z=2.5}", &diag, .{}), |
| 1405 | 1418 | ); |
| 1406 | 1419 | try std.testing.expectFmt( |
| 1407 | 1420 | \\1:4: error: unexpected field 'z' |
| ... | ... | @@ -1409,78 +1422,78 @@ test "std.zon unions" { |
| 1409 | 1422 | \\ |
| 1410 | 1423 | , |
| 1411 | 1424 | "{}", |
| 1412 | | .{status}, |
| 1425 | .{diag}, |
| 1413 | 1426 | ); |
| 1414 | 1427 | } |
| 1415 | 1428 | |
| 1416 | 1429 | // Explicit void field |
| 1417 | 1430 | { |
| 1418 | 1431 | const Union = union(enum) { x: void }; |
| 1419 | | var status: Status = .{}; |
| 1420 | | defer status.deinit(gpa); |
| 1432 | var diag: Diagnostics = .{}; |
| 1433 | defer diag.deinit(gpa); |
| 1421 | 1434 | try std.testing.expectError( |
| 1422 | 1435 | error.ParseZon, |
| 1423 | | fromSlice(Union, gpa, ".{.x=1}", &status, .{}), |
| 1436 | fromSlice(Union, gpa, ".{.x=1}", &diag, .{}), |
| 1424 | 1437 | ); |
| 1425 | | try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{}", .{status}); |
| 1438 | try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{}", .{diag}); |
| 1426 | 1439 | } |
| 1427 | 1440 | |
| 1428 | 1441 | // Extra field |
| 1429 | 1442 | { |
| 1430 | 1443 | const Union = union { x: f32, y: bool }; |
| 1431 | | var status: Status = .{}; |
| 1432 | | defer status.deinit(gpa); |
| 1444 | var diag: Diagnostics = .{}; |
| 1445 | defer diag.deinit(gpa); |
| 1433 | 1446 | try std.testing.expectError( |
| 1434 | 1447 | error.ParseZon, |
| 1435 | | fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &status, .{}), |
| 1448 | fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &diag, .{}), |
| 1436 | 1449 | ); |
| 1437 | | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status}); |
| 1450 | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag}); |
| 1438 | 1451 | } |
| 1439 | 1452 | |
| 1440 | 1453 | // No fields |
| 1441 | 1454 | { |
| 1442 | 1455 | const Union = union { x: f32, y: bool }; |
| 1443 | | var status: Status = .{}; |
| 1444 | | defer status.deinit(gpa); |
| 1456 | var diag: Diagnostics = .{}; |
| 1457 | defer diag.deinit(gpa); |
| 1445 | 1458 | try std.testing.expectError( |
| 1446 | 1459 | error.ParseZon, |
| 1447 | | fromSlice(Union, gpa, ".{}", &status, .{}), |
| 1460 | fromSlice(Union, gpa, ".{}", &diag, .{}), |
| 1448 | 1461 | ); |
| 1449 | | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status}); |
| 1462 | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag}); |
| 1450 | 1463 | } |
| 1451 | 1464 | |
| 1452 | 1465 | // Enum literals cannot coerce into untagged unions |
| 1453 | 1466 | { |
| 1454 | 1467 | const Union = union { x: void }; |
| 1455 | | var status: Status = .{}; |
| 1456 | | defer status.deinit(gpa); |
| 1457 | | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{})); |
| 1458 | | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status}); |
| 1468 | var diag: Diagnostics = .{}; |
| 1469 | defer diag.deinit(gpa); |
| 1470 | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{})); |
| 1471 | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag}); |
| 1459 | 1472 | } |
| 1460 | 1473 | |
| 1461 | 1474 | // Unknown field for enum literal coercion |
| 1462 | 1475 | { |
| 1463 | 1476 | const Union = union(enum) { x: void }; |
| 1464 | | var status: Status = .{}; |
| 1465 | | defer status.deinit(gpa); |
| 1466 | | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &status, .{})); |
| 1477 | var diag: Diagnostics = .{}; |
| 1478 | defer diag.deinit(gpa); |
| 1479 | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &diag, .{})); |
| 1467 | 1480 | try std.testing.expectFmt( |
| 1468 | 1481 | \\1:2: error: unexpected field 'y' |
| 1469 | 1482 | \\1:2: note: supported: 'x' |
| 1470 | 1483 | \\ |
| 1471 | 1484 | , |
| 1472 | 1485 | "{}", |
| 1473 | | .{status}, |
| 1486 | .{diag}, |
| 1474 | 1487 | ); |
| 1475 | 1488 | } |
| 1476 | 1489 | |
| 1477 | 1490 | // Non void field for enum literal coercion |
| 1478 | 1491 | { |
| 1479 | 1492 | const Union = union(enum) { x: f32 }; |
| 1480 | | var status: Status = .{}; |
| 1481 | | defer status.deinit(gpa); |
| 1482 | | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{})); |
| 1483 | | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status}); |
| 1493 | var diag: Diagnostics = .{}; |
| 1494 | defer diag.deinit(gpa); |
| 1495 | try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{})); |
| 1496 | try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag}); |
| 1484 | 1497 | } |
| 1485 | 1498 | } |
| 1486 | 1499 | |
| ... | ... | @@ -1525,11 +1538,11 @@ test "std.zon structs" { |
| 1525 | 1538 | // Unknown field |
| 1526 | 1539 | { |
| 1527 | 1540 | const Vec2 = struct { x: f32, y: f32 }; |
| 1528 | | var status: Status = .{}; |
| 1529 | | defer status.deinit(gpa); |
| 1541 | var diag: Diagnostics = .{}; |
| 1542 | defer diag.deinit(gpa); |
| 1530 | 1543 | try std.testing.expectError( |
| 1531 | 1544 | error.ParseZon, |
| 1532 | | fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}), |
| 1545 | fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}), |
| 1533 | 1546 | ); |
| 1534 | 1547 | try std.testing.expectFmt( |
| 1535 | 1548 | \\1:12: error: unexpected field 'z' |
| ... | ... | @@ -1537,24 +1550,24 @@ test "std.zon structs" { |
| 1537 | 1550 | \\ |
| 1538 | 1551 | , |
| 1539 | 1552 | "{}", |
| 1540 | | .{status}, |
| 1553 | .{diag}, |
| 1541 | 1554 | ); |
| 1542 | 1555 | } |
| 1543 | 1556 | |
| 1544 | 1557 | // Duplicate field |
| 1545 | 1558 | { |
| 1546 | 1559 | const Vec2 = struct { x: f32, y: f32 }; |
| 1547 | | var status: Status = .{}; |
| 1548 | | defer status.deinit(gpa); |
| 1560 | var diag: Diagnostics = .{}; |
| 1561 | defer diag.deinit(gpa); |
| 1549 | 1562 | try std.testing.expectError( |
| 1550 | 1563 | error.ParseZon, |
| 1551 | | fromSlice(Vec2, gpa, ".{.x=1.5, .x=2.5, .x=3.5}", &status, .{}), |
| 1564 | fromSlice(Vec2, gpa, ".{.x=1.5, .x=2.5, .x=3.5}", &diag, .{}), |
| 1552 | 1565 | ); |
| 1553 | 1566 | try std.testing.expectFmt( |
| 1554 | 1567 | \\1:4: error: duplicate struct field name |
| 1555 | 1568 | \\1:12: note: duplicate name here |
| 1556 | 1569 | \\ |
| 1557 | | , "{}", .{status}); |
| 1570 | , "{}", .{diag}); |
| 1558 | 1571 | } |
| 1559 | 1572 | |
| 1560 | 1573 | // Ignore unknown fields |
| ... | ... | @@ -1569,29 +1582,29 @@ test "std.zon structs" { |
| 1569 | 1582 | // Unknown field when struct has no fields (regression test) |
| 1570 | 1583 | { |
| 1571 | 1584 | const Vec2 = struct {}; |
| 1572 | | var status: Status = .{}; |
| 1573 | | defer status.deinit(gpa); |
| 1585 | var diag: Diagnostics = .{}; |
| 1586 | defer diag.deinit(gpa); |
| 1574 | 1587 | try std.testing.expectError( |
| 1575 | 1588 | error.ParseZon, |
| 1576 | | fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}), |
| 1589 | fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}), |
| 1577 | 1590 | ); |
| 1578 | 1591 | try std.testing.expectFmt( |
| 1579 | 1592 | \\1:4: error: unexpected field 'x' |
| 1580 | 1593 | \\1:4: note: none expected |
| 1581 | 1594 | \\ |
| 1582 | | , "{}", .{status}); |
| 1595 | , "{}", .{diag}); |
| 1583 | 1596 | } |
| 1584 | 1597 | |
| 1585 | 1598 | // Missing field |
| 1586 | 1599 | { |
| 1587 | 1600 | const Vec2 = struct { x: f32, y: f32 }; |
| 1588 | | var status: Status = .{}; |
| 1589 | | defer status.deinit(gpa); |
| 1601 | var diag: Diagnostics = .{}; |
| 1602 | defer diag.deinit(gpa); |
| 1590 | 1603 | try std.testing.expectError( |
| 1591 | 1604 | error.ParseZon, |
| 1592 | | fromSlice(Vec2, gpa, ".{.x=1.5}", &status, .{}), |
| 1605 | fromSlice(Vec2, gpa, ".{.x=1.5}", &diag, .{}), |
| 1593 | 1606 | ); |
| 1594 | | try std.testing.expectFmt("1:2: error: missing required field y\n", "{}", .{status}); |
| 1607 | try std.testing.expectFmt("1:2: error: missing required field y\n", "{}", .{diag}); |
| 1595 | 1608 | } |
| 1596 | 1609 | |
| 1597 | 1610 | // Default field |
| ... | ... | @@ -1611,14 +1624,14 @@ test "std.zon structs" { |
| 1611 | 1624 | // Comptime field assignment |
| 1612 | 1625 | { |
| 1613 | 1626 | const Vec2 = struct { x: f32, comptime y: f32 = 1.5 }; |
| 1614 | | var status: Status = .{}; |
| 1615 | | defer status.deinit(gpa); |
| 1616 | | const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &status, .{}); |
| 1627 | var diag: Diagnostics = .{}; |
| 1628 | defer diag.deinit(gpa); |
| 1629 | const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &diag, .{}); |
| 1617 | 1630 | try std.testing.expectError(error.ParseZon, parsed); |
| 1618 | 1631 | try std.testing.expectFmt( |
| 1619 | 1632 | \\1:18: error: cannot initialize comptime field |
| 1620 | 1633 | \\ |
| 1621 | | , "{}", .{status}); |
| 1634 | , "{}", .{diag}); |
| 1622 | 1635 | } |
| 1623 | 1636 | |
| 1624 | 1637 | // Enum field (regression test, we were previously getting the field name in an |
| ... | ... | @@ -1640,52 +1653,52 @@ test "std.zon structs" { |
| 1640 | 1653 | { |
| 1641 | 1654 | // Structs |
| 1642 | 1655 | { |
| 1643 | | var status: Status = .{}; |
| 1644 | | defer status.deinit(gpa); |
| 1645 | | const parsed = fromSlice(struct {}, gpa, "Empty{}", &status, .{}); |
| 1656 | var diag: Diagnostics = .{}; |
| 1657 | defer diag.deinit(gpa); |
| 1658 | const parsed = fromSlice(struct {}, gpa, "Empty{}", &diag, .{}); |
| 1646 | 1659 | try std.testing.expectError(error.ParseZon, parsed); |
| 1647 | 1660 | try std.testing.expectFmt( |
| 1648 | 1661 | \\1:1: error: types are not available in ZON |
| 1649 | 1662 | \\1:1: note: replace the type with '.' |
| 1650 | 1663 | \\ |
| 1651 | | , "{}", .{status}); |
| 1664 | , "{}", .{diag}); |
| 1652 | 1665 | } |
| 1653 | 1666 | |
| 1654 | 1667 | // Arrays |
| 1655 | 1668 | { |
| 1656 | | var status: Status = .{}; |
| 1657 | | defer status.deinit(gpa); |
| 1658 | | const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &status, .{}); |
| 1669 | var diag: Diagnostics = .{}; |
| 1670 | defer diag.deinit(gpa); |
| 1671 | const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &diag, .{}); |
| 1659 | 1672 | try std.testing.expectError(error.ParseZon, parsed); |
| 1660 | 1673 | try std.testing.expectFmt( |
| 1661 | 1674 | \\1:1: error: types are not available in ZON |
| 1662 | 1675 | \\1:1: note: replace the type with '.' |
| 1663 | 1676 | \\ |
| 1664 | | , "{}", .{status}); |
| 1677 | , "{}", .{diag}); |
| 1665 | 1678 | } |
| 1666 | 1679 | |
| 1667 | 1680 | // Slices |
| 1668 | 1681 | { |
| 1669 | | var status: Status = .{}; |
| 1670 | | defer status.deinit(gpa); |
| 1671 | | const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &status, .{}); |
| 1682 | var diag: Diagnostics = .{}; |
| 1683 | defer diag.deinit(gpa); |
| 1684 | const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &diag, .{}); |
| 1672 | 1685 | try std.testing.expectError(error.ParseZon, parsed); |
| 1673 | 1686 | try std.testing.expectFmt( |
| 1674 | 1687 | \\1:1: error: types are not available in ZON |
| 1675 | 1688 | \\1:1: note: replace the type with '.' |
| 1676 | 1689 | \\ |
| 1677 | | , "{}", .{status}); |
| 1690 | , "{}", .{diag}); |
| 1678 | 1691 | } |
| 1679 | 1692 | |
| 1680 | 1693 | // Tuples |
| 1681 | 1694 | { |
| 1682 | | var status: Status = .{}; |
| 1683 | | defer status.deinit(gpa); |
| 1695 | var diag: Diagnostics = .{}; |
| 1696 | defer diag.deinit(gpa); |
| 1684 | 1697 | const parsed = fromSlice( |
| 1685 | 1698 | struct { u8, u8, u8 }, |
| 1686 | 1699 | gpa, |
| 1687 | 1700 | "Tuple{1, 2, 3}", |
| 1688 | | &status, |
| 1701 | &diag, |
| 1689 | 1702 | .{}, |
| 1690 | 1703 | ); |
| 1691 | 1704 | try std.testing.expectError(error.ParseZon, parsed); |
| ... | ... | @@ -1693,20 +1706,20 @@ test "std.zon structs" { |
| 1693 | 1706 | \\1:1: error: types are not available in ZON |
| 1694 | 1707 | \\1:1: note: replace the type with '.' |
| 1695 | 1708 | \\ |
| 1696 | | , "{}", .{status}); |
| 1709 | , "{}", .{diag}); |
| 1697 | 1710 | } |
| 1698 | 1711 | |
| 1699 | 1712 | // Nested |
| 1700 | 1713 | { |
| 1701 | | var status: Status = .{}; |
| 1702 | | defer status.deinit(gpa); |
| 1703 | | const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &status, .{}); |
| 1714 | var diag: Diagnostics = .{}; |
| 1715 | defer diag.deinit(gpa); |
| 1716 | const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &diag, .{}); |
| 1704 | 1717 | try std.testing.expectError(error.ParseZon, parsed); |
| 1705 | 1718 | try std.testing.expectFmt( |
| 1706 | 1719 | \\1:9: error: types are not available in ZON |
| 1707 | 1720 | \\1:9: note: replace the type with '.' |
| 1708 | 1721 | \\ |
| 1709 | | , "{}", .{status}); |
| 1722 | , "{}", .{diag}); |
| 1710 | 1723 | } |
| 1711 | 1724 | } |
| 1712 | 1725 | } |
| ... | ... | @@ -1745,53 +1758,53 @@ test "std.zon tuples" { |
| 1745 | 1758 | // Extra field |
| 1746 | 1759 | { |
| 1747 | 1760 | const Tuple = struct { f32, bool }; |
| 1748 | | var status: Status = .{}; |
| 1749 | | defer status.deinit(gpa); |
| 1761 | var diag: Diagnostics = .{}; |
| 1762 | defer diag.deinit(gpa); |
| 1750 | 1763 | try std.testing.expectError( |
| 1751 | 1764 | error.ParseZon, |
| 1752 | | fromSlice(Tuple, gpa, ".{0.5, true, 123}", &status, .{}), |
| 1765 | fromSlice(Tuple, gpa, ".{0.5, true, 123}", &diag, .{}), |
| 1753 | 1766 | ); |
| 1754 | | try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{}", .{status}); |
| 1767 | try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{}", .{diag}); |
| 1755 | 1768 | } |
| 1756 | 1769 | |
| 1757 | 1770 | // Extra field |
| 1758 | 1771 | { |
| 1759 | 1772 | const Tuple = struct { f32, bool }; |
| 1760 | | var status: Status = .{}; |
| 1761 | | defer status.deinit(gpa); |
| 1773 | var diag: Diagnostics = .{}; |
| 1774 | defer diag.deinit(gpa); |
| 1762 | 1775 | try std.testing.expectError( |
| 1763 | 1776 | error.ParseZon, |
| 1764 | | fromSlice(Tuple, gpa, ".{0.5}", &status, .{}), |
| 1777 | fromSlice(Tuple, gpa, ".{0.5}", &diag, .{}), |
| 1765 | 1778 | ); |
| 1766 | 1779 | try std.testing.expectFmt( |
| 1767 | 1780 | "1:2: error: missing tuple field with index 1\n", |
| 1768 | 1781 | "{}", |
| 1769 | | .{status}, |
| 1782 | .{diag}, |
| 1770 | 1783 | ); |
| 1771 | 1784 | } |
| 1772 | 1785 | |
| 1773 | 1786 | // Tuple with unexpected field names |
| 1774 | 1787 | { |
| 1775 | 1788 | const Tuple = struct { f32 }; |
| 1776 | | var status: Status = .{}; |
| 1777 | | defer status.deinit(gpa); |
| 1789 | var diag: Diagnostics = .{}; |
| 1790 | defer diag.deinit(gpa); |
| 1778 | 1791 | try std.testing.expectError( |
| 1779 | 1792 | error.ParseZon, |
| 1780 | | fromSlice(Tuple, gpa, ".{.foo = 10.0}", &status, .{}), |
| 1793 | fromSlice(Tuple, gpa, ".{.foo = 10.0}", &diag, .{}), |
| 1781 | 1794 | ); |
| 1782 | | try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{status}); |
| 1795 | try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{diag}); |
| 1783 | 1796 | } |
| 1784 | 1797 | |
| 1785 | 1798 | // Struct with missing field names |
| 1786 | 1799 | { |
| 1787 | 1800 | const Struct = struct { foo: f32 }; |
| 1788 | | var status: Status = .{}; |
| 1789 | | defer status.deinit(gpa); |
| 1801 | var diag: Diagnostics = .{}; |
| 1802 | defer diag.deinit(gpa); |
| 1790 | 1803 | try std.testing.expectError( |
| 1791 | 1804 | error.ParseZon, |
| 1792 | | fromSlice(Struct, gpa, ".{10.0}", &status, .{}), |
| 1805 | fromSlice(Struct, gpa, ".{10.0}", &diag, .{}), |
| 1793 | 1806 | ); |
| 1794 | | try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{status}); |
| 1807 | try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{diag}); |
| 1795 | 1808 | } |
| 1796 | 1809 | |
| 1797 | 1810 | // Comptime field |
| ... | ... | @@ -1804,14 +1817,14 @@ test "std.zon tuples" { |
| 1804 | 1817 | // Comptime field assignment |
| 1805 | 1818 | { |
| 1806 | 1819 | const Vec2 = struct { f32, comptime f32 = 1.5 }; |
| 1807 | | var status: Status = .{}; |
| 1808 | | defer status.deinit(gpa); |
| 1809 | | const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &status, .{}); |
| 1820 | var diag: Diagnostics = .{}; |
| 1821 | defer diag.deinit(gpa); |
| 1822 | const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &diag, .{}); |
| 1810 | 1823 | try std.testing.expectError(error.ParseZon, parsed); |
| 1811 | 1824 | try std.testing.expectFmt( |
| 1812 | 1825 | \\1:9: error: cannot initialize comptime field |
| 1813 | 1826 | \\ |
| 1814 | | , "{}", .{status}); |
| 1827 | , "{}", .{diag}); |
| 1815 | 1828 | } |
| 1816 | 1829 | } |
| 1817 | 1830 | |
| ... | ... | @@ -1915,61 +1928,61 @@ test "std.zon arrays and slices" { |
| 1915 | 1928 | |
| 1916 | 1929 | // Expect 0 find 3 |
| 1917 | 1930 | { |
| 1918 | | var status: Status = .{}; |
| 1919 | | defer status.deinit(gpa); |
| 1931 | var diag: Diagnostics = .{}; |
| 1932 | defer diag.deinit(gpa); |
| 1920 | 1933 | try std.testing.expectError( |
| 1921 | 1934 | error.ParseZon, |
| 1922 | | fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &status, .{}), |
| 1935 | fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &diag, .{}), |
| 1923 | 1936 | ); |
| 1924 | 1937 | try std.testing.expectFmt( |
| 1925 | 1938 | "1:3: error: index 0 outside of array of length 0\n", |
| 1926 | 1939 | "{}", |
| 1927 | | .{status}, |
| 1940 | .{diag}, |
| 1928 | 1941 | ); |
| 1929 | 1942 | } |
| 1930 | 1943 | |
| 1931 | 1944 | // Expect 1 find 2 |
| 1932 | 1945 | { |
| 1933 | | var status: Status = .{}; |
| 1934 | | defer status.deinit(gpa); |
| 1946 | var diag: Diagnostics = .{}; |
| 1947 | defer diag.deinit(gpa); |
| 1935 | 1948 | try std.testing.expectError( |
| 1936 | 1949 | error.ParseZon, |
| 1937 | | fromSlice([1]u8, gpa, ".{'a', 'b'}", &status, .{}), |
| 1950 | fromSlice([1]u8, gpa, ".{'a', 'b'}", &diag, .{}), |
| 1938 | 1951 | ); |
| 1939 | 1952 | try std.testing.expectFmt( |
| 1940 | 1953 | "1:8: error: index 1 outside of array of length 1\n", |
| 1941 | 1954 | "{}", |
| 1942 | | .{status}, |
| 1955 | .{diag}, |
| 1943 | 1956 | ); |
| 1944 | 1957 | } |
| 1945 | 1958 | |
| 1946 | 1959 | // Expect 2 find 1 |
| 1947 | 1960 | { |
| 1948 | | var status: Status = .{}; |
| 1949 | | defer status.deinit(gpa); |
| 1961 | var diag: Diagnostics = .{}; |
| 1962 | defer diag.deinit(gpa); |
| 1950 | 1963 | try std.testing.expectError( |
| 1951 | 1964 | error.ParseZon, |
| 1952 | | fromSlice([2]u8, gpa, ".{'a'}", &status, .{}), |
| 1965 | fromSlice([2]u8, gpa, ".{'a'}", &diag, .{}), |
| 1953 | 1966 | ); |
| 1954 | 1967 | try std.testing.expectFmt( |
| 1955 | 1968 | "1:2: error: expected 2 array elements; found 1\n", |
| 1956 | 1969 | "{}", |
| 1957 | | .{status}, |
| 1970 | .{diag}, |
| 1958 | 1971 | ); |
| 1959 | 1972 | } |
| 1960 | 1973 | |
| 1961 | 1974 | // Expect 3 find 0 |
| 1962 | 1975 | { |
| 1963 | | var status: Status = .{}; |
| 1964 | | defer status.deinit(gpa); |
| 1976 | var diag: Diagnostics = .{}; |
| 1977 | defer diag.deinit(gpa); |
| 1965 | 1978 | try std.testing.expectError( |
| 1966 | 1979 | error.ParseZon, |
| 1967 | | fromSlice([3]u8, gpa, ".{}", &status, .{}), |
| 1980 | fromSlice([3]u8, gpa, ".{}", &diag, .{}), |
| 1968 | 1981 | ); |
| 1969 | 1982 | try std.testing.expectFmt( |
| 1970 | 1983 | "1:2: error: expected 3 array elements; found 0\n", |
| 1971 | 1984 | "{}", |
| 1972 | | .{status}, |
| 1985 | .{diag}, |
| 1973 | 1986 | ); |
| 1974 | 1987 | } |
| 1975 | 1988 | |
| ... | ... | @@ -1977,24 +1990,24 @@ test "std.zon arrays and slices" { |
| 1977 | 1990 | { |
| 1978 | 1991 | // Array |
| 1979 | 1992 | { |
| 1980 | | var status: Status = .{}; |
| 1981 | | defer status.deinit(gpa); |
| 1993 | var diag: Diagnostics = .{}; |
| 1994 | defer diag.deinit(gpa); |
| 1982 | 1995 | try std.testing.expectError( |
| 1983 | 1996 | error.ParseZon, |
| 1984 | | fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}), |
| 1997 | fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}), |
| 1985 | 1998 | ); |
| 1986 | | try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{status}); |
| 1999 | try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{diag}); |
| 1987 | 2000 | } |
| 1988 | 2001 | |
| 1989 | 2002 | // Slice |
| 1990 | 2003 | { |
| 1991 | | var status: Status = .{}; |
| 1992 | | defer status.deinit(gpa); |
| 2004 | var diag: Diagnostics = .{}; |
| 2005 | defer diag.deinit(gpa); |
| 1993 | 2006 | try std.testing.expectError( |
| 1994 | 2007 | error.ParseZon, |
| 1995 | | fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}), |
| 2008 | fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}), |
| 1996 | 2009 | ); |
| 1997 | | try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{status}); |
| 2010 | try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{diag}); |
| 1998 | 2011 | } |
| 1999 | 2012 | } |
| 2000 | 2013 | |
| ... | ... | @@ -2002,39 +2015,39 @@ test "std.zon arrays and slices" { |
| 2002 | 2015 | { |
| 2003 | 2016 | // Array |
| 2004 | 2017 | { |
| 2005 | | var status: Status = .{}; |
| 2006 | | defer status.deinit(gpa); |
| 2018 | var diag: Diagnostics = .{}; |
| 2019 | defer diag.deinit(gpa); |
| 2007 | 2020 | try std.testing.expectError( |
| 2008 | 2021 | error.ParseZon, |
| 2009 | | fromSlice([3]u8, gpa, "'a'", &status, .{}), |
| 2022 | fromSlice([3]u8, gpa, "'a'", &diag, .{}), |
| 2010 | 2023 | ); |
| 2011 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2024 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2012 | 2025 | } |
| 2013 | 2026 | |
| 2014 | 2027 | // Slice |
| 2015 | 2028 | { |
| 2016 | | var status: Status = .{}; |
| 2017 | | defer status.deinit(gpa); |
| 2029 | var diag: Diagnostics = .{}; |
| 2030 | defer diag.deinit(gpa); |
| 2018 | 2031 | try std.testing.expectError( |
| 2019 | 2032 | error.ParseZon, |
| 2020 | | fromSlice([]u8, gpa, "'a'", &status, .{}), |
| 2033 | fromSlice([]u8, gpa, "'a'", &diag, .{}), |
| 2021 | 2034 | ); |
| 2022 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2035 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2023 | 2036 | } |
| 2024 | 2037 | } |
| 2025 | 2038 | |
| 2026 | 2039 | // Address of is not allowed (indirection for slices in ZON is implicit) |
| 2027 | 2040 | { |
| 2028 | | var status: Status = .{}; |
| 2029 | | defer status.deinit(gpa); |
| 2041 | var diag: Diagnostics = .{}; |
| 2042 | defer diag.deinit(gpa); |
| 2030 | 2043 | try std.testing.expectError( |
| 2031 | 2044 | error.ParseZon, |
| 2032 | | fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &status, .{}), |
| 2045 | fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &diag, .{}), |
| 2033 | 2046 | ); |
| 2034 | 2047 | try std.testing.expectFmt( |
| 2035 | 2048 | "1:3: error: pointers are not available in ZON\n", |
| 2036 | 2049 | "{}", |
| 2037 | | .{status}, |
| 2050 | .{diag}, |
| 2038 | 2051 | ); |
| 2039 | 2052 | } |
| 2040 | 2053 | } |
| ... | ... | @@ -2066,23 +2079,23 @@ test "std.zon string literal" { |
| 2066 | 2079 | // Passing string literal to a mutable slice |
| 2067 | 2080 | { |
| 2068 | 2081 | { |
| 2069 | | var status: Status = .{}; |
| 2070 | | defer status.deinit(gpa); |
| 2082 | var diag: Diagnostics = .{}; |
| 2083 | defer diag.deinit(gpa); |
| 2071 | 2084 | try std.testing.expectError( |
| 2072 | 2085 | error.ParseZon, |
| 2073 | | fromSlice([]u8, gpa, "\"abcd\"", &status, .{}), |
| 2086 | fromSlice([]u8, gpa, "\"abcd\"", &diag, .{}), |
| 2074 | 2087 | ); |
| 2075 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2088 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2076 | 2089 | } |
| 2077 | 2090 | |
| 2078 | 2091 | { |
| 2079 | | var status: Status = .{}; |
| 2080 | | defer status.deinit(gpa); |
| 2092 | var diag: Diagnostics = .{}; |
| 2093 | defer diag.deinit(gpa); |
| 2081 | 2094 | try std.testing.expectError( |
| 2082 | 2095 | error.ParseZon, |
| 2083 | | fromSlice([]u8, gpa, "\\\\abcd", &status, .{}), |
| 2096 | fromSlice([]u8, gpa, "\\\\abcd", &diag, .{}), |
| 2084 | 2097 | ); |
| 2085 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2098 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2086 | 2099 | } |
| 2087 | 2100 | } |
| 2088 | 2101 | |
| ... | ... | @@ -2093,23 +2106,23 @@ test "std.zon string literal" { |
| 2093 | 2106 | defer ast.deinit(gpa); |
| 2094 | 2107 | var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false }); |
| 2095 | 2108 | defer zoir.deinit(gpa); |
| 2096 | | var status: Status = .{}; |
| 2097 | | defer status.deinit(gpa); |
| 2109 | var diag: Diagnostics = .{}; |
| 2110 | defer diag.deinit(gpa); |
| 2098 | 2111 | try std.testing.expectError( |
| 2099 | 2112 | error.ParseZon, |
| 2100 | | fromSlice([4:0]u8, gpa, "\"abcd\"", &status, .{}), |
| 2113 | fromSlice([4:0]u8, gpa, "\"abcd\"", &diag, .{}), |
| 2101 | 2114 | ); |
| 2102 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2115 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2103 | 2116 | } |
| 2104 | 2117 | |
| 2105 | 2118 | { |
| 2106 | | var status: Status = .{}; |
| 2107 | | defer status.deinit(gpa); |
| 2119 | var diag: Diagnostics = .{}; |
| 2120 | defer diag.deinit(gpa); |
| 2108 | 2121 | try std.testing.expectError( |
| 2109 | 2122 | error.ParseZon, |
| 2110 | | fromSlice([4:0]u8, gpa, "\\\\abcd", &status, .{}), |
| 2123 | fromSlice([4:0]u8, gpa, "\\\\abcd", &diag, .{}), |
| 2111 | 2124 | ); |
| 2112 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2125 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2113 | 2126 | } |
| 2114 | 2127 | } |
| 2115 | 2128 | |
| ... | ... | @@ -2145,102 +2158,102 @@ test "std.zon string literal" { |
| 2145 | 2158 | // Other value terminated slices |
| 2146 | 2159 | { |
| 2147 | 2160 | { |
| 2148 | | var status: Status = .{}; |
| 2149 | | defer status.deinit(gpa); |
| 2161 | var diag: Diagnostics = .{}; |
| 2162 | defer diag.deinit(gpa); |
| 2150 | 2163 | try std.testing.expectError( |
| 2151 | 2164 | error.ParseZon, |
| 2152 | | fromSlice([:1]const u8, gpa, "\"foo\"", &status, .{}), |
| 2165 | fromSlice([:1]const u8, gpa, "\"foo\"", &diag, .{}), |
| 2153 | 2166 | ); |
| 2154 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2167 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2155 | 2168 | } |
| 2156 | 2169 | |
| 2157 | 2170 | { |
| 2158 | | var status: Status = .{}; |
| 2159 | | defer status.deinit(gpa); |
| 2171 | var diag: Diagnostics = .{}; |
| 2172 | defer diag.deinit(gpa); |
| 2160 | 2173 | try std.testing.expectError( |
| 2161 | 2174 | error.ParseZon, |
| 2162 | | fromSlice([:1]const u8, gpa, "\\\\foo", &status, .{}), |
| 2175 | fromSlice([:1]const u8, gpa, "\\\\foo", &diag, .{}), |
| 2163 | 2176 | ); |
| 2164 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2177 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2165 | 2178 | } |
| 2166 | 2179 | } |
| 2167 | 2180 | |
| 2168 | 2181 | // Expecting string literal, getting something else |
| 2169 | 2182 | { |
| 2170 | | var status: Status = .{}; |
| 2171 | | defer status.deinit(gpa); |
| 2183 | var diag: Diagnostics = .{}; |
| 2184 | defer diag.deinit(gpa); |
| 2172 | 2185 | try std.testing.expectError( |
| 2173 | 2186 | error.ParseZon, |
| 2174 | | fromSlice([]const u8, gpa, "true", &status, .{}), |
| 2187 | fromSlice([]const u8, gpa, "true", &diag, .{}), |
| 2175 | 2188 | ); |
| 2176 | | try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{status}); |
| 2189 | try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{diag}); |
| 2177 | 2190 | } |
| 2178 | 2191 | |
| 2179 | 2192 | // Expecting string literal, getting an incompatible tuple |
| 2180 | 2193 | { |
| 2181 | | var status: Status = .{}; |
| 2182 | | defer status.deinit(gpa); |
| 2194 | var diag: Diagnostics = .{}; |
| 2195 | defer diag.deinit(gpa); |
| 2183 | 2196 | try std.testing.expectError( |
| 2184 | 2197 | error.ParseZon, |
| 2185 | | fromSlice([]const u8, gpa, ".{false}", &status, .{}), |
| 2198 | fromSlice([]const u8, gpa, ".{false}", &diag, .{}), |
| 2186 | 2199 | ); |
| 2187 | | try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{}", .{status}); |
| 2200 | try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{}", .{diag}); |
| 2188 | 2201 | } |
| 2189 | 2202 | |
| 2190 | 2203 | // Invalid string literal |
| 2191 | 2204 | { |
| 2192 | | var status: Status = .{}; |
| 2193 | | defer status.deinit(gpa); |
| 2205 | var diag: Diagnostics = .{}; |
| 2206 | defer diag.deinit(gpa); |
| 2194 | 2207 | try std.testing.expectError( |
| 2195 | 2208 | error.ParseZon, |
| 2196 | | fromSlice([]const i8, gpa, "\"\\a\"", &status, .{}), |
| 2209 | fromSlice([]const i8, gpa, "\"\\a\"", &diag, .{}), |
| 2197 | 2210 | ); |
| 2198 | | try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{}", .{status}); |
| 2211 | try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{}", .{diag}); |
| 2199 | 2212 | } |
| 2200 | 2213 | |
| 2201 | 2214 | // Slice wrong child type |
| 2202 | 2215 | { |
| 2203 | 2216 | { |
| 2204 | | var status: Status = .{}; |
| 2205 | | defer status.deinit(gpa); |
| 2217 | var diag: Diagnostics = .{}; |
| 2218 | defer diag.deinit(gpa); |
| 2206 | 2219 | try std.testing.expectError( |
| 2207 | 2220 | error.ParseZon, |
| 2208 | | fromSlice([]const i8, gpa, "\"a\"", &status, .{}), |
| 2221 | fromSlice([]const i8, gpa, "\"a\"", &diag, .{}), |
| 2209 | 2222 | ); |
| 2210 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2223 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2211 | 2224 | } |
| 2212 | 2225 | |
| 2213 | 2226 | { |
| 2214 | | var status: Status = .{}; |
| 2215 | | defer status.deinit(gpa); |
| 2227 | var diag: Diagnostics = .{}; |
| 2228 | defer diag.deinit(gpa); |
| 2216 | 2229 | try std.testing.expectError( |
| 2217 | 2230 | error.ParseZon, |
| 2218 | | fromSlice([]const i8, gpa, "\\\\a", &status, .{}), |
| 2231 | fromSlice([]const i8, gpa, "\\\\a", &diag, .{}), |
| 2219 | 2232 | ); |
| 2220 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2233 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2221 | 2234 | } |
| 2222 | 2235 | } |
| 2223 | 2236 | |
| 2224 | 2237 | // Bad alignment |
| 2225 | 2238 | { |
| 2226 | 2239 | { |
| 2227 | | var status: Status = .{}; |
| 2228 | | defer status.deinit(gpa); |
| 2240 | var diag: Diagnostics = .{}; |
| 2241 | defer diag.deinit(gpa); |
| 2229 | 2242 | try std.testing.expectError( |
| 2230 | 2243 | error.ParseZon, |
| 2231 | | fromSlice([]align(2) const u8, gpa, "\"abc\"", &status, .{}), |
| 2244 | fromSlice([]align(2) const u8, gpa, "\"abc\"", &diag, .{}), |
| 2232 | 2245 | ); |
| 2233 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2246 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2234 | 2247 | } |
| 2235 | 2248 | |
| 2236 | 2249 | { |
| 2237 | | var status: Status = .{}; |
| 2238 | | defer status.deinit(gpa); |
| 2250 | var diag: Diagnostics = .{}; |
| 2251 | defer diag.deinit(gpa); |
| 2239 | 2252 | try std.testing.expectError( |
| 2240 | 2253 | error.ParseZon, |
| 2241 | | fromSlice([]align(2) const u8, gpa, "\\\\abc", &status, .{}), |
| 2254 | fromSlice([]align(2) const u8, gpa, "\\\\abc", &diag, .{}), |
| 2242 | 2255 | ); |
| 2243 | | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status}); |
| 2256 | try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag}); |
| 2244 | 2257 | } |
| 2245 | 2258 | } |
| 2246 | 2259 | |
| ... | ... | @@ -2303,11 +2316,11 @@ test "std.zon enum literals" { |
| 2303 | 2316 | |
| 2304 | 2317 | // Bad tag |
| 2305 | 2318 | { |
| 2306 | | var status: Status = .{}; |
| 2307 | | defer status.deinit(gpa); |
| 2319 | var diag: Diagnostics = .{}; |
| 2320 | defer diag.deinit(gpa); |
| 2308 | 2321 | try std.testing.expectError( |
| 2309 | 2322 | error.ParseZon, |
| 2310 | | fromSlice(Enum, gpa, ".qux", &status, .{}), |
| 2323 | fromSlice(Enum, gpa, ".qux", &diag, .{}), |
| 2311 | 2324 | ); |
| 2312 | 2325 | try std.testing.expectFmt( |
| 2313 | 2326 | \\1:2: error: unexpected enum literal 'qux' |
| ... | ... | @@ -2315,17 +2328,17 @@ test "std.zon enum literals" { |
| 2315 | 2328 | \\ |
| 2316 | 2329 | , |
| 2317 | 2330 | "{}", |
| 2318 | | .{status}, |
| 2331 | .{diag}, |
| 2319 | 2332 | ); |
| 2320 | 2333 | } |
| 2321 | 2334 | |
| 2322 | 2335 | // Bad tag that's too long for parser |
| 2323 | 2336 | { |
| 2324 | | var status: Status = .{}; |
| 2325 | | defer status.deinit(gpa); |
| 2337 | var diag: Diagnostics = .{}; |
| 2338 | defer diag.deinit(gpa); |
| 2326 | 2339 | try std.testing.expectError( |
| 2327 | 2340 | error.ParseZon, |
| 2328 | | fromSlice(Enum, gpa, ".@\"foobarbaz\"", &status, .{}), |
| 2341 | fromSlice(Enum, gpa, ".@\"foobarbaz\"", &diag, .{}), |
| 2329 | 2342 | ); |
| 2330 | 2343 | try std.testing.expectFmt( |
| 2331 | 2344 | \\1:2: error: unexpected enum literal 'foobarbaz' |
| ... | ... | @@ -2333,33 +2346,33 @@ test "std.zon enum literals" { |
| 2333 | 2346 | \\ |
| 2334 | 2347 | , |
| 2335 | 2348 | "{}", |
| 2336 | | .{status}, |
| 2349 | .{diag}, |
| 2337 | 2350 | ); |
| 2338 | 2351 | } |
| 2339 | 2352 | |
| 2340 | 2353 | // Bad type |
| 2341 | 2354 | { |
| 2342 | | var status: Status = .{}; |
| 2343 | | defer status.deinit(gpa); |
| 2355 | var diag: Diagnostics = .{}; |
| 2356 | defer diag.deinit(gpa); |
| 2344 | 2357 | try std.testing.expectError( |
| 2345 | 2358 | error.ParseZon, |
| 2346 | | fromSlice(Enum, gpa, "true", &status, .{}), |
| 2359 | fromSlice(Enum, gpa, "true", &diag, .{}), |
| 2347 | 2360 | ); |
| 2348 | | try std.testing.expectFmt("1:1: error: expected enum literal\n", "{}", .{status}); |
| 2361 | try std.testing.expectFmt("1:1: error: expected enum literal\n", "{}", .{diag}); |
| 2349 | 2362 | } |
| 2350 | 2363 | |
| 2351 | 2364 | // Test embedded nulls in an identifier |
| 2352 | 2365 | { |
| 2353 | | var status: Status = .{}; |
| 2354 | | defer status.deinit(gpa); |
| 2366 | var diag: Diagnostics = .{}; |
| 2367 | defer diag.deinit(gpa); |
| 2355 | 2368 | try std.testing.expectError( |
| 2356 | 2369 | error.ParseZon, |
| 2357 | | fromSlice(Enum, gpa, ".@\"\\x00\"", &status, .{}), |
| 2370 | fromSlice(Enum, gpa, ".@\"\\x00\"", &diag, .{}), |
| 2358 | 2371 | ); |
| 2359 | 2372 | try std.testing.expectFmt( |
| 2360 | 2373 | "1:2: error: identifier cannot contain null bytes\n", |
| 2361 | 2374 | "{}", |
| 2362 | | .{status}, |
| 2375 | .{diag}, |
| 2363 | 2376 | ); |
| 2364 | 2377 | } |
| 2365 | 2378 | } |
| ... | ... | @@ -2373,24 +2386,24 @@ test "std.zon parse bool" { |
| 2373 | 2386 | |
| 2374 | 2387 | // Errors |
| 2375 | 2388 | { |
| 2376 | | var status: Status = .{}; |
| 2377 | | defer status.deinit(gpa); |
| 2389 | var diag: Diagnostics = .{}; |
| 2390 | defer diag.deinit(gpa); |
| 2378 | 2391 | try std.testing.expectError( |
| 2379 | 2392 | error.ParseZon, |
| 2380 | | fromSlice(bool, gpa, " foo", &status, .{}), |
| 2393 | fromSlice(bool, gpa, " foo", &diag, .{}), |
| 2381 | 2394 | ); |
| 2382 | 2395 | try std.testing.expectFmt( |
| 2383 | 2396 | \\1:2: error: invalid expression |
| 2384 | 2397 | \\1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan' |
| 2385 | 2398 | \\1:2: note: precede identifier with '.' for an enum literal |
| 2386 | 2399 | \\ |
| 2387 | | , "{}", .{status}); |
| 2400 | , "{}", .{diag}); |
| 2388 | 2401 | } |
| 2389 | 2402 | { |
| 2390 | | var status: Status = .{}; |
| 2391 | | defer status.deinit(gpa); |
| 2392 | | try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &status, .{})); |
| 2393 | | try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{status}); |
| 2403 | var diag: Diagnostics = .{}; |
| 2404 | defer diag.deinit(gpa); |
| 2405 | try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &diag, .{})); |
| 2406 | try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{diag}); |
| 2394 | 2407 | } |
| 2395 | 2408 | } |
| 2396 | 2409 | |
| ... | ... | @@ -2452,35 +2465,35 @@ test "std.zon parse int" { |
| 2452 | 2465 | try fromSlice(i66, gpa, "-36893488147419103232", null, .{}), |
| 2453 | 2466 | ); |
| 2454 | 2467 | { |
| 2455 | | var status: Status = .{}; |
| 2456 | | defer status.deinit(gpa); |
| 2468 | var diag: Diagnostics = .{}; |
| 2469 | defer diag.deinit(gpa); |
| 2457 | 2470 | try std.testing.expectError(error.ParseZon, fromSlice( |
| 2458 | 2471 | i66, |
| 2459 | 2472 | gpa, |
| 2460 | 2473 | "36893488147419103232", |
| 2461 | | &status, |
| 2474 | &diag, |
| 2462 | 2475 | .{}, |
| 2463 | 2476 | )); |
| 2464 | 2477 | try std.testing.expectFmt( |
| 2465 | 2478 | "1:1: error: type 'i66' cannot represent value\n", |
| 2466 | 2479 | "{}", |
| 2467 | | .{status}, |
| 2480 | .{diag}, |
| 2468 | 2481 | ); |
| 2469 | 2482 | } |
| 2470 | 2483 | { |
| 2471 | | var status: Status = .{}; |
| 2472 | | defer status.deinit(gpa); |
| 2484 | var diag: Diagnostics = .{}; |
| 2485 | defer diag.deinit(gpa); |
| 2473 | 2486 | try std.testing.expectError(error.ParseZon, fromSlice( |
| 2474 | 2487 | i66, |
| 2475 | 2488 | gpa, |
| 2476 | 2489 | "-36893488147419103233", |
| 2477 | | &status, |
| 2490 | &diag, |
| 2478 | 2491 | .{}, |
| 2479 | 2492 | )); |
| 2480 | 2493 | try std.testing.expectFmt( |
| 2481 | 2494 | "1:1: error: type 'i66' cannot represent value\n", |
| 2482 | 2495 | "{}", |
| 2483 | | .{status}, |
| 2496 | .{diag}, |
| 2484 | 2497 | ); |
| 2485 | 2498 | } |
| 2486 | 2499 | |
| ... | ... | @@ -2563,108 +2576,108 @@ test "std.zon parse int" { |
| 2563 | 2576 | |
| 2564 | 2577 | // Number with invalid character in the middle |
| 2565 | 2578 | { |
| 2566 | | var status: Status = .{}; |
| 2567 | | defer status.deinit(gpa); |
| 2568 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &status, .{})); |
| 2579 | var diag: Diagnostics = .{}; |
| 2580 | defer diag.deinit(gpa); |
| 2581 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &diag, .{})); |
| 2569 | 2582 | try std.testing.expectFmt( |
| 2570 | 2583 | "1:3: error: invalid digit 'a' for decimal base\n", |
| 2571 | 2584 | "{}", |
| 2572 | | .{status}, |
| 2585 | .{diag}, |
| 2573 | 2586 | ); |
| 2574 | 2587 | } |
| 2575 | 2588 | |
| 2576 | 2589 | // Failing to parse as int |
| 2577 | 2590 | { |
| 2578 | | var status: Status = .{}; |
| 2579 | | defer status.deinit(gpa); |
| 2580 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &status, .{})); |
| 2581 | | try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{status}); |
| 2591 | var diag: Diagnostics = .{}; |
| 2592 | defer diag.deinit(gpa); |
| 2593 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &diag, .{})); |
| 2594 | try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{diag}); |
| 2582 | 2595 | } |
| 2583 | 2596 | |
| 2584 | 2597 | // Failing because an int is out of range |
| 2585 | 2598 | { |
| 2586 | | var status: Status = .{}; |
| 2587 | | defer status.deinit(gpa); |
| 2588 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &status, .{})); |
| 2599 | var diag: Diagnostics = .{}; |
| 2600 | defer diag.deinit(gpa); |
| 2601 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &diag, .{})); |
| 2589 | 2602 | try std.testing.expectFmt( |
| 2590 | 2603 | "1:1: error: type 'u8' cannot represent value\n", |
| 2591 | 2604 | "{}", |
| 2592 | | .{status}, |
| 2605 | .{diag}, |
| 2593 | 2606 | ); |
| 2594 | 2607 | } |
| 2595 | 2608 | |
| 2596 | 2609 | // Failing because a negative int is out of range |
| 2597 | 2610 | { |
| 2598 | | var status: Status = .{}; |
| 2599 | | defer status.deinit(gpa); |
| 2600 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &status, .{})); |
| 2611 | var diag: Diagnostics = .{}; |
| 2612 | defer diag.deinit(gpa); |
| 2613 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &diag, .{})); |
| 2601 | 2614 | try std.testing.expectFmt( |
| 2602 | 2615 | "1:1: error: type 'i8' cannot represent value\n", |
| 2603 | 2616 | "{}", |
| 2604 | | .{status}, |
| 2617 | .{diag}, |
| 2605 | 2618 | ); |
| 2606 | 2619 | } |
| 2607 | 2620 | |
| 2608 | 2621 | // Failing because an unsigned int is negative |
| 2609 | 2622 | { |
| 2610 | | var status: Status = .{}; |
| 2611 | | defer status.deinit(gpa); |
| 2612 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &status, .{})); |
| 2623 | var diag: Diagnostics = .{}; |
| 2624 | defer diag.deinit(gpa); |
| 2625 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &diag, .{})); |
| 2613 | 2626 | try std.testing.expectFmt( |
| 2614 | 2627 | "1:1: error: type 'u8' cannot represent value\n", |
| 2615 | 2628 | "{}", |
| 2616 | | .{status}, |
| 2629 | .{diag}, |
| 2617 | 2630 | ); |
| 2618 | 2631 | } |
| 2619 | 2632 | |
| 2620 | 2633 | // Failing because a float is non-whole |
| 2621 | 2634 | { |
| 2622 | | var status: Status = .{}; |
| 2623 | | defer status.deinit(gpa); |
| 2624 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &status, .{})); |
| 2635 | var diag: Diagnostics = .{}; |
| 2636 | defer diag.deinit(gpa); |
| 2637 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &diag, .{})); |
| 2625 | 2638 | try std.testing.expectFmt( |
| 2626 | 2639 | "1:1: error: type 'u8' cannot represent value\n", |
| 2627 | 2640 | "{}", |
| 2628 | | .{status}, |
| 2641 | .{diag}, |
| 2629 | 2642 | ); |
| 2630 | 2643 | } |
| 2631 | 2644 | |
| 2632 | 2645 | // Failing because a float is negative |
| 2633 | 2646 | { |
| 2634 | | var status: Status = .{}; |
| 2635 | | defer status.deinit(gpa); |
| 2636 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &status, .{})); |
| 2647 | var diag: Diagnostics = .{}; |
| 2648 | defer diag.deinit(gpa); |
| 2649 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &diag, .{})); |
| 2637 | 2650 | try std.testing.expectFmt( |
| 2638 | 2651 | "1:1: error: type 'u8' cannot represent value\n", |
| 2639 | 2652 | "{}", |
| 2640 | | .{status}, |
| 2653 | .{diag}, |
| 2641 | 2654 | ); |
| 2642 | 2655 | } |
| 2643 | 2656 | |
| 2644 | 2657 | // Negative integer zero |
| 2645 | 2658 | { |
| 2646 | | var status: Status = .{}; |
| 2647 | | defer status.deinit(gpa); |
| 2648 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &status, .{})); |
| 2659 | var diag: Diagnostics = .{}; |
| 2660 | defer diag.deinit(gpa); |
| 2661 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &diag, .{})); |
| 2649 | 2662 | try std.testing.expectFmt( |
| 2650 | 2663 | \\1:2: error: integer literal '-0' is ambiguous |
| 2651 | 2664 | \\1:2: note: use '0' for an integer zero |
| 2652 | 2665 | \\1:2: note: use '-0.0' for a floating-point signed zero |
| 2653 | 2666 | \\ |
| 2654 | | , "{}", .{status}); |
| 2667 | , "{}", .{diag}); |
| 2655 | 2668 | } |
| 2656 | 2669 | |
| 2657 | 2670 | // Negative integer zero casted to float |
| 2658 | 2671 | { |
| 2659 | | var status: Status = .{}; |
| 2660 | | defer status.deinit(gpa); |
| 2661 | | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &status, .{})); |
| 2672 | var diag: Diagnostics = .{}; |
| 2673 | defer diag.deinit(gpa); |
| 2674 | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &diag, .{})); |
| 2662 | 2675 | try std.testing.expectFmt( |
| 2663 | 2676 | \\1:2: error: integer literal '-0' is ambiguous |
| 2664 | 2677 | \\1:2: note: use '0' for an integer zero |
| 2665 | 2678 | \\1:2: note: use '-0.0' for a floating-point signed zero |
| 2666 | 2679 | \\ |
| 2667 | | , "{}", .{status}); |
| 2680 | , "{}", .{diag}); |
| 2668 | 2681 | } |
| 2669 | 2682 | |
| 2670 | 2683 | // Negative float 0 is allowed |
| ... | ... | @@ -2675,48 +2688,48 @@ test "std.zon parse int" { |
| 2675 | 2688 | |
| 2676 | 2689 | // Double negation is not allowed |
| 2677 | 2690 | { |
| 2678 | | var status: Status = .{}; |
| 2679 | | defer status.deinit(gpa); |
| 2680 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &status, .{})); |
| 2691 | var diag: Diagnostics = .{}; |
| 2692 | defer diag.deinit(gpa); |
| 2693 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &diag, .{})); |
| 2681 | 2694 | try std.testing.expectFmt( |
| 2682 | 2695 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2683 | 2696 | "{}", |
| 2684 | | .{status}, |
| 2697 | .{diag}, |
| 2685 | 2698 | ); |
| 2686 | 2699 | } |
| 2687 | 2700 | |
| 2688 | 2701 | { |
| 2689 | | var status: Status = .{}; |
| 2690 | | defer status.deinit(gpa); |
| 2702 | var diag: Diagnostics = .{}; |
| 2703 | defer diag.deinit(gpa); |
| 2691 | 2704 | try std.testing.expectError( |
| 2692 | 2705 | error.ParseZon, |
| 2693 | | fromSlice(f32, gpa, "--2.0", &status, .{}), |
| 2706 | fromSlice(f32, gpa, "--2.0", &diag, .{}), |
| 2694 | 2707 | ); |
| 2695 | 2708 | try std.testing.expectFmt( |
| 2696 | 2709 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2697 | 2710 | "{}", |
| 2698 | | .{status}, |
| 2711 | .{diag}, |
| 2699 | 2712 | ); |
| 2700 | 2713 | } |
| 2701 | 2714 | |
| 2702 | 2715 | // Invalid int literal |
| 2703 | 2716 | { |
| 2704 | | var status: Status = .{}; |
| 2705 | | defer status.deinit(gpa); |
| 2706 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &status, .{})); |
| 2707 | | try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{status}); |
| 2717 | var diag: Diagnostics = .{}; |
| 2718 | defer diag.deinit(gpa); |
| 2719 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &diag, .{})); |
| 2720 | try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{diag}); |
| 2708 | 2721 | } |
| 2709 | 2722 | |
| 2710 | 2723 | // Notes on invalid int literal |
| 2711 | 2724 | { |
| 2712 | | var status: Status = .{}; |
| 2713 | | defer status.deinit(gpa); |
| 2714 | | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &status, .{})); |
| 2725 | var diag: Diagnostics = .{}; |
| 2726 | defer diag.deinit(gpa); |
| 2727 | try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &diag, .{})); |
| 2715 | 2728 | try std.testing.expectFmt( |
| 2716 | 2729 | \\1:1: error: number '0123' has leading zero |
| 2717 | 2730 | \\1:1: note: use '0o' prefix for octal literals |
| 2718 | 2731 | \\ |
| 2719 | | , "{}", .{status}); |
| 2732 | , "{}", .{diag}); |
| 2720 | 2733 | } |
| 2721 | 2734 | } |
| 2722 | 2735 | |
| ... | ... | @@ -2724,23 +2737,23 @@ test "std.zon negative char" { |
| 2724 | 2737 | const gpa = std.testing.allocator; |
| 2725 | 2738 | |
| 2726 | 2739 | { |
| 2727 | | var status: Status = .{}; |
| 2728 | | defer status.deinit(gpa); |
| 2729 | | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &status, .{})); |
| 2740 | var diag: Diagnostics = .{}; |
| 2741 | defer diag.deinit(gpa); |
| 2742 | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &diag, .{})); |
| 2730 | 2743 | try std.testing.expectFmt( |
| 2731 | 2744 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2732 | 2745 | "{}", |
| 2733 | | .{status}, |
| 2746 | .{diag}, |
| 2734 | 2747 | ); |
| 2735 | 2748 | } |
| 2736 | 2749 | { |
| 2737 | | var status: Status = .{}; |
| 2738 | | defer status.deinit(gpa); |
| 2739 | | try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &status, .{})); |
| 2750 | var diag: Diagnostics = .{}; |
| 2751 | defer diag.deinit(gpa); |
| 2752 | try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &diag, .{})); |
| 2740 | 2753 | try std.testing.expectFmt( |
| 2741 | 2754 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2742 | 2755 | "{}", |
| 2743 | | .{status}, |
| 2756 | .{diag}, |
| 2744 | 2757 | ); |
| 2745 | 2758 | } |
| 2746 | 2759 | } |
| ... | ... | @@ -2821,81 +2834,81 @@ test "std.zon parse float" { |
| 2821 | 2834 | |
| 2822 | 2835 | // Negative nan not allowed |
| 2823 | 2836 | { |
| 2824 | | var status: Status = .{}; |
| 2825 | | defer status.deinit(gpa); |
| 2826 | | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &status, .{})); |
| 2837 | var diag: Diagnostics = .{}; |
| 2838 | defer diag.deinit(gpa); |
| 2839 | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &diag, .{})); |
| 2827 | 2840 | try std.testing.expectFmt( |
| 2828 | 2841 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2829 | 2842 | "{}", |
| 2830 | | .{status}, |
| 2843 | .{diag}, |
| 2831 | 2844 | ); |
| 2832 | 2845 | } |
| 2833 | 2846 | |
| 2834 | 2847 | // nan as int not allowed |
| 2835 | 2848 | { |
| 2836 | | var status: Status = .{}; |
| 2837 | | defer status.deinit(gpa); |
| 2838 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{})); |
| 2839 | | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status}); |
| 2849 | var diag: Diagnostics = .{}; |
| 2850 | defer diag.deinit(gpa); |
| 2851 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{})); |
| 2852 | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag}); |
| 2840 | 2853 | } |
| 2841 | 2854 | |
| 2842 | 2855 | // nan as int not allowed |
| 2843 | 2856 | { |
| 2844 | | var status: Status = .{}; |
| 2845 | | defer status.deinit(gpa); |
| 2846 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{})); |
| 2847 | | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status}); |
| 2857 | var diag: Diagnostics = .{}; |
| 2858 | defer diag.deinit(gpa); |
| 2859 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{})); |
| 2860 | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag}); |
| 2848 | 2861 | } |
| 2849 | 2862 | |
| 2850 | 2863 | // inf as int not allowed |
| 2851 | 2864 | { |
| 2852 | | var status: Status = .{}; |
| 2853 | | defer status.deinit(gpa); |
| 2854 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &status, .{})); |
| 2855 | | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status}); |
| 2865 | var diag: Diagnostics = .{}; |
| 2866 | defer diag.deinit(gpa); |
| 2867 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &diag, .{})); |
| 2868 | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag}); |
| 2856 | 2869 | } |
| 2857 | 2870 | |
| 2858 | 2871 | // -inf as int not allowed |
| 2859 | 2872 | { |
| 2860 | | var status: Status = .{}; |
| 2861 | | defer status.deinit(gpa); |
| 2862 | | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &status, .{})); |
| 2863 | | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status}); |
| 2873 | var diag: Diagnostics = .{}; |
| 2874 | defer diag.deinit(gpa); |
| 2875 | try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &diag, .{})); |
| 2876 | try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag}); |
| 2864 | 2877 | } |
| 2865 | 2878 | |
| 2866 | 2879 | // Bad identifier as float |
| 2867 | 2880 | { |
| 2868 | | var status: Status = .{}; |
| 2869 | | defer status.deinit(gpa); |
| 2870 | | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &status, .{})); |
| 2881 | var diag: Diagnostics = .{}; |
| 2882 | defer diag.deinit(gpa); |
| 2883 | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &diag, .{})); |
| 2871 | 2884 | try std.testing.expectFmt( |
| 2872 | 2885 | \\1:1: error: invalid expression |
| 2873 | 2886 | \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan' |
| 2874 | 2887 | \\1:1: note: precede identifier with '.' for an enum literal |
| 2875 | 2888 | \\ |
| 2876 | | , "{}", .{status}); |
| 2889 | , "{}", .{diag}); |
| 2877 | 2890 | } |
| 2878 | 2891 | |
| 2879 | 2892 | { |
| 2880 | | var status: Status = .{}; |
| 2881 | | defer status.deinit(gpa); |
| 2882 | | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &status, .{})); |
| 2893 | var diag: Diagnostics = .{}; |
| 2894 | defer diag.deinit(gpa); |
| 2895 | try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &diag, .{})); |
| 2883 | 2896 | try std.testing.expectFmt( |
| 2884 | 2897 | "1:1: error: expected number or 'inf' after '-'\n", |
| 2885 | 2898 | "{}", |
| 2886 | | .{status}, |
| 2899 | .{diag}, |
| 2887 | 2900 | ); |
| 2888 | 2901 | } |
| 2889 | 2902 | |
| 2890 | 2903 | // Non float as float |
| 2891 | 2904 | { |
| 2892 | | var status: Status = .{}; |
| 2893 | | defer status.deinit(gpa); |
| 2905 | var diag: Diagnostics = .{}; |
| 2906 | defer diag.deinit(gpa); |
| 2894 | 2907 | try std.testing.expectError( |
| 2895 | 2908 | error.ParseZon, |
| 2896 | | fromSlice(f32, gpa, "\"foo\"", &status, .{}), |
| 2909 | fromSlice(f32, gpa, "\"foo\"", &diag, .{}), |
| 2897 | 2910 | ); |
| 2898 | | try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{}", .{status}); |
| 2911 | try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{}", .{diag}); |
| 2899 | 2912 | } |
| 2900 | 2913 | } |
| 2901 | 2914 | |
| ... | ... | @@ -3132,69 +3145,69 @@ test "std.zon vector" { |
| 3132 | 3145 | |
| 3133 | 3146 | // Too few fields |
| 3134 | 3147 | { |
| 3135 | | var status: Status = .{}; |
| 3136 | | defer status.deinit(gpa); |
| 3148 | var diag: Diagnostics = .{}; |
| 3149 | defer diag.deinit(gpa); |
| 3137 | 3150 | try std.testing.expectError( |
| 3138 | 3151 | error.ParseZon, |
| 3139 | | fromSlice(@Vector(2, f32), gpa, ".{0.5}", &status, .{}), |
| 3152 | fromSlice(@Vector(2, f32), gpa, ".{0.5}", &diag, .{}), |
| 3140 | 3153 | ); |
| 3141 | 3154 | try std.testing.expectFmt( |
| 3142 | 3155 | "1:2: error: expected 2 vector elements; found 1\n", |
| 3143 | 3156 | "{}", |
| 3144 | | .{status}, |
| 3157 | .{diag}, |
| 3145 | 3158 | ); |
| 3146 | 3159 | } |
| 3147 | 3160 | |
| 3148 | 3161 | // Too many fields |
| 3149 | 3162 | { |
| 3150 | | var status: Status = .{}; |
| 3151 | | defer status.deinit(gpa); |
| 3163 | var diag: Diagnostics = .{}; |
| 3164 | defer diag.deinit(gpa); |
| 3152 | 3165 | try std.testing.expectError( |
| 3153 | 3166 | error.ParseZon, |
| 3154 | | fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &status, .{}), |
| 3167 | fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &diag, .{}), |
| 3155 | 3168 | ); |
| 3156 | 3169 | try std.testing.expectFmt( |
| 3157 | 3170 | "1:2: error: expected 2 vector elements; found 3\n", |
| 3158 | 3171 | "{}", |
| 3159 | | .{status}, |
| 3172 | .{diag}, |
| 3160 | 3173 | ); |
| 3161 | 3174 | } |
| 3162 | 3175 | |
| 3163 | 3176 | // Wrong type fields |
| 3164 | 3177 | { |
| 3165 | | var status: Status = .{}; |
| 3166 | | defer status.deinit(gpa); |
| 3178 | var diag: Diagnostics = .{}; |
| 3179 | defer diag.deinit(gpa); |
| 3167 | 3180 | try std.testing.expectError( |
| 3168 | 3181 | error.ParseZon, |
| 3169 | | fromSlice(@Vector(3, f32), gpa, ".{0.5, true, 2.5}", &status, .{}), |
| 3182 | fromSlice(@Vector(3, f32), gpa, ".{0.5, true, 2.5}", &diag, .{}), |
| 3170 | 3183 | ); |
| 3171 | 3184 | try std.testing.expectFmt( |
| 3172 | 3185 | "1:8: error: expected type 'f32'\n", |
| 3173 | 3186 | "{}", |
| 3174 | | .{status}, |
| 3187 | .{diag}, |
| 3175 | 3188 | ); |
| 3176 | 3189 | } |
| 3177 | 3190 | |
| 3178 | 3191 | // Wrong type |
| 3179 | 3192 | { |
| 3180 | | var status: Status = .{}; |
| 3181 | | defer status.deinit(gpa); |
| 3193 | var diag: Diagnostics = .{}; |
| 3194 | defer diag.deinit(gpa); |
| 3182 | 3195 | try std.testing.expectError( |
| 3183 | 3196 | error.ParseZon, |
| 3184 | | fromSlice(@Vector(3, u8), gpa, "true", &status, .{}), |
| 3197 | fromSlice(@Vector(3, u8), gpa, "true", &diag, .{}), |
| 3185 | 3198 | ); |
| 3186 | | try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{}", .{status}); |
| 3199 | try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{}", .{diag}); |
| 3187 | 3200 | } |
| 3188 | 3201 | |
| 3189 | 3202 | // Elements should get freed on error |
| 3190 | 3203 | { |
| 3191 | | var status: Status = .{}; |
| 3192 | | defer status.deinit(gpa); |
| 3204 | var diag: Diagnostics = .{}; |
| 3205 | defer diag.deinit(gpa); |
| 3193 | 3206 | try std.testing.expectError( |
| 3194 | 3207 | error.ParseZon, |
| 3195 | | fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &status, .{}), |
| 3208 | fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &diag, .{}), |
| 3196 | 3209 | ); |
| 3197 | | try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{}", .{status}); |
| 3210 | try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{}", .{diag}); |
| 3198 | 3211 | } |
| 3199 | 3212 | } |
| 3200 | 3213 | |
| ... | ... | @@ -3312,132 +3325,156 @@ test "std.zon add pointers" { |
| 3312 | 3325 | |
| 3313 | 3326 | // Test that optional types are flattened correctly in errors |
| 3314 | 3327 | { |
| 3315 | | var status: Status = .{}; |
| 3316 | | defer status.deinit(gpa); |
| 3328 | var diag: Diagnostics = .{}; |
| 3329 | defer diag.deinit(gpa); |
| 3317 | 3330 | try std.testing.expectError( |
| 3318 | 3331 | error.ParseZon, |
| 3319 | | fromSlice(*const ?*const u8, gpa, "true", &status, .{}), |
| 3332 | fromSlice(*const ?*const u8, gpa, "true", &diag, .{}), |
| 3320 | 3333 | ); |
| 3321 | | try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{}", .{status}); |
| 3334 | try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{}", .{diag}); |
| 3322 | 3335 | } |
| 3323 | 3336 | |
| 3324 | 3337 | { |
| 3325 | | var status: Status = .{}; |
| 3326 | | defer status.deinit(gpa); |
| 3338 | var diag: Diagnostics = .{}; |
| 3339 | defer diag.deinit(gpa); |
| 3327 | 3340 | try std.testing.expectError( |
| 3328 | 3341 | error.ParseZon, |
| 3329 | | fromSlice(*const ?*const f32, gpa, "true", &status, .{}), |
| 3342 | fromSlice(*const ?*const f32, gpa, "true", &diag, .{}), |
| 3330 | 3343 | ); |
| 3331 | | try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{}", .{status}); |
| 3344 | try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{}", .{diag}); |
| 3332 | 3345 | } |
| 3333 | 3346 | |
| 3334 | 3347 | { |
| 3335 | | var status: Status = .{}; |
| 3336 | | defer status.deinit(gpa); |
| 3348 | var diag: Diagnostics = .{}; |
| 3349 | defer diag.deinit(gpa); |
| 3337 | 3350 | try std.testing.expectError( |
| 3338 | 3351 | error.ParseZon, |
| 3339 | | fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &status, .{}), |
| 3352 | fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &diag, .{}), |
| 3340 | 3353 | ); |
| 3341 | | try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{}", .{status}); |
| 3354 | try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{}", .{diag}); |
| 3342 | 3355 | } |
| 3343 | 3356 | |
| 3344 | 3357 | { |
| 3345 | | var status: Status = .{}; |
| 3346 | | defer status.deinit(gpa); |
| 3358 | var diag: Diagnostics = .{}; |
| 3359 | defer diag.deinit(gpa); |
| 3347 | 3360 | try std.testing.expectError( |
| 3348 | 3361 | error.ParseZon, |
| 3349 | | fromSlice(*const ?*const bool, gpa, "10", &status, .{}), |
| 3362 | fromSlice(*const ?*const bool, gpa, "10", &diag, .{}), |
| 3350 | 3363 | ); |
| 3351 | | try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{}", .{status}); |
| 3364 | try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{}", .{diag}); |
| 3352 | 3365 | } |
| 3353 | 3366 | |
| 3354 | 3367 | { |
| 3355 | | var status: Status = .{}; |
| 3356 | | defer status.deinit(gpa); |
| 3368 | var diag: Diagnostics = .{}; |
| 3369 | defer diag.deinit(gpa); |
| 3357 | 3370 | try std.testing.expectError( |
| 3358 | 3371 | error.ParseZon, |
| 3359 | | fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &status, .{}), |
| 3372 | fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &diag, .{}), |
| 3360 | 3373 | ); |
| 3361 | | try std.testing.expectFmt("1:1: error: expected optional struct\n", "{}", .{status}); |
| 3374 | try std.testing.expectFmt("1:1: error: expected optional struct\n", "{}", .{diag}); |
| 3362 | 3375 | } |
| 3363 | 3376 | |
| 3364 | 3377 | { |
| 3365 | | var status: Status = .{}; |
| 3366 | | defer status.deinit(gpa); |
| 3378 | var diag: Diagnostics = .{}; |
| 3379 | defer diag.deinit(gpa); |
| 3367 | 3380 | try std.testing.expectError( |
| 3368 | 3381 | error.ParseZon, |
| 3369 | | fromSlice(*const ?*const struct { i32 }, gpa, "true", &status, .{}), |
| 3382 | fromSlice(*const ?*const struct { i32 }, gpa, "true", &diag, .{}), |
| 3370 | 3383 | ); |
| 3371 | | try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{}", .{status}); |
| 3384 | try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{}", .{diag}); |
| 3372 | 3385 | } |
| 3373 | 3386 | |
| 3374 | 3387 | { |
| 3375 | | var status: Status = .{}; |
| 3376 | | defer status.deinit(gpa); |
| 3388 | var diag: Diagnostics = .{}; |
| 3389 | defer diag.deinit(gpa); |
| 3377 | 3390 | try std.testing.expectError( |
| 3378 | 3391 | error.ParseZon, |
| 3379 | | fromSlice(*const ?*const union { x: void }, gpa, "true", &status, .{}), |
| 3392 | fromSlice(*const ?*const union { x: void }, gpa, "true", &diag, .{}), |
| 3380 | 3393 | ); |
| 3381 | | try std.testing.expectFmt("1:1: error: expected optional union\n", "{}", .{status}); |
| 3394 | try std.testing.expectFmt("1:1: error: expected optional union\n", "{}", .{diag}); |
| 3382 | 3395 | } |
| 3383 | 3396 | |
| 3384 | 3397 | { |
| 3385 | | var status: Status = .{}; |
| 3386 | | defer status.deinit(gpa); |
| 3398 | var diag: Diagnostics = .{}; |
| 3399 | defer diag.deinit(gpa); |
| 3387 | 3400 | try std.testing.expectError( |
| 3388 | 3401 | error.ParseZon, |
| 3389 | | fromSlice(*const ?*const [3]u8, gpa, "true", &status, .{}), |
| 3402 | fromSlice(*const ?*const [3]u8, gpa, "true", &diag, .{}), |
| 3390 | 3403 | ); |
| 3391 | | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status}); |
| 3404 | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag}); |
| 3392 | 3405 | } |
| 3393 | 3406 | |
| 3394 | 3407 | { |
| 3395 | | var status: Status = .{}; |
| 3396 | | defer status.deinit(gpa); |
| 3408 | var diag: Diagnostics = .{}; |
| 3409 | defer diag.deinit(gpa); |
| 3397 | 3410 | try std.testing.expectError( |
| 3398 | 3411 | error.ParseZon, |
| 3399 | | fromSlice(?[3]u8, gpa, "true", &status, .{}), |
| 3412 | fromSlice(?[3]u8, gpa, "true", &diag, .{}), |
| 3400 | 3413 | ); |
| 3401 | | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status}); |
| 3414 | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag}); |
| 3402 | 3415 | } |
| 3403 | 3416 | |
| 3404 | 3417 | { |
| 3405 | | var status: Status = .{}; |
| 3406 | | defer status.deinit(gpa); |
| 3418 | var diag: Diagnostics = .{}; |
| 3419 | defer diag.deinit(gpa); |
| 3407 | 3420 | try std.testing.expectError( |
| 3408 | 3421 | error.ParseZon, |
| 3409 | | fromSlice(*const ?*const []u8, gpa, "true", &status, .{}), |
| 3422 | fromSlice(*const ?*const []u8, gpa, "true", &diag, .{}), |
| 3410 | 3423 | ); |
| 3411 | | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status}); |
| 3424 | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag}); |
| 3412 | 3425 | } |
| 3413 | 3426 | |
| 3414 | 3427 | { |
| 3415 | | var status: Status = .{}; |
| 3416 | | defer status.deinit(gpa); |
| 3428 | var diag: Diagnostics = .{}; |
| 3429 | defer diag.deinit(gpa); |
| 3417 | 3430 | try std.testing.expectError( |
| 3418 | 3431 | error.ParseZon, |
| 3419 | | fromSlice(?[]u8, gpa, "true", &status, .{}), |
| 3432 | fromSlice(?[]u8, gpa, "true", &diag, .{}), |
| 3420 | 3433 | ); |
| 3421 | | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status}); |
| 3434 | try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag}); |
| 3422 | 3435 | } |
| 3423 | 3436 | |
| 3424 | 3437 | { |
| 3425 | | var status: Status = .{}; |
| 3426 | | defer status.deinit(gpa); |
| 3438 | var diag: Diagnostics = .{}; |
| 3439 | defer diag.deinit(gpa); |
| 3427 | 3440 | try std.testing.expectError( |
| 3428 | 3441 | error.ParseZon, |
| 3429 | | fromSlice(*const ?*const []const u8, gpa, "true", &status, .{}), |
| 3442 | fromSlice(*const ?*const []const u8, gpa, "true", &diag, .{}), |
| 3430 | 3443 | ); |
| 3431 | | try std.testing.expectFmt("1:1: error: expected optional string\n", "{}", .{status}); |
| 3444 | try std.testing.expectFmt("1:1: error: expected optional string\n", "{}", .{diag}); |
| 3432 | 3445 | } |
| 3433 | 3446 | |
| 3434 | 3447 | { |
| 3435 | | var status: Status = .{}; |
| 3436 | | defer status.deinit(gpa); |
| 3448 | var diag: Diagnostics = .{}; |
| 3449 | defer diag.deinit(gpa); |
| 3437 | 3450 | try std.testing.expectError( |
| 3438 | 3451 | error.ParseZon, |
| 3439 | | fromSlice(*const ?*const enum { foo }, gpa, "true", &status, .{}), |
| 3452 | fromSlice(*const ?*const enum { foo }, gpa, "true", &diag, .{}), |
| 3440 | 3453 | ); |
| 3441 | | try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{}", .{status}); |
| 3454 | try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{}", .{diag}); |
| 3455 | } |
| 3456 | } |
| 3457 | |
| 3458 | test "std.zon stop on node" { |
| 3459 | const gpa = std.testing.allocator; |
| 3460 | |
| 3461 | { |
| 3462 | const Vec2 = struct { |
| 3463 | x: Zoir.Node.Index, |
| 3464 | y: f32, |
| 3465 | }; |
| 3466 | |
| 3467 | var diag: Diagnostics = .{}; |
| 3468 | defer diag.deinit(gpa); |
| 3469 | const result = try fromSlice(Vec2, gpa, ".{ .x = 1.5, .y = 2.5 }", &diag, .{}); |
| 3470 | try std.testing.expectEqual(result.y, 2.5); |
| 3471 | try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.5 }, result.x.get(diag.zoir)); |
| 3472 | } |
| 3473 | |
| 3474 | { |
| 3475 | var diag: Diagnostics = .{}; |
| 3476 | defer diag.deinit(gpa); |
| 3477 | const result = try fromSlice(Zoir.Node.Index, gpa, "1.23", &diag, .{}); |
| 3478 | try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.23 }, result.get(diag.zoir)); |
| 3442 | 3479 | } |
| 3443 | 3480 | } |