mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Delete a ton of unused arguments
This commit is contained in:
parent
1e57610913
commit
799dada6a0
58 changed files with 200 additions and 228 deletions
34
build.zig
34
build.zig
|
|
@ -334,7 +334,7 @@ const CheckUnusedSuppressionStep = struct {
|
|||
std.debug.print("=" ** 80 ++ "\n\n", .{});
|
||||
|
||||
std.debug.print(
|
||||
\\In this codebase, we do NOT use `_ = variable;` to suppress unused variable warnings.
|
||||
\\In this codebase, we do NOT use `_ = variable;` or `_:` to suppress unused warnings.
|
||||
\\
|
||||
\\Instead, you should:
|
||||
\\ 1. Delete the unused variable, parameter, or argument
|
||||
|
|
@ -359,7 +359,7 @@ const CheckUnusedSuppressionStep = struct {
|
|||
std.debug.print("\n" ++ "=" ** 80 ++ "\n", .{});
|
||||
|
||||
return step.fail(
|
||||
"Found {d} unused variable suppression patterns (`_ = identifier;`). " ++
|
||||
"Found {d} unused variable/argument suppression patterns (`_ = identifier;` or `_:`). " ++
|
||||
"Delete the unused variables/arguments and update call sites instead.",
|
||||
.{violations.items.len},
|
||||
);
|
||||
|
|
@ -393,6 +393,12 @@ const CheckUnusedSuppressionStep = struct {
|
|||
const content = file.readToEndAlloc(allocator, 10 * 1024 * 1024) catch continue;
|
||||
defer allocator.free(content);
|
||||
|
||||
// Skip files that contain "// zig-lint: required-param" comment
|
||||
// These are files with implementations that must match external API signatures
|
||||
if (std.mem.indexOf(u8, content, "// zig-lint: required-param")) |_| {
|
||||
continue;
|
||||
}
|
||||
|
||||
var line_number: usize = 1;
|
||||
var line_start: usize = 0;
|
||||
|
||||
|
|
@ -410,6 +416,14 @@ const CheckUnusedSuppressionStep = struct {
|
|||
.line_content = try allocator.dupe(u8, trimmed),
|
||||
});
|
||||
}
|
||||
// Also check for _: pattern (unused argument in parameter list)
|
||||
if (hasUnusedArgumentPattern(trimmed)) {
|
||||
try violations.append(allocator, .{
|
||||
.file_path = full_path,
|
||||
.line_number = line_number,
|
||||
.line_content = try allocator.dupe(u8, trimmed),
|
||||
});
|
||||
}
|
||||
|
||||
line_number += 1;
|
||||
line_start = i + 1;
|
||||
|
|
@ -440,6 +454,22 @@ const CheckUnusedSuppressionStep = struct {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn hasUnusedArgumentPattern(line: []const u8) bool {
|
||||
// Pattern: `_:` in function parameter positions
|
||||
// This catches patterns like `fn foo(_: SomeType)` or `_: anytype`
|
||||
// We look for `_:` followed by a space and a type, or just `_:` with a type
|
||||
var i: usize = 0;
|
||||
while (i + 1 < line.len) : (i += 1) {
|
||||
if (line[i] == '_' and line[i + 1] == ':') {
|
||||
// Check that this is preceded by start of line, space, paren, or comma
|
||||
if (i == 0 or line[i - 1] == ' ' or line[i - 1] == '(' or line[i - 1] == ',') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
fn checkFxPlatformTestCoverage(step: *Step) !void {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! A S-expression tree representation
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Memory safety utilities for bounds checking and safe memory operations
|
||||
//! Provides helpers to prevent buffer overflows and memory corruption
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Base58 encoding and decoding for BLAKE3 hashes
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module provides base58 encoding/decoding specifically optimized for 256-bit BLAKE3 hashes.
|
||||
//! The base58 alphabet excludes visually similar characters (0, O, I, l) to prevent confusion.
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! GNU libc stub generation for test platforms
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
//! This file is part of zig, which is MIT licensed.
|
||||
//! See http://opensource.org/licenses/MIT
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! This module provides a fuzz testing implementation for sorting functions,
|
||||
//! featuring memory allocation tracking, sorting verification, and reference-counted
|
||||
//! comparison mechanisms.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const sort = @import("sort.zig");
|
||||
|
|
@ -97,9 +99,6 @@ fn testing_roc_dealloc(c_ptr: *anyopaque, _: u32) callconv(.c) void {
|
|||
allocator.free(slice);
|
||||
}
|
||||
|
||||
fn testing_roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.c) void {
|
||||
_ = c_ptr;
|
||||
_ = tag_id;
|
||||
|
||||
fn testing_roc_panic(_: *anyopaque, _: u32) callconv(.c) void {
|
||||
@panic("Roc panicked");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! Lists use copy-on-write semantics to minimize allocations when shared across contexts.
|
||||
//! Seamless slice optimization reduces memory overhead for substring operations.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! ## Ownership Semantics
|
||||
//!
|
||||
//! See `OWNERSHIP.md` for the canonical terminology. Functions in this module
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! This module provides efficient sorting implementations for Roc's List type,
|
||||
//! including comparison-based sorting with custom compare functions. It handles
|
||||
//! both direct sorting for small lists and indirect pointer-based sorting for
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//! larger lists to optimize memory usage and cache performance.
|
||||
const std = @import("std");
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! This module provides the core implementation of Roc's Str type, including
|
||||
//! operations for string manipulation, Unicode handling, formatting, and
|
||||
//! memory management. It defines the RocStr structure and associated functions
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//! that are called from compiled Roc code to handle string operations efficiently.
|
||||
//!
|
||||
//! ## Ownership Semantics
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! This module provides essential infrastructure for builtin operations,
|
||||
//! including memory allocation interfaces, overflow detection utilities,
|
||||
//! debug functions, and common types used throughout the builtin modules.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//! It serves as the foundation layer that other builtin modules depend on
|
||||
//! for low-level operations and host interface functions.
|
||||
const std = @import("std");
|
||||
|
|
@ -163,18 +165,11 @@ pub const TestEnv = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn rocDbgFn(roc_dbg: *const RocDbg, env: *anyopaque) callconv(.c) void {
|
||||
_ = env;
|
||||
_ = roc_dbg;
|
||||
}
|
||||
fn rocDbgFn(_: *const RocDbg, _: *anyopaque) callconv(.c) void {}
|
||||
|
||||
fn rocExpectFailedFn(roc_expect: *const RocExpectFailed, env: *anyopaque) callconv(.c) void {
|
||||
_ = env;
|
||||
_ = roc_expect;
|
||||
}
|
||||
fn rocExpectFailedFn(_: *const RocExpectFailed, _: *anyopaque) callconv(.c) void {}
|
||||
|
||||
fn rocCrashedFn(roc_crashed: *const RocCrashed, env: *anyopaque) callconv(.c) noreturn {
|
||||
_ = env;
|
||||
fn rocCrashedFn(roc_crashed: *const RocCrashed, _: *anyopaque) callconv(.c) noreturn {
|
||||
const message = roc_crashed.utf8_bytes[0..roc_crashed.len];
|
||||
@panic(message);
|
||||
}
|
||||
|
|
@ -763,10 +758,9 @@ test "TestEnv basic functionality" {
|
|||
// Should start with no allocations
|
||||
try std.testing.expectEqual(@as(usize, 0), test_env.getAllocationCount());
|
||||
|
||||
// Get ops should work
|
||||
// Get ops should work - verify we can get ops and it points back to our test env
|
||||
const ops = test_env.getOps();
|
||||
// Function pointers are non-null by design, just verify we can get ops
|
||||
_ = ops;
|
||||
try std.testing.expectEqual(@as(*anyopaque, @ptrCast(&test_env)), ops.env);
|
||||
}
|
||||
|
||||
test "TestEnv allocation tracking" {
|
||||
|
|
|
|||
|
|
@ -40,5 +40,4 @@ pub const freeForZstd = bundle.freeForZstd;
|
|||
test {
|
||||
_ = @import("test_bundle.zig");
|
||||
_ = @import("test_streaming.zig");
|
||||
_ = bundle;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Common IR types and utilities
|
||||
//! This module contains type definitions and utilities used across the canonicalization IR.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const types_mod = @import("types");
|
||||
|
|
@ -271,7 +273,7 @@ pub const WhereClause = union(enum) {
|
|||
const attrs = tree.beginNode();
|
||||
try tree.endNode(begin, attrs);
|
||||
},
|
||||
.w_malformed => |malformed| {
|
||||
.w_malformed => {
|
||||
const begin = tree.beginNode();
|
||||
try tree.pushStaticAtom("malformed");
|
||||
|
||||
|
|
@ -280,7 +282,6 @@ pub const WhereClause = union(enum) {
|
|||
const region = cir.store.getRegionAt(node_idx);
|
||||
try cir.appendRegionInfoToSExprTreeFromRegion(tree, region);
|
||||
|
||||
_ = malformed;
|
||||
const attrs = tree.beginNode();
|
||||
try tree.endNode(begin, attrs);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Transforms Abstract Syntax Tree (AST) into Canonical Intermediate Representation (CIR) through desugaring and scope resolution.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module performs semantic analysis, resolves scoping, and transforms high-level language
|
||||
//! constructs into a simplified, normalized form suitable for type inference.
|
||||
|
||||
|
|
@ -1322,10 +1324,8 @@ fn processAssociatedItemsSecondPass(
|
|||
fn registerUserFacingName(
|
||||
self: *Self,
|
||||
fully_qualified_idx: Ident.Idx,
|
||||
item_name_idx: Ident.Idx,
|
||||
pattern_idx: CIR.Pattern.Idx,
|
||||
) std.mem.Allocator.Error!void {
|
||||
_ = item_name_idx;
|
||||
|
||||
// Get the fully qualified text and strip the module prefix
|
||||
const fully_qualified_text = self.env.getIdent(fully_qualified_idx);
|
||||
|
|
@ -1656,7 +1656,7 @@ fn processAssociatedItemsFirstPass(
|
|||
// - Module scope gets "Foo.Bar.baz" (user-facing fully qualified)
|
||||
// - Foo's scope gets "Bar.baz" (partially qualified)
|
||||
// - Bar's scope gets "baz" (unqualified)
|
||||
try self.registerUserFacingName(qualified_idx, decl_ident, placeholder_pattern_idx);
|
||||
try self.registerUserFacingName(qualified_idx, placeholder_pattern_idx);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1684,7 +1684,7 @@ fn processAssociatedItemsFirstPass(
|
|||
try current_scope.idents.put(self.env.gpa, qualified_idx, placeholder_pattern_idx);
|
||||
|
||||
// Register progressively qualified names at each scope level per the plan
|
||||
try self.registerUserFacingName(qualified_idx, anno_ident, placeholder_pattern_idx);
|
||||
try self.registerUserFacingName(qualified_idx, placeholder_pattern_idx);
|
||||
}
|
||||
},
|
||||
else => {
|
||||
|
|
@ -2280,9 +2280,8 @@ pub fn canonicalizeFile(
|
|||
}
|
||||
}
|
||||
},
|
||||
.malformed => |malformed| {
|
||||
.malformed => {
|
||||
// We won't touch this since it's already a parse error.
|
||||
_ = malformed;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -2687,9 +2686,8 @@ fn addToExposedScope(
|
|||
try self.exposed_type_texts.put(gpa, type_text, region);
|
||||
}
|
||||
},
|
||||
.malformed => |malformed| {
|
||||
.malformed => {
|
||||
// Malformed exposed items are already captured as diagnostics during parsing
|
||||
_ = malformed;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -2895,20 +2893,14 @@ fn bringImportIntoScope(
|
|||
const exposed = self.parse_ir.store.getExposedItem(exposed_idx);
|
||||
switch (exposed) {
|
||||
.lower_ident => |ident| {
|
||||
|
||||
// TODO handle `as` here using an Alias
|
||||
|
||||
if (self.parse_ir.tokens.resolveIdentifier(ident.ident)) |ident_idx| {
|
||||
_ = ident_idx;
|
||||
|
||||
// TODO Introduce our import
|
||||
|
||||
// TODO Introduce our import
|
||||
if (self.parse_ir.tokens.resolveIdentifier(ident.ident)) |_| {
|
||||
// _ = self.scope.levels.introduce(gpa, &self.env.idents, .ident, .{ .scope_name = ident_idx, .ident = ident_idx });
|
||||
}
|
||||
},
|
||||
.upper_ident => |imported_type| {
|
||||
_ = imported_type;
|
||||
// const alias = Alias{
|
||||
.upper_ident => {
|
||||
// TODO: const alias = Alias{
|
||||
// .name = imported_type.name,
|
||||
// .region = ir.env.tag_names.getRegion(imported_type.name),
|
||||
// .is_builtin = false,
|
||||
|
|
@ -2921,9 +2913,7 @@ fn bringImportIntoScope(
|
|||
// .alias = alias_idx,
|
||||
// });
|
||||
},
|
||||
.upper_ident_star => |ident| {
|
||||
_ = ident;
|
||||
},
|
||||
.upper_ident_star => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5662,7 +5652,7 @@ pub fn canonicalizeExpr(
|
|||
},
|
||||
.for_expr => |for_expr| {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(for_expr.region);
|
||||
const result = try self.canonicalizeForLoop(for_expr.patt, for_expr.expr, for_expr.body, region);
|
||||
const result = try self.canonicalizeForLoop(for_expr.patt, for_expr.expr, for_expr.body);
|
||||
|
||||
const for_expr_idx = try self.env.addExpr(Expr{
|
||||
.e_for = .{
|
||||
|
|
@ -5674,9 +5664,8 @@ pub fn canonicalizeExpr(
|
|||
|
||||
return CanonicalizedExpr{ .idx = for_expr_idx, .free_vars = result.free_vars };
|
||||
},
|
||||
.malformed => |malformed| {
|
||||
.malformed => {
|
||||
// We won't touch this since it's already a parse error.
|
||||
_ = malformed;
|
||||
return null;
|
||||
},
|
||||
}
|
||||
|
|
@ -5712,9 +5701,7 @@ fn canonicalizeForLoop(
|
|||
ast_patt: AST.Pattern.Idx,
|
||||
ast_list_expr: AST.Expr.Idx,
|
||||
ast_body: AST.Expr.Idx,
|
||||
region: base.Region,
|
||||
) std.mem.Allocator.Error!CanonicalizedForLoop {
|
||||
_ = region;
|
||||
|
||||
// Tmp state to capture free vars from both expr & body
|
||||
// This is stored as a map to avoid duplicate captures
|
||||
|
|
@ -7179,9 +7166,8 @@ fn canonicalizePattern(
|
|||
return pattern_idx;
|
||||
}
|
||||
},
|
||||
.malformed => |malformed| {
|
||||
.malformed => {
|
||||
// We won't touch this since it's already a parse error.
|
||||
_ = malformed;
|
||||
return null;
|
||||
},
|
||||
}
|
||||
|
|
@ -9256,7 +9242,7 @@ pub fn canonicalizeBlockStatement(self: *Self, ast_stmt: AST.Statement, ast_stmt
|
|||
},
|
||||
.@"for" => |for_stmt| {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(for_stmt.region);
|
||||
const result = try self.canonicalizeForLoop(for_stmt.patt, for_stmt.expr, for_stmt.body, region);
|
||||
const result = try self.canonicalizeForLoop(for_stmt.patt, for_stmt.expr, for_stmt.body);
|
||||
|
||||
const stmt_idx = try self.env.addStatement(Statement{
|
||||
.s_for = .{
|
||||
|
|
|
|||
|
|
@ -468,7 +468,6 @@ pub const Diagnostic = union(enum) {
|
|||
allocator: Allocator,
|
||||
ident_name: []const u8,
|
||||
region_info: base.RegionInfo,
|
||||
original_region_info: base.RegionInfo,
|
||||
filename: []const u8,
|
||||
source: []const u8,
|
||||
line_starts: []const u32,
|
||||
|
|
@ -490,10 +489,6 @@ pub const Diagnostic = union(enum) {
|
|||
line_starts,
|
||||
);
|
||||
|
||||
// we don't need to display the original region info
|
||||
// as this header is in a single location
|
||||
_ = original_region_info;
|
||||
|
||||
try report.document.addReflowingText("You can remove the duplicate entry to fix this warning.");
|
||||
|
||||
return report;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Expression constructs used in Roc's canonicalization phase.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module defines the `Expr` union which represents all possible expressions
|
||||
//! in Roc's Canonical Intermediate Representation (CIR). These expressions are
|
||||
//! created during the canonicalization phase and represent the semantic meaning
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Represents an external declaration from another module
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const base = @import("base");
|
||||
const collections = @import("collections");
|
||||
|
|
@ -22,8 +24,6 @@ pub const Idx = enum(u32) { _ };
|
|||
pub const Span = extern struct { span: DataSpan };
|
||||
|
||||
/// Converts this external declaration to an S-expression tree representation for debugging
|
||||
pub fn pushToSExprTree(self: *const ExternalDecl, cir: anytype, tree: anytype) !void {
|
||||
_ = self;
|
||||
_ = cir;
|
||||
pub fn pushToSExprTree(_: *const ExternalDecl, _: anytype, tree: anytype) !void {
|
||||
try tree.pushStaticAtom("external-decl-stub");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Compiler support for hosted functions in platform modules.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module handles the transformation of annotation-only declarations
|
||||
//! into hosted lambda expressions that will be provided by the platform at runtime.
|
||||
|
||||
|
|
@ -122,10 +124,6 @@ pub fn replaceAnnoOnlyWithHosted(env: *ModuleEnv) !std.ArrayList(CIR.Def.Idx) {
|
|||
|
||||
env.store.extra_data.items.items[extra_start + 1] = @intFromEnum(expr_idx);
|
||||
|
||||
// Verify the def still has its annotation after modification
|
||||
const modified_def = env.store.getDef(def_idx);
|
||||
_ = modified_def;
|
||||
|
||||
// Track this modified def index
|
||||
try modified_def_indices.append(gpa, def_idx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -981,7 +981,6 @@ pub fn diagnosticToReport(self: *Self, diagnostic: CIR.Diagnostic, allocator: st
|
|||
.redundant_exposed => |data| blk: {
|
||||
const ident_name = self.getIdent(data.ident);
|
||||
const region_info = self.calcRegionInfo(data.region);
|
||||
const original_region_info = self.calcRegionInfo(data.original_region);
|
||||
|
||||
var report = Report.init(allocator, "REDUNDANT EXPOSED", .warning);
|
||||
const owned_ident = try report.addOwnedString(ident_name);
|
||||
|
|
@ -1000,10 +999,6 @@ pub fn diagnosticToReport(self: *Self, diagnostic: CIR.Diagnostic, allocator: st
|
|||
self.getLineStartsAll(),
|
||||
);
|
||||
|
||||
// we don't need to display the original region info
|
||||
// as this header is in a single location
|
||||
_ = original_region_info;
|
||||
|
||||
try report.document.addReflowingText("You can remove the duplicate entry to fix this warning.");
|
||||
|
||||
break :blk report;
|
||||
|
|
@ -1205,9 +1200,7 @@ pub fn diagnosticToReport(self: *Self, diagnostic: CIR.Diagnostic, allocator: st
|
|||
|
||||
break :blk report;
|
||||
},
|
||||
.lambda_body_not_canonicalized => |data| blk: {
|
||||
_ = data;
|
||||
|
||||
.lambda_body_not_canonicalized => blk: {
|
||||
var report = Report.init(allocator, "INVALID LAMBDA", .runtime_error);
|
||||
try report.document.addReflowingText("The body of this lambda expression is not valid.");
|
||||
|
||||
|
|
@ -1233,9 +1226,7 @@ pub fn diagnosticToReport(self: *Self, diagnostic: CIR.Diagnostic, allocator: st
|
|||
|
||||
break :blk report;
|
||||
},
|
||||
.var_across_function_boundary => |data| blk: {
|
||||
_ = data;
|
||||
|
||||
.var_across_function_boundary => blk: {
|
||||
var report = Report.init(allocator, "VAR REASSIGNMENT ERROR", .runtime_error);
|
||||
try report.document.addReflowingText("Cannot reassign a ");
|
||||
try report.document.addKeyword("var");
|
||||
|
|
@ -1247,9 +1238,7 @@ pub fn diagnosticToReport(self: *Self, diagnostic: CIR.Diagnostic, allocator: st
|
|||
|
||||
break :blk report;
|
||||
},
|
||||
.tuple_elem_not_canonicalized => |data| blk: {
|
||||
_ = data;
|
||||
|
||||
.tuple_elem_not_canonicalized => blk: {
|
||||
var report = Report.init(allocator, "INVALID TUPLE ELEMENT", .runtime_error);
|
||||
try report.document.addReflowingText("This tuple element is malformed or contains invalid syntax.");
|
||||
|
||||
|
|
@ -2237,8 +2226,7 @@ pub fn addMatchBranchPattern(self: *Self, expr: CIR.Expr.Match.BranchPattern, re
|
|||
|
||||
/// Add a new pattern record field to the node store.
|
||||
/// This function asserts that the nodes and regions are in sync.
|
||||
pub fn addPatternRecordField(self: *Self, expr: CIR.PatternRecordField, region: Region) std.mem.Allocator.Error!CIR.PatternRecordField.Idx {
|
||||
_ = region;
|
||||
pub fn addPatternRecordField(self: *Self, expr: CIR.PatternRecordField) std.mem.Allocator.Error!CIR.PatternRecordField.Idx {
|
||||
const expr_idx = try self.store.addPatternRecordField(expr);
|
||||
self.debugAssertArraysInSync();
|
||||
return expr_idx;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Stores AST nodes and provides scratch arrays for working with nodes.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
|
|
@ -1126,9 +1128,7 @@ pub fn getPattern(store: *const NodeStore, pattern_idx: CIR.Pattern.Idx) CIR.Pat
|
|||
}
|
||||
|
||||
/// Retrieves a pattern record field from the store.
|
||||
pub fn getPatternRecordField(store: *NodeStore, patternRecordField: CIR.PatternRecordField.Idx) CIR.PatternRecordField {
|
||||
_ = store;
|
||||
_ = patternRecordField;
|
||||
pub fn getPatternRecordField(_: *NodeStore, _: CIR.PatternRecordField.Idx) CIR.PatternRecordField {
|
||||
// Return empty placeholder since PatternRecordField has no fields yet
|
||||
return CIR.PatternRecordField{};
|
||||
}
|
||||
|
|
@ -2140,10 +2140,7 @@ pub fn addPattern(store: *NodeStore, pattern: CIR.Pattern, region: base.Region)
|
|||
}
|
||||
|
||||
/// Adds a pattern record field to the store.
|
||||
pub fn addPatternRecordField(store: *NodeStore, patternRecordField: CIR.PatternRecordField) Allocator.Error!CIR.PatternRecordField.Idx {
|
||||
_ = store;
|
||||
_ = patternRecordField;
|
||||
|
||||
pub fn addPatternRecordField(_: *NodeStore, _: CIR.PatternRecordField) Allocator.Error!CIR.PatternRecordField.Idx {
|
||||
return @enumFromInt(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ test "fractional literal - basic decimal" {
|
|||
try testing.expectEqual(dec.value.numerator, 314);
|
||||
try testing.expectEqual(dec.value.denominator_power_of_ten, 2);
|
||||
},
|
||||
.e_dec => |dec| {
|
||||
_ = dec;
|
||||
},
|
||||
.e_dec => {},
|
||||
else => {
|
||||
std.debug.print("Unexpected expr type: {}\n", .{expr});
|
||||
try testing.expect(false); // Should be dec_small or frac_dec
|
||||
|
|
@ -54,9 +52,8 @@ test "fractional literal - scientific notation small" {
|
|||
// This is expected behavior when the value is too small for i16 representation
|
||||
try testing.expectEqual(dec.value.numerator, 0);
|
||||
},
|
||||
.e_dec => |frac| {
|
||||
.e_dec => {
|
||||
// RocDec stores the value in a special format
|
||||
_ = frac;
|
||||
},
|
||||
.e_frac_f64 => |frac| {
|
||||
try testing.expectApproxEqAbs(frac.value, 1.23e-10, 1e-20);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Performs Hindley-Milner type inference with constraint solving and unification on the Canonical Intermediate Representation (CIR).
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module implements constraint-based type inference.
|
||||
|
||||
const std = @import("std");
|
||||
|
|
@ -1497,8 +1499,7 @@ fn generateStaticDispatchConstraintFromWhere(self: *Self, where_idx: CIR.WhereCl
|
|||
},
|
||||
});
|
||||
},
|
||||
.w_alias => |alias| {
|
||||
_ = alias;
|
||||
.w_alias => {
|
||||
// TODO: Recursively unwrap alias
|
||||
},
|
||||
.w_malformed => {
|
||||
|
|
@ -4964,28 +4965,6 @@ fn handleRecursiveConstraint(
|
|||
///
|
||||
/// Initially, we only have to check constraint for `Test.to_str2`. But when we
|
||||
/// process that, we then have to check `Test.to_str`.
|
||||
/// Check a from_numeral constraint - actual validation happens during comptime evaluation
|
||||
fn checkNumeralConstraint(
|
||||
self: *Self,
|
||||
type_var: Var,
|
||||
constraint: types_mod.StaticDispatchConstraint,
|
||||
num_lit_info: types_mod.NumeralInfo,
|
||||
nominal_type: types_mod.NominalType,
|
||||
env: *Env,
|
||||
) !void {
|
||||
// Mark parameters as intentionally unused - validation happens in comptime evaluation
|
||||
_ = self;
|
||||
_ = type_var;
|
||||
_ = constraint;
|
||||
_ = num_lit_info;
|
||||
_ = nominal_type;
|
||||
_ = env;
|
||||
|
||||
// All numeric literal validation now happens during comptime evaluation
|
||||
// in ComptimeEvaluator.validateDeferredNumericLiterals()
|
||||
// This function exists only to satisfy the constraint checking interface
|
||||
}
|
||||
|
||||
fn checkDeferredStaticDispatchConstraints(self: *Self, env: *Env) std.mem.Allocator.Error!void {
|
||||
var deferred_constraint_len = env.deferred_static_dispatch_constraints.items.items.len;
|
||||
var deferred_constraint_index: usize = 0;
|
||||
|
|
@ -5250,16 +5229,9 @@ fn checkDeferredStaticDispatchConstraints(self: *Self, env: *Env) std.mem.Alloca
|
|||
if (any_arg_failed or ret_result.isProblem()) {
|
||||
try self.unifyWith(deferred_constraint.var_, .err, env);
|
||||
try self.unifyWith(resolved_func.ret, .err, env);
|
||||
} else if (constraint.origin == .from_numeral and constraint.num_literal != null) {
|
||||
// For from_numeral constraints on builtin types, do compile-time validation
|
||||
try self.checkNumeralConstraint(
|
||||
deferred_constraint.var_,
|
||||
constraint,
|
||||
constraint.num_literal.?,
|
||||
nominal_type,
|
||||
env,
|
||||
);
|
||||
}
|
||||
// Note: from_numeral constraint validation happens during comptime evaluation
|
||||
// in ComptimeEvaluator.validateDeferredNumericLiterals()
|
||||
}
|
||||
} else if (dispatcher_content == .structure and
|
||||
(dispatcher_content.structure == .record or
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ pub const ReportBuilder = struct {
|
|||
const expected_content = self.snapshots.getContent(types.expected_snapshot);
|
||||
const actual_content = self.snapshots.getContent(types.actual_snapshot);
|
||||
|
||||
if (types.from_annotation and self.areBothFunctionSnapshots(expected_content, actual_content)) {
|
||||
if (types.from_annotation and areBothFunctionSnapshots(expected_content, actual_content)) {
|
||||
// When we have constraint_origin_var, it indicates this error originated from
|
||||
// a specific constraint like a dot access (e.g., str.to_utf8()).
|
||||
// In this case, show a specialized argument type mismatch error.
|
||||
|
|
@ -2436,13 +2436,12 @@ pub const ReportBuilder = struct {
|
|||
}
|
||||
|
||||
/// Check if both snapshot contents represent function types
|
||||
fn areBothFunctionSnapshots(self: *Self, expected_content: snapshot.SnapshotContent, actual_content: snapshot.SnapshotContent) bool {
|
||||
return self.isSnapshotFunction(expected_content) and self.isSnapshotFunction(actual_content);
|
||||
fn areBothFunctionSnapshots(expected_content: snapshot.SnapshotContent, actual_content: snapshot.SnapshotContent) bool {
|
||||
return isSnapshotFunction(expected_content) and isSnapshotFunction(actual_content);
|
||||
}
|
||||
|
||||
/// Check if a snapshot content represents a function type
|
||||
fn isSnapshotFunction(self: *Self, content: snapshot.SnapshotContent) bool {
|
||||
_ = self;
|
||||
fn isSnapshotFunction(content: snapshot.SnapshotContent) bool {
|
||||
return switch (content) {
|
||||
.structure => |structure| switch (structure) {
|
||||
.fn_pure, .fn_effectful, .fn_unbound => true,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
//! This module implements Hindley-Milner style type unification with extensions for:
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! * flex/rigid variables
|
||||
//! * type aliases
|
||||
//! * tuples
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//! Roc command line interface for the new compiler. Entrypoint of the Roc binary.
|
||||
//! Build with `zig build -Dfuzz -Dsystem-afl=false`.
|
||||
//! Result is at `./zig-out/bin/roc`
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
|
|
@ -3217,8 +3219,7 @@ fn rocTest(allocs: *Allocators, args: cli_args.TestArgs) !void {
|
|||
}
|
||||
}
|
||||
|
||||
fn rocRepl(allocs: *Allocators) !void {
|
||||
_ = allocs;
|
||||
fn rocRepl(_: *Allocators) !void {
|
||||
const stderr = stderrWriter();
|
||||
defer stderr.flush() catch {};
|
||||
stderr.print("repl not implemented\n", .{}) catch {};
|
||||
|
|
|
|||
|
|
@ -86,13 +86,6 @@ test "roc docs generates nested package documentation" {
|
|||
\\
|
||||
);
|
||||
|
||||
// Create output directory path
|
||||
const output_dir = try std.fs.path.join(gpa, &[_][]const u8{ tmp_path, "generated-docs" });
|
||||
defer gpa.free(output_dir);
|
||||
|
||||
const root_path = try std.fs.path.join(gpa, &[_][]const u8{ tmp_path, "root.roc" });
|
||||
defer gpa.free(root_path);
|
||||
|
||||
// Note: We would call main.rocDocs(gpa, args) here, but it requires
|
||||
// a full build environment setup. Instead, we test the individual
|
||||
// helper functions in separate tests below.
|
||||
|
|
@ -103,9 +96,6 @@ test "roc docs generates nested package documentation" {
|
|||
tmp.dir.access("bar/main.roc", .{}) catch unreachable;
|
||||
tmp.dir.access("baz/main.roc", .{}) catch unreachable;
|
||||
tmp.dir.access("qux/main.roc", .{}) catch unreachable;
|
||||
|
||||
_ = root_path;
|
||||
_ = output_dir;
|
||||
}
|
||||
|
||||
test "generatePackageIndex creates valid HTML" {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! A builder for creating sorted arrays with binary search lookups.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! SortedArrayBuilder provides a way to build key-value mappings that are
|
||||
//! optimized for small sizes and deterministic serialization. It maintains
|
||||
//! a sorted array internally, enabling efficient binary search lookups.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Lists that make it easier to avoid incorrect indexing.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Cache key generation and management for uniquely identifying cached compilation results.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const fs_mod = @import("fs");
|
||||
|
|
@ -84,13 +86,10 @@ pub const CacheKey = struct {
|
|||
/// Format cache key for debugging output.
|
||||
pub fn format(
|
||||
self: Self,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
comptime _: []const u8,
|
||||
_: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
try writer.print("CacheKey{{ content: {x}, mtime: {}, compiler: {x} }}", .{
|
||||
self.content_hash[0..8], // First 8 bytes for readability
|
||||
self.file_mtime,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Modern cache manager that uses BLAKE3-based keys and subdirectory splitting.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
|
|
@ -66,8 +68,7 @@ pub const CacheManager = struct {
|
|||
}
|
||||
|
||||
/// Deinitialize the cache manager.
|
||||
pub fn deinit(self: *Self) void {
|
||||
_ = self;
|
||||
pub fn deinit(_: *Self) void {
|
||||
// Nothing to deinit currently
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//!
|
||||
//! This module provides memory-mapped caching for compiled Roc modules,
|
||||
//! allowing fast serialization and deserialization of ModuleEnv and CIR data.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const Can = @import("can");
|
||||
|
|
@ -203,12 +205,11 @@ pub const CacheModule = struct {
|
|||
|
||||
/// Convenience functions for reading/writing cache files
|
||||
pub fn writeToFile(
|
||||
allocator: Allocator,
|
||||
_: Allocator,
|
||||
cache_data: []const u8,
|
||||
file_path: []const u8,
|
||||
filesystem: anytype,
|
||||
) !void {
|
||||
_ = allocator;
|
||||
try filesystem.writeFile(file_path, cache_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//!
|
||||
//! Modules are built in parallel unless targeting WebAssembly, which doesn't support threads.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! Errors are reported as soon as they're encountered, with the only exception being that
|
||||
//! there is some buffering to make their output order determined by the dependency graph
|
||||
//! rather than by parallelism races. In other words, if you build the same set of source files
|
||||
|
|
@ -294,10 +296,8 @@ const GlobalQueue = struct {
|
|||
}
|
||||
|
||||
// Hook from ModuleBuild to enqueue newly discovered/scheduled modules
|
||||
pub fn hookOnSchedule(ctx: ?*anyopaque, package_name: []const u8, module_name: []const u8, _path: []const u8, _depth: u32) void {
|
||||
pub fn hookOnSchedule(ctx: ?*anyopaque, package_name: []const u8, module_name: []const u8, _: []const u8, _: u32) void {
|
||||
var self: *GlobalQueue = @ptrCast(@alignCast(ctx.?));
|
||||
_ = _path;
|
||||
_ = _depth;
|
||||
// Enqueue to global queue - log but don't fail on error
|
||||
self.enqueue(package_name, module_name) catch {
|
||||
// Continue anyway - the module will still be processed by local scheduler
|
||||
|
|
@ -682,14 +682,8 @@ pub const BuildEnv = struct {
|
|||
ws: *BuildEnv,
|
||||
|
||||
// Called by ModuleBuild.schedule_hook when a module is discovered/scheduled
|
||||
pub fn onSchedule(ctx: ?*anyopaque, package_name: []const u8, module_name: []const u8, _path: []const u8, _depth: u32) void {
|
||||
const self: *ScheduleCtx = @ptrCast(@alignCast(ctx.?));
|
||||
_ = package_name;
|
||||
_ = module_name;
|
||||
_ = _path;
|
||||
_ = _depth;
|
||||
pub fn onSchedule(_: ?*anyopaque, _: []const u8, _: []const u8, _: []const u8, _: u32) void {
|
||||
// Early reports auto-register in OrderedSink.emitReport when they are emitted
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -704,12 +698,6 @@ pub const BuildEnv = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolverClassify(ctx: ?*anyopaque, _: []const u8, _: []const u8) bool {
|
||||
_ = ctx;
|
||||
// Unused: ModuleBuild determines external vs local from CIR (s_import.qualifier_tok)
|
||||
return false;
|
||||
}
|
||||
|
||||
fn resolverScheduleExternal(ctx: ?*anyopaque, current_package: []const u8, import_name: []const u8) void {
|
||||
var self: *ResolverCtx = @ptrCast(@alignCast(ctx.?));
|
||||
const cur_pkg = self.ws.packages.get(current_package) orelse return;
|
||||
|
|
@ -761,8 +749,7 @@ pub const BuildEnv = struct {
|
|||
return sched.*.getEnvIfDone(rest);
|
||||
}
|
||||
|
||||
fn resolverResolveLocalPath(ctx: ?*anyopaque, _current_package: []const u8, root_dir: []const u8, import_name: []const u8) []const u8 {
|
||||
_ = _current_package;
|
||||
fn resolverResolveLocalPath(ctx: ?*anyopaque, _: []const u8, root_dir: []const u8, import_name: []const u8) []const u8 {
|
||||
var self: *ResolverCtx = @ptrCast(@alignCast(ctx.?));
|
||||
return self.ws.dottedToPath(root_dir, import_name) catch import_name;
|
||||
}
|
||||
|
|
@ -774,7 +761,6 @@ pub const BuildEnv = struct {
|
|||
ctx.* = .{ .ws = self };
|
||||
return .{
|
||||
.ctx = ctx,
|
||||
.classify = resolverClassify,
|
||||
.scheduleExternal = resolverScheduleExternal,
|
||||
.isReady = resolverIsReady,
|
||||
.getEnv = resolverGetEnv,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
//! This component manages the concurrent compilation of all modules within a single package,
|
||||
//! orchestrating the build phases for each module:
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! - Parsing modules to discover their import dependencies
|
||||
//! - Canonicalizing parsed modules into an intermediate representation
|
||||
//! - Type-checking modules once their dependencies are ready
|
||||
|
|
@ -83,8 +85,6 @@ pub const ScheduleHook = struct {
|
|||
/// Resolver for handling imports across package boundaries
|
||||
pub const ImportResolver = struct {
|
||||
ctx: ?*anyopaque,
|
||||
/// Return true if the import_name refers to an external package (e.g. "cli.Stdout")
|
||||
classify: *const fn (ctx: ?*anyopaque, current_package: []const u8, import_name: []const u8) bool,
|
||||
/// Ensure the external import is scheduled for building in its owning package
|
||||
scheduleExternal: *const fn (ctx: ?*anyopaque, current_package: []const u8, import_name: []const u8) void,
|
||||
/// Return true if the external import is fully type-checked and its ModuleEnv is ready
|
||||
|
|
|
|||
|
|
@ -431,11 +431,8 @@ test "ModuleEnv pushExprTypesToSExprTree extracts and formats types" {
|
|||
.origin_module = builtin_ident,
|
||||
.is_opaque = false,
|
||||
};
|
||||
const str_type = try env.types.freshFromContent(.{ .structure = .{ .nominal_type = str_nominal } });
|
||||
|
||||
// Add a string segment expression
|
||||
const segment_idx = try env.addExpr(.{ .e_str_segment = .{ .literal = str_literal_idx } }, base.Region.from_raw_offsets(0, 5));
|
||||
_ = str_type;
|
||||
|
||||
// Now create a string expression that references the segment
|
||||
const expr_idx = try env.addExpr(.{ .e_str = .{ .span = Expr.Span{ .span = base.DataSpan{ .start = @intFromEnum(segment_idx), .len = 1 } } } }, base.Region.from_raw_offsets(0, 5));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Represents a "value" on the Interpreter's stack.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This is the public facing interface for interacting with stack values.
|
||||
//!
|
||||
//! It provides methods for working with the value safely using the layout.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//!
|
||||
//! This module evaluates all top-level declarations after type checking,
|
||||
//! converting any crashes into diagnostics that are reported normally.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Interpreter implementing the type-carrying architecture.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! An implementation of RocOps for testing purposes.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtins = @import("builtins");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
//! Tests for compile-time evaluation of top-level declarations
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const parse = @import("parse");
|
||||
const types = @import("types");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//! Polymorphism tests for Interpreter focused on closures without captures (Milestone 1).
|
||||
//! Each test starts with Roc source (multiline Zig string with `\\`), parses + canonicalizes
|
||||
//! with early diagnostics, evaluates with Interpreter, and renders Roc output.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const helpers = @import("helpers.zig");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Tests for e_low_level_lambda runtime evaluation in the interpreter
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! These tests verify that low-level operations (like Str.is_empty, List.concat) that are defined
|
||||
//! as e_low_level_lambda nodes correctly dispatch to their builtin implementations
|
||||
//! when called at compile-time, producing the correct runtime values.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//! Runs expect expressions
|
||||
//!
|
||||
//! This module is a wrapper around the interpreter used to simplify evaluating expect expressions.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Abstract filesystem functions so we can mock them out for testing
|
||||
//! and also provide an alternative implementation for WASM (webREPL, playground).
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const collections = @import("collections");
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
//! resize it should never come up in practice, since coordinating resizing with the
|
||||
//! child process would be complex.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! ## Cross-platform coordination
|
||||
//!
|
||||
//! The allocator uses platform-specific coordination mechanisms:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! Stores Layout values by index.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
|
@ -1121,20 +1123,7 @@ pub const Store = struct {
|
|||
current = self.types_store.resolveVar(last_pending_field.var_);
|
||||
continue :outer;
|
||||
},
|
||||
.fn_pure => |func| {
|
||||
_ = func;
|
||||
// Create empty captures layout for generic function type
|
||||
const empty_captures_idx = try self.getEmptyRecordLayout();
|
||||
break :flat_type Layout.closure(empty_captures_idx);
|
||||
},
|
||||
.fn_effectful => |func| {
|
||||
_ = func;
|
||||
// Create empty captures layout for generic function type
|
||||
const empty_captures_idx = try self.getEmptyRecordLayout();
|
||||
break :flat_type Layout.closure(empty_captures_idx);
|
||||
},
|
||||
.fn_unbound => |func| {
|
||||
_ = func;
|
||||
.fn_pure, .fn_effectful, .fn_unbound => {
|
||||
// Create empty captures layout for generic function type
|
||||
const empty_captures_idx = try self.getEmptyRecordLayout();
|
||||
break :flat_type Layout.closure(empty_captures_idx);
|
||||
|
|
@ -1285,7 +1274,7 @@ pub const Store = struct {
|
|||
// and append our variant layouts. This ensures our variants are contiguous.
|
||||
const variants_start: u32 = @intCast(self.tag_union_variants.len());
|
||||
|
||||
for (variant_layout_indices, 0..) |variant_layout_idx, variant_i| {
|
||||
for (variant_layout_indices) |variant_layout_idx| {
|
||||
const variant_layout = self.getLayout(variant_layout_idx);
|
||||
const variant_size = self.layoutSize(variant_layout);
|
||||
const variant_alignment = variant_layout.alignment(self.targetUsize());
|
||||
|
|
@ -1298,7 +1287,6 @@ pub const Store = struct {
|
|||
_ = try self.tag_union_variants.append(self.env.gpa, .{
|
||||
.payload_layout = variant_layout_idx,
|
||||
});
|
||||
_ = variant_i;
|
||||
}
|
||||
|
||||
// Calculate discriminant info
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const protocol = @import("../protocol.zig");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Syntax checking integration that runs the Roc compiler and converts
|
||||
//! reports to LSP diagnostics.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const compile = @import("compile");
|
||||
|
|
@ -190,7 +192,7 @@ pub const SyntaxChecker = struct {
|
|||
};
|
||||
}
|
||||
|
||||
fn rangeFromReport(self: *SyntaxChecker, rep: reporting.Report) Diagnostics.Range {
|
||||
fn rangeFromReport(_: *SyntaxChecker, rep: reporting.Report) Diagnostics.Range {
|
||||
var start = Diagnostics.Position{ .line = 0, .character = 0 };
|
||||
var end = Diagnostics.Position{ .line = 0, .character = 0 };
|
||||
|
||||
|
|
@ -220,7 +222,6 @@ pub const SyntaxChecker = struct {
|
|||
}
|
||||
}
|
||||
|
||||
_ = self;
|
||||
return .{ .start = start, .end = end };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,7 @@ pub const Statement = union(enum) {
|
|||
try tree.pushStaticAtom("exposing");
|
||||
const attrs2 = tree.beginNode();
|
||||
for (ast.store.exposedItemSlice(import.exposes)) |e| {
|
||||
try ast.store.getExposedItem(e).pushToSExprTree(gpa, env, ast, tree);
|
||||
try ast.store.getExposedItem(e).pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(exposed, attrs2);
|
||||
}
|
||||
|
|
@ -1641,7 +1641,7 @@ pub const Header = union(enum) {
|
|||
// Could push region info for provides_coll here if desired
|
||||
for (provides_items) |item_idx| {
|
||||
const item = ast.store.getExposedItem(item_idx);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(provides_begin, attrs2);
|
||||
|
||||
|
|
@ -1677,7 +1677,7 @@ pub const Header = union(enum) {
|
|||
const attrs2 = tree.beginNode();
|
||||
for (ast.store.exposedItemSlice(.{ .span = exposes.span })) |exposed| {
|
||||
const item = ast.store.getExposedItem(exposed);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(exposes_begin, attrs2);
|
||||
|
||||
|
|
@ -1697,7 +1697,7 @@ pub const Header = union(enum) {
|
|||
const attrs2 = tree.beginNode();
|
||||
for (ast.store.exposedItemSlice(.{ .span = exposes.span })) |exposed| {
|
||||
const item = ast.store.getExposedItem(exposed);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(exposes_begin, attrs2);
|
||||
|
||||
|
|
@ -1732,7 +1732,7 @@ pub const Header = union(enum) {
|
|||
// Could push region info for rigids here if desired
|
||||
for (ast.store.exposedItemSlice(.{ .span = rigids.span })) |exposed| {
|
||||
const item = ast.store.getExposedItem(exposed);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(rigids_begin, attrs3);
|
||||
|
||||
|
|
@ -1748,7 +1748,7 @@ pub const Header = union(enum) {
|
|||
const attrs4 = tree.beginNode();
|
||||
for (ast.store.exposedItemSlice(.{ .span = exposes.span })) |exposed| {
|
||||
const item = ast.store.getExposedItem(exposed);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(exposes_begin, attrs4);
|
||||
|
||||
|
|
@ -1793,7 +1793,7 @@ pub const Header = union(enum) {
|
|||
const attrs2 = tree.beginNode();
|
||||
for (ast.store.exposedItemSlice(.{ .span = exposes.span })) |exposed| {
|
||||
const item = ast.store.getExposedItem(exposed);
|
||||
try item.pushToSExprTree(gpa, env, ast, tree);
|
||||
try item.pushToSExprTree(env, ast, tree);
|
||||
}
|
||||
try tree.endNode(exposes_begin, attrs2);
|
||||
|
||||
|
|
@ -1866,9 +1866,7 @@ pub const ExposedItem = union(enum) {
|
|||
pub const Idx = enum(u32) { _ };
|
||||
pub const Span = struct { span: base.DataSpan };
|
||||
|
||||
pub fn pushToSExprTree(self: @This(), gpa: std.mem.Allocator, env: *const CommonEnv, ast: *const AST, tree: *SExprTree) std.mem.Allocator.Error!void {
|
||||
_ = gpa;
|
||||
|
||||
pub fn pushToSExprTree(self: @This(), env: *const CommonEnv, ast: *const AST, tree: *SExprTree) std.mem.Allocator.Error!void {
|
||||
switch (self) {
|
||||
.lower_ident => |i| {
|
||||
const begin = tree.beginNode();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Tokenization functionality for the Roc parser.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module provides the tokenizer that converts Roc source code into
|
||||
//! a stream of tokens for parsing. It handles all Roc language tokens including
|
||||
//! keywords, identifiers, literals, operators, and punctuation, representing
|
||||
|
|
@ -1569,8 +1571,7 @@ pub const Tokenizer = struct {
|
|||
}
|
||||
|
||||
/// Determines if a character can follow a unary minus (i.e., can start an expression)
|
||||
fn canFollowUnaryMinus(self: *const Tokenizer, c: u8) bool {
|
||||
_ = self;
|
||||
fn canFollowUnaryMinus(_: *const Tokenizer, c: u8) bool {
|
||||
return switch (c) {
|
||||
// Identifiers
|
||||
'a'...'z', 'A'...'Z', '_' => true,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//! WASM-specific filesystem implementation for the playground.
|
||||
//! This provides a minimal filesystem interface where source code
|
||||
//! can be provided from JavaScript and most other operations return errors.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const fs_mod = @import("fs");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//!
|
||||
//! This module provides a state machine interface for the Roc compiler.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! State Machine:
|
||||
//! 1. START: Initialize module, return compiler version
|
||||
//! 2. READY: Receive Roc source, compile through all stages, return "LOADED" with diagnostics
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! An implementation of RocOps for testing purposes.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtins = @import("builtins");
|
||||
|
|
@ -132,9 +134,7 @@ fn testRocRealloc(realloc_args: *RocRealloc, env: *anyopaque) callconv(.c) void
|
|||
realloc_args.answer = @ptrFromInt(@intFromPtr(new_slice.ptr) + size_storage_bytes);
|
||||
}
|
||||
|
||||
fn testRocDbg(dbg_args: *const RocDbg, env: *anyopaque) callconv(.c) void {
|
||||
_ = dbg_args;
|
||||
_ = env;
|
||||
fn testRocDbg(_: *const RocDbg, _: *anyopaque) callconv(.c) void {
|
||||
@panic("testRocDbg not implemented yet");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Snapshot testing infrastructure for the Roc compiler.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module provides functionality to generate and validate snapshot tests
|
||||
//! that capture the compiler's behavior at each stage of compilation. Snapshots
|
||||
//! help ensure the compiler continues to behave as expected by showing the
|
||||
|
|
@ -2918,8 +2920,7 @@ fn generateReplOutputSection(output: *DualOutput, snapshot_path: []const u8, con
|
|||
return success;
|
||||
}
|
||||
|
||||
fn generateReplProblemsSection(output: *DualOutput, content: *const Content) !void {
|
||||
_ = content;
|
||||
fn generateReplProblemsSection(output: *DualOutput, _: *const Content) !void {
|
||||
try output.begin_section("PROBLEMS");
|
||||
try output.md_writer.writer.writeAll("NIL\n");
|
||||
|
||||
|
|
@ -3151,9 +3152,7 @@ fn snapshotRocRealloc(realloc_args: *RocRealloc, env: *anyopaque) callconv(.c) v
|
|||
realloc_args.answer = @ptrFromInt(@intFromPtr(new_slice.ptr) + size_storage_bytes);
|
||||
}
|
||||
|
||||
fn snapshotRocDbg(dbg_args: *const RocDbg, env: *anyopaque) callconv(.c) void {
|
||||
_ = dbg_args;
|
||||
_ = env;
|
||||
fn snapshotRocDbg(_: *const RocDbg, _: *anyopaque) callconv(.c) void {
|
||||
@panic("snapshotRocDbg not implemented yet");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Type generalization for Hindley-Milner type inference.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
//!
|
||||
//! This module implements the generalization phase of Hindley-Milner type inference,
|
||||
//! which determines which type variables can be made polymorphic (generalized).
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! The store of solved types
|
||||
//! Contains both Slot & Descriptor stores
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const base = @import("base");
|
||||
|
|
@ -50,8 +52,7 @@ pub const Slot = union(enum) {
|
|||
redirect: Var,
|
||||
|
||||
/// Calculate the size needed to serialize this Slot
|
||||
pub fn serializedSize(self: *const Slot) usize {
|
||||
_ = self;
|
||||
pub fn serializedSize(_: *const Slot) usize {
|
||||
return @sizeOf(u8) + @sizeOf(u32); // tag + data
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ test "BufferExtractWriter - basic functionality" {
|
|||
// Create a file
|
||||
const file_writer = try writer.extractWriter().createFile("test.txt");
|
||||
try file_writer.writeAll("Hello, World!");
|
||||
writer.extractWriter().finishFile(file_writer);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Create a directory (should be no-op for buffer writer)
|
||||
try writer.extractWriter().makeDir("test_dir");
|
||||
|
|
@ -151,7 +151,7 @@ test "BufferExtractWriter - basic functionality" {
|
|||
// Create another file in a subdirectory
|
||||
const file_writer2 = try writer.extractWriter().createFile("subdir/test2.txt");
|
||||
try file_writer2.writeAll("Second file");
|
||||
writer.extractWriter().finishFile(file_writer2);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Verify files were stored
|
||||
try testing.expectEqual(@as(usize, 2), writer.files.count());
|
||||
|
|
@ -185,7 +185,7 @@ test "DirExtractWriter - basic functionality" {
|
|||
// Create a file
|
||||
const file_writer = try writer.extractWriter().createFile("test.txt");
|
||||
try file_writer.writeAll("Test content");
|
||||
writer.extractWriter().finishFile(file_writer);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Verify file was created
|
||||
const content = try tmp.dir.readFileAlloc(testing.allocator, "test.txt", 1024);
|
||||
|
|
@ -195,7 +195,7 @@ test "DirExtractWriter - basic functionality" {
|
|||
// Create a file in a subdirectory (should create parent dirs)
|
||||
const file_writer2 = try writer.extractWriter().createFile("deep/nested/file.txt");
|
||||
try file_writer2.writeAll("Nested content");
|
||||
writer.extractWriter().finishFile(file_writer2);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Verify nested file was created
|
||||
const nested_content = try tmp.dir.readFileAlloc(testing.allocator, "deep/nested/file.txt", 1024);
|
||||
|
|
@ -304,12 +304,12 @@ test "BufferExtractWriter - overwrite existing file" {
|
|||
// Create a file with initial content
|
||||
const file_writer1 = try writer.extractWriter().createFile("test.txt");
|
||||
try file_writer1.writeAll("Initial content");
|
||||
writer.extractWriter().finishFile(file_writer1);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Overwrite the same file
|
||||
const file_writer2 = try writer.extractWriter().createFile("test.txt");
|
||||
try file_writer2.writeAll("New content");
|
||||
writer.extractWriter().finishFile(file_writer2);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Verify it was overwritten
|
||||
const file = writer.files.get("test.txt");
|
||||
|
|
@ -327,7 +327,7 @@ test "DirExtractWriter - nested directory creation" {
|
|||
// Create a file in a deeply nested path
|
||||
const file_writer = try writer.extractWriter().createFile("a/b/c/d/e/file.txt");
|
||||
try file_writer.writeAll("Nested content");
|
||||
writer.extractWriter().finishFile(file_writer);
|
||||
writer.extractWriter().finishFile();
|
||||
|
||||
// Verify the file was created
|
||||
const content = try tmp.dir.readFileAlloc(testing.allocator, "a/b/c/d/e/file.txt", 1024);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ pub const ExtractWriter = struct {
|
|||
|
||||
pub const VTable = struct {
|
||||
createFile: *const fn (ptr: *anyopaque, path: []const u8) CreateFileError!*std.Io.Writer,
|
||||
finishFile: *const fn (ptr: *anyopaque, writer: *std.Io.Writer) void,
|
||||
finishFile: *const fn (ptr: *anyopaque) void,
|
||||
makeDir: *const fn (ptr: *anyopaque, path: []const u8) MakeDirError!void,
|
||||
};
|
||||
|
||||
|
|
@ -82,8 +82,8 @@ pub const ExtractWriter = struct {
|
|||
return self.vtable.createFile(self.ptr, path);
|
||||
}
|
||||
|
||||
pub fn finishFile(self: ExtractWriter, writer: *std.Io.Writer) void {
|
||||
return self.vtable.finishFile(self.ptr, writer);
|
||||
pub fn finishFile(self: ExtractWriter) void {
|
||||
return self.vtable.finishFile(self.ptr);
|
||||
}
|
||||
|
||||
pub fn makeDir(self: ExtractWriter, path: []const u8) MakeDirError!void {
|
||||
|
|
@ -162,8 +162,7 @@ pub const DirExtractWriter = struct {
|
|||
return &entry.writer.interface;
|
||||
}
|
||||
|
||||
fn finishFile(ptr: *anyopaque, writer: *std.Io.Writer) void {
|
||||
_ = writer;
|
||||
fn finishFile(ptr: *anyopaque) void {
|
||||
const self: *DirExtractWriter = @ptrCast(@alignCast(ptr));
|
||||
// Close and remove the last file
|
||||
if (self.open_files.items.len > 0) {
|
||||
|
|
@ -236,7 +235,7 @@ pub const BufferExtractWriter = struct {
|
|||
return &self.current_file_writer.?.writer;
|
||||
}
|
||||
|
||||
fn finishFile(ptr: *anyopaque, _: *std.Io.Writer) void {
|
||||
fn finishFile(ptr: *anyopaque) void {
|
||||
const self: *BufferExtractWriter = @ptrCast(@alignCast(ptr));
|
||||
if (self.current_file_writer) |*writer| {
|
||||
if (self.current_file_path) |path| {
|
||||
|
|
@ -591,7 +590,7 @@ pub fn unbundleStream(
|
|||
},
|
||||
.file => {
|
||||
const file_writer = try extract_writer.createFile(file_path);
|
||||
defer extract_writer.finishFile(file_writer);
|
||||
defer extract_writer.finishFile();
|
||||
|
||||
try tar_iterator.streamRemaining(entry, file_writer);
|
||||
try file_writer.flush();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! File system watcher for monitoring .roc file changes across platforms.
|
||||
//! Provides efficient, cross-platform file watching with recursive directory support.
|
||||
//!
|
||||
// zig-lint: required-param
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue