| ... | ... | @@ -36,9 +36,14 @@ branch_count: u32 = 0, |
| 36 | 36 | /// access to the source location set by the previous instruction which did |
| 37 | 37 | /// contain a mapped source location. |
| 38 | 38 | src: LazySrcLoc = .{ .token_offset = 0 }, |
| 39 | | next_arg_index: usize = 0, |
| 40 | | params: std.ArrayListUnmanaged(Param) = .{}, |
| 41 | 39 | decl_val_table: std.AutoHashMapUnmanaged(*Decl, Air.Inst.Ref) = .{}, |
| 40 | /// `param` instructions are collected here to be used by the `func` instruction. |
| 41 | params: std.ArrayListUnmanaged(Param) = .{}, |
| 42 | /// When doing a generic function instantiation, this array collects a `Value` object for |
| 43 | /// each parameter that is comptime known and thus elided from the generated function. |
| 44 | /// This memory is allocated by a parent `Sema` and owned by the values arena of the owner_decl. |
| 45 | comptime_args: []TypedValue = &.{}, |
| 46 | next_arg_index: usize = 0, |
| 42 | 47 | |
| 43 | 48 | const std = @import("std"); |
| 44 | 49 | const mem = std.mem; |
| ... | ... | @@ -64,8 +69,8 @@ const target_util = @import("target.zig"); |
| 64 | 69 | |
| 65 | 70 | const Param = struct { |
| 66 | 71 | name: [:0]const u8, |
| 67 | | /// `none` means `anytype`. |
| 68 | | ty: Air.Inst.Ref, |
| 72 | /// `noreturn` means `anytype`. |
| 73 | ty: Type, |
| 69 | 74 | is_comptime: bool, |
| 70 | 75 | }; |
| 71 | 76 | |
| ... | ... | @@ -366,26 +371,6 @@ pub fn analyzeBody( |
| 366 | 371 | // continue the loop. |
| 367 | 372 | // We also know that they cannot be referenced later, so we avoid |
| 368 | 373 | // putting them into the map. |
| 369 | | .param => { |
| 370 | | try sema.zirParam(inst, false); |
| 371 | | i += 1; |
| 372 | | continue; |
| 373 | | }, |
| 374 | | .param_comptime => { |
| 375 | | try sema.zirParam(inst, true); |
| 376 | | i += 1; |
| 377 | | continue; |
| 378 | | }, |
| 379 | | .param_anytype => { |
| 380 | | try sema.zirParamAnytype(inst, false); |
| 381 | | i += 1; |
| 382 | | continue; |
| 383 | | }, |
| 384 | | .param_anytype_comptime => { |
| 385 | | try sema.zirParamAnytype(inst, true); |
| 386 | | i += 1; |
| 387 | | continue; |
| 388 | | }, |
| 389 | 374 | .breakpoint => { |
| 390 | 375 | try sema.zirBreakpoint(block, inst); |
| 391 | 376 | i += 1; |
| ... | ... | @@ -519,6 +504,88 @@ pub fn analyzeBody( |
| 519 | 504 | return break_inst; |
| 520 | 505 | } |
| 521 | 506 | }, |
| 507 | .param => blk: { |
| 508 | const inst_data = sema.code.instructions.items(.data)[inst].pl_tok; |
| 509 | const src = inst_data.src(); |
| 510 | const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index).data; |
| 511 | const param_name = sema.code.nullTerminatedString(extra.name); |
| 512 | |
| 513 | if (sema.nextArgIsComptimeElided()) { |
| 514 | i += 1; |
| 515 | continue; |
| 516 | } |
| 517 | |
| 518 | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 519 | // usingnamespace is implemented. |
| 520 | |
| 521 | const param_ty = try sema.resolveType(block, src, extra.ty); |
| 522 | try sema.params.append(sema.gpa, .{ |
| 523 | .name = param_name, |
| 524 | .ty = param_ty, |
| 525 | .is_comptime = false, |
| 526 | }); |
| 527 | break :blk try sema.addConstUndef(param_ty); |
| 528 | }, |
| 529 | .param_comptime => blk: { |
| 530 | const inst_data = sema.code.instructions.items(.data)[inst].pl_tok; |
| 531 | const src = inst_data.src(); |
| 532 | const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index).data; |
| 533 | const param_name = sema.code.nullTerminatedString(extra.name); |
| 534 | |
| 535 | if (sema.nextArgIsComptimeElided()) { |
| 536 | i += 1; |
| 537 | continue; |
| 538 | } |
| 539 | |
| 540 | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 541 | // usingnamespace is implemented. |
| 542 | |
| 543 | const param_ty = try sema.resolveType(block, src, extra.ty); |
| 544 | try sema.params.append(sema.gpa, .{ |
| 545 | .name = param_name, |
| 546 | .ty = param_ty, |
| 547 | .is_comptime = true, |
| 548 | }); |
| 549 | break :blk try sema.addConstUndef(param_ty); |
| 550 | }, |
| 551 | .param_anytype => blk: { |
| 552 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 553 | const param_name = inst_data.get(sema.code); |
| 554 | |
| 555 | if (sema.nextArgIsComptimeElided()) { |
| 556 | i += 1; |
| 557 | continue; |
| 558 | } |
| 559 | |
| 560 | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 561 | // usingnamespace is implemented. |
| 562 | |
| 563 | try sema.params.append(sema.gpa, .{ |
| 564 | .name = param_name, |
| 565 | .ty = Type.initTag(.noreturn), |
| 566 | .is_comptime = false, |
| 567 | }); |
| 568 | break :blk try sema.addConstUndef(Type.initTag(.@"undefined")); |
| 569 | }, |
| 570 | .param_anytype_comptime => blk: { |
| 571 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 572 | const param_name = inst_data.get(sema.code); |
| 573 | |
| 574 | if (sema.nextArgIsComptimeElided()) { |
| 575 | i += 1; |
| 576 | continue; |
| 577 | } |
| 578 | |
| 579 | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 580 | // usingnamespace is implemented. |
| 581 | |
| 582 | try sema.params.append(sema.gpa, .{ |
| 583 | .name = param_name, |
| 584 | .ty = Type.initTag(.noreturn), |
| 585 | .is_comptime = true, |
| 586 | }); |
| 587 | break :blk try sema.addConstUndef(Type.initTag(.@"undefined")); |
| 588 | }, |
| 522 | 589 | }; |
| 523 | 590 | if (sema.typeOf(air_inst).isNoReturn()) |
| 524 | 591 | return always_noreturn; |
| ... | ... | @@ -1339,36 +1406,6 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 1339 | 1406 | return sema.analyzeLoad(block, src, result_ptr, result_ptr_src); |
| 1340 | 1407 | } |
| 1341 | 1408 | |
| 1342 | | fn zirParam(sema: *Sema, inst: Zir.Inst.Index, is_comptime: bool) CompileError!void { |
| 1343 | | const inst_data = sema.code.instructions.items(.data)[inst].pl_tok; |
| 1344 | | const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index).data; |
| 1345 | | const param_name = sema.code.nullTerminatedString(extra.name); |
| 1346 | | |
| 1347 | | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 1348 | | // usingnamespace is implemented. |
| 1349 | | |
| 1350 | | const param_ty = sema.resolveInst(extra.ty); |
| 1351 | | try sema.params.append(sema.gpa, .{ |
| 1352 | | .name = param_name, |
| 1353 | | .ty = param_ty, |
| 1354 | | .is_comptime = is_comptime, |
| 1355 | | }); |
| 1356 | | } |
| 1357 | | |
| 1358 | | fn zirParamAnytype(sema: *Sema, inst: Zir.Inst.Index, is_comptime: bool) CompileError!void { |
| 1359 | | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 1360 | | const param_name = inst_data.get(sema.code); |
| 1361 | | |
| 1362 | | // TODO check if param_name shadows a Decl. This only needs to be done if |
| 1363 | | // usingnamespace is implemented. |
| 1364 | | |
| 1365 | | try sema.params.append(sema.gpa, .{ |
| 1366 | | .name = param_name, |
| 1367 | | .ty = .none, |
| 1368 | | .is_comptime = is_comptime, |
| 1369 | | }); |
| 1370 | | } |
| 1371 | | |
| 1372 | 1409 | fn zirAllocExtended( |
| 1373 | 1410 | sema: *Sema, |
| 1374 | 1411 | block: *Scope.Block, |
| ... | ... | @@ -2497,10 +2534,6 @@ fn analyzeCall( |
| 2497 | 2534 | sema.func = module_fn; |
| 2498 | 2535 | defer sema.func = parent_func; |
| 2499 | 2536 | |
| 2500 | | const parent_next_arg_index = sema.next_arg_index; |
| 2501 | | sema.next_arg_index = 0; |
| 2502 | | defer sema.next_arg_index = parent_next_arg_index; |
| 2503 | | |
| 2504 | 2537 | var child_block: Scope.Block = .{ |
| 2505 | 2538 | .parent = null, |
| 2506 | 2539 | .sema = sema, |
| ... | ... | @@ -2537,7 +2570,7 @@ fn analyzeCall( |
| 2537 | 2570 | } |
| 2538 | 2571 | _ = try sema.analyzeBody(&child_block, fn_info.body); |
| 2539 | 2572 | break :res try sema.analyzeBlockBody(block, call_src, &child_block, merges); |
| 2540 | | } else if (func_ty_info.is_generic) { |
| 2573 | } else if (func_ty_info.is_generic) res: { |
| 2541 | 2574 | const func_val = try sema.resolveConstValue(block, func_src, func); |
| 2542 | 2575 | const module_fn = func_val.castTag(.function).?.data; |
| 2543 | 2576 | // Check the Module's generic function map with an adapted context, so that we |
| ... | ... | @@ -2545,37 +2578,142 @@ fn analyzeCall( |
| 2545 | 2578 | // only to junk it if it matches an existing instantiation. |
| 2546 | 2579 | // TODO |
| 2547 | 2580 | |
| 2548 | | // Create a Decl for the new function. |
| 2549 | | const generic_namespace = try sema.arena.create(Module.Scope.Namespace); |
| 2550 | | generic_namespace.* = .{ |
| 2551 | | .parent = block.src_decl.namespace, |
| 2552 | | .file_scope = block.src_decl.namespace.file_scope, |
| 2553 | | .ty = func_ty, |
| 2581 | const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst); |
| 2582 | const zir_tags = sema.code.instructions.items(.tag); |
| 2583 | var non_comptime_args_len: u32 = 0; |
| 2584 | const new_func = new_func: { |
| 2585 | const namespace = module_fn.owner_decl.namespace; |
| 2586 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); |
| 2587 | |
| 2588 | // Create a Decl for the new function. |
| 2589 | const new_decl = try mod.allocateNewDecl(namespace, module_fn.owner_decl.src_node); |
| 2590 | // TODO better names for generic function instantiations |
| 2591 | const name_index = mod.getNextAnonNameIndex(); |
| 2592 | new_decl.name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{ |
| 2593 | module_fn.owner_decl.name, name_index, |
| 2594 | }); |
| 2595 | new_decl.src_line = module_fn.owner_decl.src_line; |
| 2596 | new_decl.is_pub = module_fn.owner_decl.is_pub; |
| 2597 | new_decl.is_exported = module_fn.owner_decl.is_exported; |
| 2598 | new_decl.has_align = module_fn.owner_decl.has_align; |
| 2599 | new_decl.has_linksection = module_fn.owner_decl.has_linksection; |
| 2600 | new_decl.zir_decl_index = module_fn.owner_decl.zir_decl_index; |
| 2601 | new_decl.alive = true; // This Decl is called at runtime. |
| 2602 | new_decl.has_tv = true; |
| 2603 | new_decl.owns_tv = true; |
| 2604 | new_decl.analysis = .in_progress; |
| 2605 | new_decl.generation = mod.generation; |
| 2606 | |
| 2607 | namespace.anon_decls.putAssumeCapacityNoClobber(new_decl, {}); |
| 2608 | |
| 2609 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| 2610 | errdefer new_decl_arena.deinit(); |
| 2611 | |
| 2612 | // Re-run the block that creates the function, with the comptime parameters |
| 2613 | // pre-populated inside `inst_map`. This causes `param_comptime` and |
| 2614 | // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a |
| 2615 | // new, monomorphized function, with the comptime parameters elided. |
| 2616 | var child_sema: Sema = .{ |
| 2617 | .mod = mod, |
| 2618 | .gpa = gpa, |
| 2619 | .arena = sema.arena, |
| 2620 | .code = sema.code, |
| 2621 | .owner_decl = new_decl, |
| 2622 | .namespace = namespace, |
| 2623 | .func = null, |
| 2624 | .owner_func = null, |
| 2625 | .comptime_args = try new_decl_arena.allocator.alloc(TypedValue, args.len), |
| 2626 | }; |
| 2627 | defer child_sema.deinit(); |
| 2628 | |
| 2629 | var child_block: Scope.Block = .{ |
| 2630 | .parent = null, |
| 2631 | .sema = &child_sema, |
| 2632 | .src_decl = new_decl, |
| 2633 | .instructions = .{}, |
| 2634 | .inlining = null, |
| 2635 | .is_comptime = true, |
| 2636 | }; |
| 2637 | defer child_block.instructions.deinit(gpa); |
| 2638 | |
| 2639 | try child_sema.inst_map.ensureUnusedCapacity(gpa, @intCast(u32, args.len)); |
| 2640 | var arg_i: usize = 0; |
| 2641 | for (fn_info.param_body) |inst| { |
| 2642 | const is_comptime = switch (zir_tags[inst]) { |
| 2643 | .param_comptime, .param_anytype_comptime => true, |
| 2644 | .param, .param_anytype => false, // TODO make true for always comptime types |
| 2645 | else => continue, |
| 2646 | }; |
| 2647 | if (is_comptime) { |
| 2648 | // TODO: pass .unneeded to resolveConstValue and then if we get |
| 2649 | // error.NeededSourceLocation resolve the arg source location and |
| 2650 | // try again. |
| 2651 | const arg_src = call_src; |
| 2652 | const arg = args[arg_i]; |
| 2653 | const arg_val = try sema.resolveConstValue(block, arg_src, arg); |
| 2654 | child_sema.comptime_args[arg_i] = .{ |
| 2655 | .ty = try sema.typeOf(arg).copy(&new_decl_arena.allocator), |
| 2656 | .val = try arg_val.copy(&new_decl_arena.allocator), |
| 2657 | }; |
| 2658 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 2659 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 2660 | } else { |
| 2661 | non_comptime_args_len += 1; |
| 2662 | child_sema.comptime_args[arg_i] = .{ |
| 2663 | .ty = Type.initTag(.noreturn), |
| 2664 | .val = Value.initTag(.unreachable_value), |
| 2665 | }; |
| 2666 | } |
| 2667 | arg_i += 1; |
| 2668 | } |
| 2669 | const new_func_inst = try child_sema.resolveBody(&child_block, fn_info.param_body); |
| 2670 | const new_func_val = try child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst); |
| 2671 | const new_func = new_func_val.castTag(.function).?.data; |
| 2672 | |
| 2673 | // Populate the Decl ty/val with the function and its type. |
| 2674 | new_decl.ty = try child_sema.typeOf(new_func_inst).copy(&new_decl_arena.allocator); |
| 2675 | new_decl.val = try Value.Tag.function.create(&new_decl_arena.allocator, new_func); |
| 2676 | new_decl.analysis = .complete; |
| 2677 | |
| 2678 | // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field |
| 2679 | // will be populated, ensuring it will have `analyzeBody` called with the ZIR |
| 2680 | // parameters mapped appropriately. |
| 2681 | try mod.comp.bin_file.allocateDeclIndexes(new_decl); |
| 2682 | try mod.comp.work_queue.writeItem(.{ .codegen_func = new_func }); |
| 2683 | |
| 2684 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 2685 | break :new_func try sema.analyzeDeclVal(block, func_src, new_decl); |
| 2554 | 2686 | }; |
| 2555 | | const new_decl = try mod.allocateNewDecl(generic_namespace, module_fn.owner_decl.src_node); |
| 2556 | | _ = new_decl; |
| 2557 | | |
| 2558 | | // Iterate over the parameters that are comptime, evaluating their type expressions |
| 2559 | | // inside a Scope which contains the previous parameters. |
| 2560 | | //for (args) |arg, arg_i| { |
| 2561 | | //} |
| 2562 | | |
| 2563 | | // Create a new Fn with only the runtime-known parameters. |
| 2564 | | // TODO |
| 2565 | | |
| 2566 | | // Populate the Decl ty/val with the function and its type. |
| 2567 | | // TODO |
| 2568 | | |
| 2569 | | // Queue up a `codegen_func` work item for the new Fn, making sure it will have |
| 2570 | | // `analyzeBody` called with the ZIR parameters mapped appropriately. |
| 2571 | | // TODO |
| 2572 | 2687 | |
| 2573 | 2688 | // Save it into the Module's generic function map. |
| 2574 | 2689 | // TODO |
| 2575 | 2690 | |
| 2576 | | // Call it the same as a runtime function. |
| 2577 | | // TODO |
| 2578 | | return mod.fail(&block.base, func_src, "TODO implement generic fn call", .{}); |
| 2691 | // Make a runtime call to the new function, making sure to omit the comptime args. |
| 2692 | try sema.requireRuntimeBlock(block, call_src); |
| 2693 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + |
| 2694 | non_comptime_args_len); |
| 2695 | const func_inst = try block.addInst(.{ |
| 2696 | .tag = .call, |
| 2697 | .data = .{ .pl_op = .{ |
| 2698 | .operand = new_func, |
| 2699 | .payload = sema.addExtraAssumeCapacity(Air.Call{ |
| 2700 | .args_len = non_comptime_args_len, |
| 2701 | }), |
| 2702 | } }, |
| 2703 | }); |
| 2704 | var arg_i: usize = 0; |
| 2705 | for (fn_info.param_body) |inst| { |
| 2706 | const is_comptime = switch (zir_tags[inst]) { |
| 2707 | .param_comptime, .param_anytype_comptime => true, |
| 2708 | .param, .param_anytype => false, // TODO make true for always comptime types |
| 2709 | else => continue, |
| 2710 | }; |
| 2711 | if (is_comptime) { |
| 2712 | sema.air_extra.appendAssumeCapacity(@enumToInt(args[arg_i])); |
| 2713 | } |
| 2714 | arg_i += 1; |
| 2715 | } |
| 2716 | break :res func_inst; |
| 2579 | 2717 | } else res: { |
| 2580 | 2718 | try sema.requireRuntimeBlock(block, call_src); |
| 2581 | 2719 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + |
| ... | ... | @@ -3302,15 +3440,10 @@ fn funcCommon( |
| 3302 | 3440 | const param_types = try sema.arena.alloc(Type, sema.params.items.len); |
| 3303 | 3441 | const comptime_params = try sema.arena.alloc(bool, sema.params.items.len); |
| 3304 | 3442 | for (sema.params.items) |param, i| { |
| 3305 | | if (param.ty == .none) { |
| 3443 | if (param.ty.tag() == .noreturn) { |
| 3306 | 3444 | param_types[i] = Type.initTag(.noreturn); // indicates anytype |
| 3307 | 3445 | } else { |
| 3308 | | // TODO make a compile error from `resolveType` report the source location |
| 3309 | | // of the specific parameter. Will need to take a similar strategy as |
| 3310 | | // `resolveSwitchItemVal` to avoid resolving the source location unless |
| 3311 | | // we actually need to report an error. |
| 3312 | | const param_src = src; |
| 3313 | | param_types[i] = try sema.analyzeAsType(block, param_src, param.ty); |
| 3446 | param_types[i] = param.ty; |
| 3314 | 3447 | } |
| 3315 | 3448 | comptime_params[i] = param.is_comptime; |
| 3316 | 3449 | any_are_comptime = any_are_comptime or param.is_comptime; |
| ... | ... | @@ -3402,6 +3535,7 @@ fn funcCommon( |
| 3402 | 3535 | .state = anal_state, |
| 3403 | 3536 | .zir_body_inst = body_inst, |
| 3404 | 3537 | .owner_decl = sema.owner_decl, |
| 3538 | .comptime_args = if (sema.comptime_args.len == 0) null else sema.comptime_args.ptr, |
| 3405 | 3539 | .lbrace_line = src_locs.lbrace_line, |
| 3406 | 3540 | .rbrace_line = src_locs.rbrace_line, |
| 3407 | 3541 | .lbrace_column = @truncate(u16, src_locs.columns), |
| ... | ... | @@ -6819,19 +6953,12 @@ fn safetyPanic( |
| 6819 | 6953 | const msg_inst = msg_inst: { |
| 6820 | 6954 | // TODO instead of making a new decl for every panic in the entire compilation, |
| 6821 | 6955 | // introduce the concept of a reference-counted decl for these |
| 6822 | | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| 6823 | | errdefer new_decl_arena.deinit(); |
| 6824 | | |
| 6825 | | const decl_ty = try Type.Tag.array_u8.create(&new_decl_arena.allocator, msg.len); |
| 6826 | | const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, msg); |
| 6827 | | |
| 6828 | | const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ |
| 6829 | | .ty = decl_ty, |
| 6830 | | .val = decl_val, |
| 6831 | | }); |
| 6832 | | errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); |
| 6833 | | try new_decl.finalizeNewArena(&new_decl_arena); |
| 6834 | | break :msg_inst try sema.analyzeDeclRef(new_decl); |
| 6956 | var anon_decl = try block.startAnonDecl(); |
| 6957 | defer anon_decl.deinit(); |
| 6958 | break :msg_inst try sema.analyzeDeclRef(try anon_decl.finish( |
| 6959 | try Type.Tag.array_u8.create(anon_decl.arena(), msg.len), |
| 6960 | try Value.Tag.bytes.create(anon_decl.arena(), msg), |
| 6961 | )); |
| 6835 | 6962 | }; |
| 6836 | 6963 | |
| 6837 | 6964 | const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src); |
| ... | ... | @@ -8832,7 +8959,7 @@ fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { |
| 8832 | 8959 | return sema.addConstant(ty, Value.initTag(.undef)); |
| 8833 | 8960 | } |
| 8834 | 8961 | |
| 8835 | | fn addConstant(sema: *Sema, ty: Type, val: Value) CompileError!Air.Inst.Ref { |
| 8962 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |
| 8836 | 8963 | const gpa = sema.gpa; |
| 8837 | 8964 | const ty_inst = try sema.addType(ty); |
| 8838 | 8965 | try sema.air_values.append(gpa, val); |
| ... | ... | @@ -8888,3 +9015,10 @@ fn isComptimeKnown( |
| 8888 | 9015 | ) !bool { |
| 8889 | 9016 | return (try sema.resolveMaybeUndefVal(block, src, inst)) != null; |
| 8890 | 9017 | } |
| 9018 | |
| 9019 | fn nextArgIsComptimeElided(sema: *Sema) bool { |
| 9020 | if (sema.comptime_args.len == 0) return false; |
| 9021 | const result = sema.comptime_args[sema.next_arg_index].val.tag() != .unreachable_value; |
| 9022 | sema.next_arg_index += 1; |
| 9023 | return result; |
| 9024 | } |